views:

1052

answers:

2

Hi,

I was trying out the code for offline storage in firefox 3.5, taken from http://starkravingfinkle.org/blog/2008/05/firefox-3-offline-app-demo-part-2/. When the page loads i get a dialog prompting me that the application is asking for storing data, but when i press Allow, the dialog does not go away . The app works fine at the online demo given on the website. The source file containing the javascript is as follows :

todo.html

<!--
  Simple task list application used to illusrate Firefox's offline/DOMStorage capabilities

  Author: Mark Finkle
-->

<html manifest="todo.manifest">
  <head>
    <title>TODO - Offline Demo</title>
    <script type="text/javascript" src="json.js"></script>
    <script language="javascript">
    var taskStorage = "[]";
    var storageDomain = location.hostname;
    if (storageDomain == "localhost")
      storageDomain += ".localdomain";

    function loaded() {
      updateOnlineStatus("load", false);
      document.body.addEventListener("offline", function () { updateOnlineStatus("offline", true) }, false);
      document.body.addEventListener("online", function () { updateOnlineStatus("online", true) }, false);

      if (typeof globalStorage != "undefined") {
        var storage = globalStorage[storageDomain];
        if (storage && storage.taskStorage) {
          taskStorage = storage.taskStorage;
        }
      }

      fetchList();
    }

    function updateOnlineStatus(msg, allowUpdate) {
      var status = document.getElementById("status");
      status.innerHTML = (navigator.onLine ? "[online]" : "[offline]");

      var log = document.getElementById("log");
      log.appendChild(document.createTextNode("Event: " + msg + "\n"));

      if (navigator.onLine && allowUpdate) {
        update();
        log.appendChild(document.createTextNode("Updated server\n"));
      }

    }

    function httpRequest(type, data, callback) {
      var httpreq = new XMLHttpRequest();
      httpreq.onreadystatechange = function() { if (httpreq.readyState == 4) callback(httpreq.readyState, httpreq.status, httpreq.responseText); };
      httpreq.open(type, "todo-server.php", true);
      if (type == "POST") {
        httpreq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      }
      httpreq.send(data);
    }

    function loadList(readyState, status, responseText) {
      if (readyState == 4) {
        if (status == 200) {
          taskStorage = responseText;
          var tasks = eval("(" + taskStorage + ")");
          var html = "";
          for (var i=0; i<tasks.length; i++) {
            html += "<input type='checkbox' id='" + tasks[i].name + "'/><label for='" + tasks[i].name + "'>" + tasks[i].data + "</label><br/>";
          }
          document.getElementById("tasklist").innerHTML = html;


          if (typeof globalStorage != "undefined") {
            globalStorage[storageDomain].taskStorage = taskStorage;
          }
        }
      }
    }

    function fetchList() {
      if (navigator.onLine) {
        httpRequest("GET", null, loadList);
      }
      else {
        loadList(4, 200, taskStorage);
      }
    }

    function addItem() {
      var data = document.getElementById("data").value;
      document.getElementById("data").value = "";

      var tasks = eval("(" + taskStorage + ")");
      tasks.push({"name": Date.now(), "data": data });

      taskStorage = tasks.toJSONString();
      update();
    }

    function removeItems() {
      var tasks = eval("(" + taskStorage + ")");
      var newTasks = [];

      var items = document.getElementById("tasklist").getElementsByTagName("input");
      for (var i=0; i<items.length; i++) {
        if (items[i].checked == false) {
          newTasks.push(tasks[i]);
        }
      }

      taskStorage = newTasks.toJSONString();
      update();
    }

    function completeItems() {
      var tasks = eval("(" + taskStorage + ")");

      var items = document.getElementById("tasklist").getElementsByTagName("input");
      for (var i=0; i<items.length; i++) {
        if (items[i].checked) {
          var task = tasks[i].data;
          if (task.indexOf("<strike>") != -1) {
            task = task.replace("<strike>", "");
            task = task.replace("</strike>", "");
          }
          else {
            task = "<strike>" + task + "</strike>";
          }
          tasks[i].data = task;
        }
      }

      taskStorage = tasks.toJSONString();
      update();
    }

    function update() {
      if (navigator.onLine) {
        var post = "action=update&data=";
        post += encodeURIComponent(taskStorage);
        httpRequest("POST", post, function(readyState, status, json) { fetchList(); });
      }
      else {
        loadList(4, 200, taskStorage);
      }
    }
    </script>

    <style type="text/css">
      body          { font-family: verdana,tahoma, arial; }
      div#container { width: 300px; }
      div#title     { font-size: 120%; }
      div#subtitle  { font-size: 80%; }
      div#tasklist  { margin-bottom: .5em; }
      div#log       { font-size: 90%; background-color: lightgray; margin-top: 1em; white-space: pre; }
    </style>

  </head>
  <body onload="loaded();">
    <div id="container">
      <div id="title">Task Helper - <span id="status">ONLINE</span></div>
      <div id="subtitle">simple online/offline demo application</div>
      <hr />
      <div id="tasklist">
      </div>
      <input type="text" id="data" size="35" />
      <input type="button" value="Add" onclick="addItem();"/>
      <hr />
      <input type="button" value="Remove" onclick="removeItems();"/>
      <input type="button" value="Complete" onclick="completeItems();"/>
      <div id="log"><strong>Event Log</strong>
      </div>
    </div>
  </body>
</html>

Please help. Thanks.

A: 

I believe that the localStorage api is replacing globalStorage in FF 3.5. You can read more about it here: https://developer.mozilla.org/en/DOM/Storage

I think the api is very similar, so you could try something like this:

var storage;
if (typeof localStorage != "undefined") {
    storage = localStorage;
}
else if (typeof globalStorage != "undefined") {
    storage = globalStorage[storageDomain];
}
if (storage && storage.taskStorage) {
    taskStorage = storage.taskStorage;
}

Hope that helps!

EDIT: Anywhere you use globalStorage, you'll have to check for localStorage as well. Or promote the storage variable up in scope and detect it once.

Freyday
A: 

So after reading the question twice, I think I understood the question: you're asking about using globalStorage in file:/// documents.

globalStorage (as well as localStorage) doesn't work very well in file:/// documents as of Firefox 3.5. I didn't see the specific bug report about this issue, but since globalStorage is deprecated in favor of localStorage, it doesn't really matter.

If you're just testing it out, install some kind of web server locally, it's not complicated at all.

Nickolay