firefox とか javascript とか XPConnect とか

すっかりWeb系のnihaです。
ほんまかいな。

Fx3 でブックマークが色々変わった

Fx2 までは、ブックマークは bookmarks.html で管理されていましたが、Fx3 からは places.sqlite で管理されるようになりました。
ボクはこれまで bookmarks.html をホームページに設定して、ブックマークからページを開きたいときは新しいタブにホームページを表示していたりしたので、これは困るわけ。
ということで javascript でブックマークの一覧を表示するようなものを書こう。
書きました。大変でした。

XPConnect を使う

ブックマークのデータを引っ張ってくるには、まあ places.sqlite から引っ張ってきてもいいんですがすごくだるそうなので、どうせなら firefox から引っ張ってこようよ、ということでそうします。
どうするかというと XPCOM というコンポーネントがあって、何ができるかというとまあ色々できる。mozilla developer center とか読んで! XPConnect はその javascriptバインディング
こんな色々できる子が普通に使えたら問題があるわけで、通常は制限されています。まずはその制限を解除する必要があって、何も考えずにエディタに以下のように入力しましょう。

netscape.security.PrivilegeManager.enablePrivilege ('UniversalXPConnect');

深く考えてはいけない。
で、世の中の便利なものの多くがそうであるように、こいつはとにかく面倒くさい。
あんまりめんどくさいので説明とか書くのだるいし多分自分も含めて誰も読まないので、知りたかったら moxilla developer center とか読んで!
下にコード貼っときます。

結論

ブックマークはもう捨てろ。

<html>
  <head>
    <title>bookmark</title>
    <style type='text/css'>
      div.folder{
        padding: 0.5em;
        margin: 1em;
		border: 1px solid black;
      }
      h1.folder{
        margin: 0px;
        font-size: 1em;
      }
    </style>
    <script language='javascript'>
      window.onload = function(){
        netscape.security.PrivilegeManager.enablePrivilege ('UniversalXPConnect');
        var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"].getService(Components.interfaces.nsINavHistoryService);
        var options = historyService.getNewQueryOptions();
        var bookmarksService = Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Components.interfaces.nsINavBookmarksService);

        function listFolder(folder, elem){
          var query = historyService.getNewQuery();
          query.setFolders([folder], 1);
          var result = historyService.executeQuery(query, options);
          var rootNode = result.root;
          rootNode.containerOpen = true;
          for (var i = 0; i < rootNode.childCount; i++) {
            var node = rootNode.getChild(i);
            var id = node.itemId;
            var title = node.title;
            var type = bookmarksService.getItemType(id);
            var br = document.createElement('br');
            if (type == bookmarksService.TYPE_BOOKMARK){
              var a = document.createElement('a');
              a.innerHTML = title;
              var uri = bookmarksService.getBookmarkURI(id);
              a.href = uri.prePath + uri.path;
              elem.appendChild(a);
              elem.appendChild(br);
            } else if (type == bookmarksService.TYPE_SEPARATOR){
              var hr = document.createElement('hr');
              elem.appendChild(hr);
            } else if (type == bookmarksService.TYPE_FOLDER){
              var div = document.createElement('div');
              div.id = title;
              div.className = 'folder';
              var h = document.createElement('h1');
              h.className = 'folder';
              h.innerHTML = title;
              div.appendChild(h);
              listFolder(id, div);
              elem.appendChild(div);
            }
          }
          rootNode.containerOpen = false;
        }

        listFolder(bookmarksService.bookmarksMenuFolder, document.getElementById('bookmarksMenuFolder'));
      }
    </script>
  </head>
  <body>
    <div id='bookmarksMenuFolder' class='folder'>
    </div>
  </body>
</html>

HTMLとかCSSとかjavascriptとか似非Web系なのでわかりません。