Hatena::Groupmoz-addon

Ci.nsIZIGOROu

2008-09-17

子要素を全部削除

| 16:21 |  子要素を全部削除 - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  子要素を全部削除 - Ci.nsIZIGOROu

while (element.firstChild)
  element.removeChild(element.firstChild);

でいいかな?innerHTML = "" だとtext nodeが残るしなー。

takenspctakenspc2008/09/17 20:02DOM 2 Range を使う方法もあるようです。
http://purl.org/jintrick/Personal/DOM_Range.html#EMPT_DIV

mayokara384mayokara3842008/09/17 21:44element.parentNode.replaceChild(element.cloneNode(false), element)という方法もありますが、イベントリスナが消えます。

ZIGOROuZIGOROu2008/09/19 10:17> takenさん
おー、そんな方法もあるんですね。ありがとうございます。
> mayokara384 さん
nrhd
これは目から鱗www
cloneNode(false)で自分自身置換かー。

2008-08-11

今日のJavaScriptプチtips

| 15:05 |  今日のJavaScriptプチtips - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  今日のJavaScriptプチtips - Ci.nsIZIGOROu

文字列の存在確認からtoLowerCase()までワンライナー

var name = "HolyGrail";
alert(name && name.toLowerCase()); // holygrail

for each - let で要素を列挙

for each ( let item in "yappo hirose31 tokuhirom" ) {
  alert( item );
}

まとめ

chrome://browser/content/pageinfo/feeds.js

JaylynnJaylynn2011/12/30 15:44You've got to be kdiding me-it's so transparently clear now!

cihkqonnncihkqonnn2011/12/31 17:09QECXVo <a href="http://eyjqeqncluyu.com/">eyjqeqncluyu</a>

twgxckytwgxcky2011/12/31 22:47Nd72Oe , [url=http://pqvzzcatthaj.com/]pqvzzcatthaj[/url], [link=http://ymbrvznkcolt.com/]ymbrvznkcolt[/link], http://hfquuyoupfdu.com/

utczioutczio2012/01/01 22:33I53GJv <a href="http://gpmloblunvmv.com/">gpmloblunvmv</a>

ivsuvegsivsuvegs2012/01/02 03:26mE8149 , [url=http://zopvzvpgbsrz.com/]zopvzvpgbsrz[/url], [link=http://dmdirlxxmhtw.com/]dmdirlxxmhtw[/link], http://dabigaimaqjd.com/

2008-06-10

JS Code Module での Singleton

| 13:59 |  JS Code Module での Singleton - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  JS Code Module での Singleton - Ci.nsIZIGOROu

var EXPORTED_SYMBOLS = ['_singleton', 'Singleton'];

var _singleton = null;

var Singleton = function() {
  if (Components.stack.filename != Components.stack.caller.filename)
	throw new Error('private constructor');
};

Singleton.getInstance = function() {
  if (!(_singleton instanceof Singleton))
	_singleton = new Singleton();
  return _singleton;
};

こんなんで出来ちゃう件。コンストラクタは外部から呼べないようにしてみた。

iufmuijcfpiufmuijcfp2011/04/08 03:14xS42aR <a href="http://pzwbfbxoaztw.com/">pzwbfbxoaztw</a>, [url=http://nycqufeyznko.com/]nycqufeyznko[/url], [link=http://xobbqvvaigma.com/]xobbqvvaigma[/link], http://ovwhykwkxjsl.com/

2008-06-03><

Statement は close する前に finalize() する

| 17:47 |  Statement は close する前に finalize() する - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  Statement は close する前に finalize() する - Ci.nsIZIGOROu

忘れちゃダメだかんね!

finalize()し忘れるとFILEがロックされっぱになってclose()でコケます。

もしwrapper作るならclose, createStatementにそれぞれ wrap して、close()の時にfinalize()してないstatementがあれば全部やるとかやった方がいいっぽぃ。

nsIPropertyBag, nsISimpleEnumerator, nsIProperty

| 14:07 |  nsIPropertyBag, nsISimpleEnumerator, nsIProperty - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  nsIPropertyBag, nsISimpleEnumerator, nsIProperty - Ci.nsIZIGOROu

nsIWritablePropertyBag と wrappedJSObject - Ci.nsIZIGOROu - Mozilla 拡張機能勉強会 の続き。

キーの列挙は nsIPropertyBag.enumerator を他の変数に使うたびに代入して行う。

コードとしては下記のような感じになるかなと。

var props = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag);
// 中略、ここでキーに色々入れる
var iterator = props.enumerator;
while (iterator.hasMoreElements()) {
  with ({prop: iterator:getNext()}) {
    prop.QueryInterface(Ci.nsIProperty);
    // 以下略
  }
}

hasMoreElements() で確認して getNext() するんだけど、この際にnsISuportsで返ってくるんだけど、nsIProperty を実装したオブジェクトが返ってくるので QueryInterface で型変換する。

name, valueと言うメンバ変数がreadonlyで提供されるので、これで元のhashのキーと値が取れる寸法。

インターフェース操作、要するにQueryInterfaceを何度か駆使しなきゃいけないのは面倒だけど、こうしてJSオブジェクトが突っ込めるハッシュがあると便利だな。


nsIWritablePropertyBag と wrappedJSObject

| 13:30 |  nsIWritablePropertyBag と wrappedJSObject - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  nsIWritablePropertyBag と wrappedJSObject - Ci.nsIZIGOROu

d:id:fls さんに教えて貰った wrappedJSObject と nsIWritablePropertyBag についてです。

準備

function wrapped(obj) {
  return { wrappedJSObject: obj };
}

とか定義しておく。

実験

var props = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag);
var data = {a: 1, b: 2};
props.setProperty("foo", data);
props.setProperty("bar", wrapped(data));

とした時に、getPropertyしたらどうなるかと言う話。

Fx2
props.getProperty("foo")
[xpconnect wrapped nsISupports]{QueryInterface: function() {}}

となり、props.getProperty("foo").a とか取れません。

一方で wrappedJSObject しておくと、

props.getProperty("bar");
// [xpconnect wrapped nsISupports] — {QueryInterface: function() {…}}
props.getProperty("bar").wrappedJSObject;
// [object Object] — {a: 1, b: 2}

と言う訳で wrappedJSObject プロパティが出来てます。

Fx3

こっちはgetPropertyした時点で生のJSオブジェクトが帰って来ます。つまり

props.getProperty("foo").a; // 1
props.getProperty("bar").wrappedJSObject.a; // 1

便利になったけど、互換性のある書き方としては後者のwrappedJSObjectを使う場合ですね。

まとめ

と言う訳でwrappedJSObject使うと幸せになれます^^


joinした際に重複するカラム名がある場合、区別が出来ない件

| 13:03 |  joinした際に重複するカラム名がある場合、区別が出来ない件 - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  joinした際に重複するカラム名がある場合、区別が出来ない件 - Ci.nsIZIGOROu

例えば以下のようなクエリがあるとする。

SELECT * FROM Foo, Bar WHERE Foo.name = Bar.name;

当然両者にnameと言うカラムがあるんだけど、これが Storage だと区別が付けられない。

もちろんそれぞれのカラムインデックスが振ってあるので mozIStorageValueArray の get系メソッドインデックス指定すれば問題無いのですが、意図的に区別しないといけないので厄介過ぎる件。

まぁこのように実際にjoin時のキーになるなら同じ値であるから問題無いんですが、

  • mozIStorageStatementWrapper で
  • joinのキーになってない、つまり同じ値じゃない同じ名前のカラムが複数ある

って場合は mozIStorageStatementWrapper じゃ成り立たない気がする。

明後日以降に試してみる。

2008-05-28

Components.utils.getWeakReference() がウマーな件

| 19:13 |  Components.utils.getWeakReference() がウマーな件 - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  Components.utils.getWeakReference() がウマーな件 - Ci.nsIZIGOROu

JS XPCOM などで呼び出し元の JS のコンテキストに対して、Object 型の値を返すとか、あるいは Object 型をそのまま渡すとかっていう事は原則として出来ませんでした。

Firefox 3からある Components.utils.getWeakReference() を使うとそれが出来るようになります。

nsIObserverService を使った例

例えば次のようなソースを用意して実行します。(どこかで)

var EXPORTED_SYMBOLS = ["testObserval"];

const Cc = Components.classes;
const Ci = Components.interfaces;

var testObserval = (function() {
  var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
  var constructor = function() {
  };

  var TEST_TOPIC = "test-observer-notify";

  constructor.prototype = {
	notify: function(aData) {
	  observerService.notifyObservers({ foo: 1 }, TEST_TOPIC, aData);
	},
	notifyJSObject: function(aData) {
	  observerService.notifyObservers(Components.utils.getWeakReference({ foo: 1 }), TEST_TOPIC, aData);
	},
	register: function(aObserver) {
	  observerService.addObserver(aObserver, TEST_TOPIC, false);
	},
	remove: function(aObserver) {
	  observerService.removeObserver(aObserver, TEST_TOPIC);
	}
  };

  return new constructor();
})();

これは Components.utils.import で読み込んで下さい。JS XPCOM 相当と言う事を確認する為です。

次に呼び出し側の ChromeWindow の JS のコンテキストで、

var testObserver = (function() {
  var constructor = function() {
	this.subject = null;
	this.topic = "";
	this.data = "";
  };

  constructor.prototype = {
	logger: Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService),
	observe: function(aSubject, aTopic, aData) {
	  this.log(aTopic);
	  this.subject = aSubject;
	  this.topic = aTopic;
	  this.data = aData;
	},
	interfaces: function() {
	  var ifaces = [];
	  for (var iface in Ci) {
		if (this.subject instanceof Ci[iface]) {
		  ifaces.push(iface);
		}
	  }
	  return ifaces;
	},
	log: function(msg) {
	  this.logger.logStringMessage(msg);
	}
  };

  return new constructor();
})();

を定義しておきます。

次に testObserval の register で testObserver を登録します。

testObserval.register(testObserver);

次に普通にnotifyしてみます。

testObserval.notify("bar");

中では無理矢理 JSObject 型を subject としています。

testObserver.interfaces().toString(); // nsISupports 

なので、これ以上何も出来ません><

getWeakReference を使うとどうなるか

今度は testObserval.notifyJSObject を代わりに使ってみます。

testObserval.notifyJSObject("bar");

同じように実装しているインターフェースを見てみます。

testObserver.interfaces().toString(); // xpcIJSWeakReference,nsISupports

xpcIJSWeakReference が実装されたオブジェクトが返ってきます。

従って subject の QueryInterface() でキャストして、ここで使えるget()メソッドを呼び出してみると、

testObserver.subject.QueryInterface(Ci.xpcIJSWeakReference).get().foo; // 1

のようにぶち込んだ Objectプロパティアクセス出来ます。

まとめ

今まで XPCOM 的なプリミティブな値か XPCOM オブジェクトしか XPConnect 経由で渡せなかったけど、Componsnts.utils.getWeakReference() を使えば、JSオブジェクトそのままで渡す事が可能になります。

すげー。

呼び出し元では QueryInterface() して get() と言う余計な手続きはありますが、そのまま扱えるのは非常に大きなメリットだなと。この辺りはgetter/setterとかで何とかしちゃえば良さそうだし。

追記 (2008-06-01T02:01:08+09:00)

d:id:fls さんから教えて頂いた wrappedJSObject なら全然問題無いとの事でした。ほぉー。

piro_orpiro_or2008/05/28 19:53要点だけ抜き出すと

var observerService = Cc["@mozilla.org/observer-service;1"]
    .getService(Ci.nsIObserverService);

// XPCOMのインターフェースを通と生のJSオブジェクトにアクセスできない
var observer = {
observe : function(aSubject, aTopic, aData) {
alert(aSubject.foo); // undefined
}
};
observerService.addObserver(observer, 'test-topic', false);
observerService.notifyObservers(
{ foo : 1 },
'test-topic',
null
);
observerService.removeObserver(observer, 'test-topic');

// XPCOMのインターフェース越しで生のJSオブジェクトにアクセスする
var observer = {
observe : function(aSubject, aTopic, aData) {
aSubject = aSubject.QueryInterface(Ci.xpcIJSWeakReference).get(); //****追加****
alert(aSubject.foo); // 1
}
};
observerService.addObserver(observer, 'test-topic', false);
observerService.notifyObservers(
Components.utils.getWeakReference( //****追加****
{ foo : 1 }
), //****追加****
'test-topic',
null
);
observerService.removeObserver(observer, 'test-topic');

てことでしょうか?
第1引数のsubjectはあくまでsubject(主語)としてのみ使うものだ、という思い込みがあったので、こういう使い方は思いつきませんでしたね……

ZIGOROuZIGOROu2008/05/29 11:11> てことでしょうか?

て事ですね。

> 第1引数のsubjectはあくまでsubject(主語)としてのみ使うものだ

第一引数のsubjectを何に使うべきかと言う議論もあるかもしれませんが、言いたい事はそこじゃなくて、xpcIJSWeakReferenceとしてやりとりすれば素のJSオブジェクトでやり取り出来るという事だけですね。

flsfls2008/05/30 21:00wrappedJSObject を使えば簡単にJSオブジェクトでやり取りできますよ

function SubjectWrapper(aObject){
this.wrappedJSObject = aObject;
}

var observer = {
observe : function(aSubject, aTopic, aData) {
alert(aSubject.wrappedJSObject.foo);
}
};

observerService.addObserver(observer, 'test-topic', false);
observerService.notifyObservers(new SubjectWrapper({ foo:1 }), 'test-topic', null);
observerService.removeObserver(observer, 'test-topic');

ZIGOROuZIGOROu2008/06/01 01:57> d:id:fls さん

うへw 知らなかった><
ありがとうございます。勉強になります。

NanaNana2012/07/23 13:02This is an article that makes you think "never touhght of that!"

ivdpvghivdpvgh2012/07/23 22:06z9fRrF <a href="http://dhhlfemkguyw.com/">dhhlfemkguyw</a>

tbsgzgtbsgzg2012/07/24 11:43Ynms0P , [url=http://tvzpvwukgsei.com/]tvzpvwukgsei[/url], [link=http://qdfuftfcfvqc.com/]qdfuftfcfvqc[/link], http://ptogkdwzynow.com/

htuuvzjhtuuvzj2012/07/25 22:35yAH5UE <a href="http://pwhtacsynlwv.com/">pwhtacsynlwv</a>

bekljzllabekljzlla2012/07/26 22:591z5SBX , [url=http://irtffefggpcq.com/]irtffefggpcq[/url], [link=http://zchnxrdznina.com/]zchnxrdznina[/link], http://zgnrqcekjqgd.com/