Hatena::Groupmoz-addon

hogezilla RSSフィード

当ページに書かれているコードは、修正BSDライセンスのもと、再頒布して頂いて構いません。

2013-12-02

JavaScriptコードモジュール内で console や Promsie を使う

21:46 | はてなブックマーク - JavaScriptコードモジュール内で console や Promsie を使う - hogezilla

JavaScript コードモジュール内では DOM が存在しない。

普通のJavaScriptに慣れてしまうと、console オブジェクトがなかったり、Promsie がなかったり、setTimeout がなかったりでちょいと面倒な思いをする。

ってことで、ダーティな気がするけど、無理やり使えるようにしちゃおう。

Components.utils.import("resource://gre/modules/Services.jsm");
const { console, Promise, setTimeout } = Services.appShell.hiddenDOMWindow;

console.group("Test");
console.dir(this);
(new Promise(function (r) {
  setTimeout(function() {
    if (typeof r === "function") {
      r("OK");
      return;
    }
    r.resolve("OK (old Promise)");
  }, 500);
}).then(function(msg) {
  console.log("Promise: " + msg);
});
console.groupEnd();

Services.appShell(nsIAppShellService)には、hiddenDOMWindowという、名前の通り隠されたDOMWindowオブジェクトを持っている。当然、DOMを持っていたりするので、ここから console 等を取ってきてしまおうという作戦。

console オブジェクトの各メソッドから出るログは、従来のJavaScriptコンソールだと出てこないが、最近のFirefoxにあるブラウザコンソールなら出てくる。(Thunderbird アドオンでのロギング時には注意が必要かも)

トラックバック - http://moz-addon.g.hatena.ne.jp/teramako/20131202

2013-07-06

要素の ARIA role 値を得る

| 20:05 | はてなブックマーク - 要素の ARIA role 値を得る - hogezilla

HTMLの要素には暗黙的に付くARIA roleが定められているものある。これってどうやって取るの? って話

"use strict";
const gAccRetrieval = Cc["@mozilla.org/accessibleRetrieval;1"]
                      .getService(Ci.nsIAccessibleRetrieval);

function getAccessible (elm) {
  return gAccRetrieval.getAccessibleFor(elm);
}

function getARIARole (elm) {
  var acc = getAccessible(elm);
  if (acc) {
    var attrs = acc.attributes;
    if (attrs.has("xml-roles"))
      return attrs.getStringProperty("xml-roles");
  }
  return "";
}
  1. 対象要素の nsIAccessible インスタンスを得る
  2. その属性値からxml-rolesキーの値を得る

参考

トラックバック - http://moz-addon.g.hatena.ne.jp/teramako/20130706

2013-06-03

nsIXULSortService

| 23:19 | はてなブックマーク - nsIXULSortService - hogezilla

使用可能なメソッドは sort のみ。

引数:

  1. コンテナとなる親要素
  2. ソートに使用する値を持つ属性名
  3. ソート種類(以下の値を空白区切りで指定)
    • ascending: 昇順
    • descending: 降順
    • comparecase: 大文字小文字を区別
    • integer: 値を整数とみなす
    • twostate: ?

XUL と付いているけど DOM なら OK だと思われる。

<ol id="container">
  <li value="3">b</li>
  <li value="10">a</li>
  <li value="4">c</li>
  <li value="5">d</li>
</ol>
const sortSerive = Cc["@mozilla.org/xul/xul-sort-service;1"].getService(Ci.nsIXULSortService);

var ol = document.getElementById("container");

sortService.sort(ol, "value", "integer descending");

とすると

<ol id="container">
  <li value="10">a</li>
  <li value="5">d</li>
  <li value="4">c</li>
  <li value="3">b</li>
</ol>

と並び替えられる。

トラックバック - http://moz-addon.g.hatena.ne.jp/teramako/20130603

2013-05-22

Firefox 24 で browser.__SS_restoreState が削除された

| 21:18 | はてなブックマーク - Firefox 24 で browser.__SS_restoreState が削除された - hogezilla

これまで、起動時等のタブは前のセッションから回復しているが、コンテンツはまだロードされていない状態を示すフラグ的プロパティとして、browser.__SS_restoreState というプロパティに1が入ってた。そして、ロードされた後は、このプロパティは削除されるという挙動であった。

が、このバグで、__SS_restoreStateプロパティは使用されなくなる。

代わりに、nsISessionStore.isTabStateNeedsRestore(browser) を使用して真偽値を得るように変更された。


before after

before

var browser = gBrowser.browsers[i];
if ("__SS_restoreState" in browser) {
  // not restored yet
}

after

const sessionStore = Cc["@mozilla.org/browser/sessionstore;1"].getServices(Ci.nsISessionStore);
var browser = gBrowser.browsers[i];
if (sessionstore.isTabStateNeedsRestore(browser)) {
  // not restored yet
}

参考

Firefox 23 で browser.__SS_data が削除された

| 21:17 | はてなブックマーク - Firefox 23 で browser.__SS_data が削除された - hogezilla

これまで、browser.__SS_dataにタブのセッションデータを得ることができたが、削除されてしまった。

代わりに、きちんとnsISessionStore.getTabState(tab)を使用しないといけない。

const sessionStore = Cc["@mozilla.org/browser/sessionstore;1"].getServices(Ci.nsISessionStore);
var tab = gBrowser.tabs[i];
var tabState = JSON.parse(sessionStore.getTabState(tab));
トラックバック - http://moz-addon.g.hatena.ne.jp/teramako/20130522

2013-03-06

Bug-407956 Firefox 22 で nsITreeView の nsISupportsArray が削除された件の対応

21:34 | はてなブックマーク - Bug-407956 Firefox 22 で nsITreeView の nsISupportsArray が削除された件の対応 - hogezilla

nsITreeViewの実装が変更され、 以下のメソッドのnsISupportsArray型のpropertiesが削除された。

  • getCellProperties (in long row, in nsITreeColumn col, in nsISupportsArray properties)
  • getColumnProperties (in nsITreeColumn col, in nsISupportsArray properties)
  • getRowProperties (in long index, in nsISupportsArray properties)

Firefox22からは、properties.AppendElement(nsIAtom)をするのではなく、文字列を空白区切りで返すことになる。

とはいえ、アドオン作成としてはFirefox21-との互換性も重要なので、両対応のメソッドを定義する必要がある。

Firefox21-とFirefox22+の両対応

getRowPropertiesをサンプルに両対応コード例を書いておく。

function nsICustomTreeView () {
  this.rows = [];
}
nsICustomTreeView.prototype = {
  // ....
  getRowProperties: function (row, properties) {
    var item = this.rows[row];
    var isSupportsArray = true;
    if (!properties) {
      isSupportsArray = false;
      properties = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
    }
    /*
      今まで通り properties.AppendElement するコード
     */
    if (!isSupportsArray) {
      let props = [];
      for (let i = 0, len = properties.Count(); i < len; ++i) {
        props.push(properties.GetElementAt(i));
      }
      return props.join(" ");
    }
  },
  // ...
};
  1. Firefox22+では、propertiesは渡ってこないので、存在しないならnsISupportsArrayを生成する
    • その際、フラグ設定もしておく
  2. これまで通り、properties.AppendElement(...)していく
  3. 最後に、配列に突っ込んで、連結して返す

Services.vc.compare(Services.appinfo.version, "22.0a1")等で比較をして、メソッド自体を書き換えたほうが効率が良いかもしれない。

トラックバック - http://moz-addon.g.hatena.ne.jp/teramako/20130306