Home > Latest topics

Latest topics 近況報告

たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。

萌えるふぉくす子さんだば子本制作プロジェクトの動向はもえじら組ブログで。

宣伝1。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

宣伝2。Firefox Hacks Rebooted発売中。本書の1/3を使って、再起動不要なアドオンの作り方のテクニックや非同期処理の効率のいい書き方などを解説しています。既刊のFirefox 3 Hacks拡張機能開発チュートリアルと併せてどうぞ。

Firefox Hacks Rebooted ―Mozillaテクノロジ徹底活用テクニック
浅井 智也 池田 譲治 小山田 昌史 五味渕 大賀 下田 洋志 寺田 真 松澤 太郎
オライリージャパン

Page 9/239: « 5 6 7 8 9 10 11 12 13 »

UXU - UnitTest.XUL、1000人スピーカプロジェクト - Jan 21, 2008

amachangの1000人スピーカプロジェクト第1回でお披露目したUXU(うず)のこととか。書くのが遅くなったのは見てたからです。

プレゼンの話

ニコ動に全プレゼンの映像が上がってて僕の奴も見れるんですが、いやー、これはひどいプレゼンですね。

いや言い訳さしてもらうとですね、前日に仕事用マシン(Let's note W2)のHDDが逝ってしまいまして、前日夕方くらいからそれのせいであたふたして徹夜してて、あんまり頭働いてなかったんですよ。だからこの日はマシンは持参してたけどUbuntu 7.10のLive CDで起動してました。隣の人とか後ろの人とか多分CD-ROMドライブの音がぶんぶんうるさかったと思いますが、それはこのせいです。それにしてもUbuntuすごいね。CD起動なのに無線LAN使えちゃったよ。さすがにプロジェクターの認識は再起動が必要みたいだったからプレゼンの時だけamachangにマシンをお借りしましたが。

プレゼンでちゃんと言えてなかったことの補足。自分がテストという物の意義を理解したのがRailsのそれだったので、UXUを最終的にどういうものにしたいのかという目標も、今の所はRailsに置いてます。なので、今は実現できてないけどfixtureみたいな物もできるようにはしたいと思ってます。

それか、もっと根本的なところで、テスト専用のプロファイルにその時だけ切り替えて……みたいなこともできるようにしたいんですが、この辺になってくるとプラットフォーム用のバイナリを作らないといけないような気がしていて気が重いです。もしかしたらProfile Switcherが解決のヒントになるでしょうか?

yieldの変な使い方の話

yieldの読み方は「いーるど」でよかったんですね。でもそれ知ってもどうしても「いぇーるど」と読んでしまう……

昨年頭にごにょごにょしてたのはプレゼン中に書いたお蔵入りバージョンのUXU 0.1のことなんですが、その時は単にウェイトの秒数を指定するだけでした。つい最近になって奥さんのエントリを見て、そうか「復帰条件」と考えれば返り値は数値だけじゃなくてもっとなんでも渡してイイんだな、とインスパイアされて、フラグを保持するオブジェクトを渡すパターンをまず実装し、それから関数を渡すパターンも実装したという次第です。

UXUでやってることの工夫というか特徴的なところは、yieldの本来の用途であるところのジェネレータ・イテレータの生成という役割を隠蔽してしまって、「処理の一時停止」「再開」という部分だけに特化した見せ方をしているところではないでしょうか。内部的には昨年頭に書いた話にあるとおり、setUpとかテストケースとかの関数オブジェクトの返り値がジェネレータであればタイマーを使ってイテレーションを行う、というだけのことなんですが。

amachangが紹介していたJSDeferredの方がもっときっと便利でいろんな事ができるとは思うんですが、プレゼンでも言った通り僕はN88BASICの行番号の呪縛から未だに逃れられていないような人間ですので、これ以上の複雑なことは脳が拒否して受け入れてくれんのですよ……

続きを表示する ...

Chromeウィンドウを最前面にする・最背面にする - Sep 26, 2007

Chromeウィンドウでは、window.open()window.openDialog()の第3引数でalwaysRaisedフラグを指定することで、「常に最前面に表示」状態のウィンドウを開くことができる(通常のスクリプトではこのフラグを使うには特権が必要)。じゃあ、すでに開かれているウィンドウを最前面にすることはできないのか? というのが今日のお題。

フォクすけクロックを使ってみて、Firefoxのウィンドウの下に時計が隠れてしまうのは不便きわまりないと思ったので、これをどうにかしたかった。最初は、前述のalwaysRaisedを使った方法でいけるかなと思ったんだけど、Firefoxのアドオンとして動作する時はこれでいいけどXULRunnerアプリとして動作する時には「開く元の親ウィンドウ」が無いからこれじゃダメだ、と気がついた。

んでちょっと調べてみた所によると、どうもnsIXULWindowインターフェースのzLevelというプロパティをいじることで、ウィンドウの重ね合わせの優先順位を動的に変更できるようだということが分かってきた。

以下のようにいくつかのインターフェースを経由することで、Chromeウィンドウ(nsIDOMWindow)からnsIXULWindowのインターフェースに辿り着くことができる。

var Ci = Components.interfaces;
var XULWindow = window
    .QueryInterface(Ci.nsIInterfaceRequestor)
    .getInterface(Ci.nsIWebNavigation)
    .QueryInterface(Ci.nsIDocShellTreeItem)
    .treeOwner
    .QueryInterface(Ci.nsIInterfaceRequestor)
    .getInterface(Ci.nsIXULWindow);

XULWindow.zLevel = Ci.nsIXULWindow.raisedZ;

zLevelに指定可能な値はnsIXULWindowインターフェースにおいて定数プロパティとして定義されていて、以下の種類がある。

プロパティ実際の値意味
Ci.nsIXULWindow.lowestZ 0 すべてのウィンドウの最背面
Ci.nsIXULWindow.loweredZ 4 すべてのChromeウィンドウの最背面
Ci.nsIXULWindow.normalZ 5 通常
Ci.nsIXULWindow.raisedZ 6 すべてのChromeウィンドウの最前面
Ci.nsIXULWindow.highestZ 9 すべてのウィンドウの最前面

lowestZloweredZの違いは、前者がエクスプローラその他Windowsネイティブのアプリケーションのウィンドウも含めてすべての最背面になるのに対して、後者はあくまでFirefoxのウィンドウの中での最背面になるだけであるということ。loweredZを指定したChromeウィンドウが他のネイティブアプリのウィンドウの下にある時、そのChromeウィンドウをクリックすると、そのChromeウィンドウがネイティブアプリのウィンドウの上に表示されるようになると同時に、それに「押し上げられる」形で、FirefoxのウィンドウすべてがそのChromeウィンドウより前面に表示される。

highestZraisedZもそれと同様に、後者を指定したウィンドウは上にネイティブアプリのウィンドウが重なりうるけど、前者にはいかなるウィンドウも上には重ならない……のかと思いきや、こちらはどっちを指定してみてもraisedZで期待される通りの挙動にしかならなかった(Firefoxのウィンドウの中での最前面になるだけで、他のネイティブアプリのウィンドウが前面にくると、その下に隠れてしまう)。これってバグ?

ちなみに、数値で1~3を指定した場合はloweredZ(4)を指定したのと同じ挙動になるようだ。多分7~8はraisedZ(6)と同じで、それ以上はすべてhighestZ(9)と同じになるんだろうと思うけど……前述の通りhighestZraisedZは実際の挙動に違いが全然無いので、それを確認することはできなかった。

あと、ずっと前にEz Sidebarでこの問題にぶち当たってから気になってるもののずっと直ってないみたいなんだけど、raisedZ以上が指定されたウィンドウがあると、通常のウィンドウで開いたモーダルダイアログが親ウィンドウの下に潜ってしまうという問題が起こる。パスワードの入力を求めるダイアログ等がFirefoxのウィンドウの下に潜ってしまって使い物にならないので、これはマジで困る。どうにかならんものだろうか。

――ということで対策を考えてみた。

var XULWindow = window
     .QueryInterface(Ci.nsIInterfaceRequestor)
     .getInterface(Ci.nsIWebNavigation)
     .QueryInterface(Ci.nsIDocShellTreeItem)
     .treeOwner
     .QueryInterface(Ci.nsIInterfaceRequestor)
     .getInterface(Ci.nsIXULWindow);
var observer = {
  observe : function(aSubect, aTopic, aData)
  {
    if (aTopic == "xul-window-registered") {
      XULWindow.zLevel = Ci.nsIXULWindow.normalZ;
      window.setTimeout(function() {
        XULWindow.zLevel = Ci.nsIXULWindow.highestZ;
      }, 250);
    }
  }
};

var ObserverService = Cc["@mozilla.org/observer-service;1"]
      .getService(Ci.nsIObserverService);
ObserverService.addObserver(MakeOnTopObserver,
                            "xul-window-registered", false);

新しいウィンドウが開かれる直前にウィンドウのzLevelを元に戻して、ウィンドウが開かれた後にまた最前面に戻す。こうすれば最後の問題は回避できる。

はてな匿名ダイアリー トラックバックローダー for Greasemonkey - Sep 18, 2007

どっちが正しいとかはどうでもいいがとかの増田エントリを見ていて、トラックバックとして書き込まれているレスをいちいちタブ開いて読むのが面倒だったので、ダブルクリックもしくは「show」ボタンのクリックでその場に読み込むようなスクリプトを探してみたんだけど、見付からなかったのでサクッと書いてみた。

Firefox + Greasemonkeyの組み合わせでしかテストしてないので、他の類似環境で動くかどうかは知りません。

さりげなく更新。一度展開した項目をもう一度展開しようとすると中身が消えてしまう問題を修正したり、外部サイトのトラックバックはインラインフレームで表示するようにしたり、項目の上でしばらく待つだけで項目を読み込むようにしたりしてみた。

もう一度検索し直してみたら似たスクリプトが既に存在していた……

更新。ボタンを押したりダブルクリックしたりした時に内容が消えてしまう問題を修正。

getElementsByなんちゃら の代わりにXPathを使う - Sep 09, 2007

拡張機能勉強会の時に焚き付けられたText Shadowのコード(textshadow.js)を教材にして拡張機能開発のノウハウを解説していくシリーズ。

W3CのDOMでは、要素ノード(およびそのリスト)を得る方法として以下の方法がある。

getElementById(aName)
IDをキーにして単一の要素ノードを得る。
getElementsByTagName(aTagName)
タグ名、要素名をキーにして要素ノードのリストを得る。
childNodes
子ノードのリスト。

本当はネームスペースを指定して検索する物もあるんだけど、ここでは割愛。

これら以外に、W3C DOMではないがこういうのもある。

getElementsByClassName(aClassName)
クラス名をキーにして要素ノードのリストを得る。WHATWGのWeb Applications 1.0で定義されており、Firefox 3で利用可能。
getElementsByAttribute(aName, aValue)
属性名と属性値をキーにして要素ノードのリストを得る。属性値として「*」を渡すとその属性を指定された要素全てを得る。FirefoxでXULドキュメントにおいて利用可能。

ただ、探したい要素ノードの条件が複雑な時は、これらを使って取得したノードリストをループ回して条件判断しないといけないし、そもそもこれらでは要素ノード以外は取得できない。そこで最近のJS界隈でよく使われているのが、XPathだ。

XPathとは、/html/descendant::li[@class="navigation"]という風な「式」でXMLノードを特定する技術だ。XPathの書き方を新たに憶える必要はあるが、これを使えば、複雑な条件に合致するノードのリストを一発で取得することができる。コードが簡潔になるのはいいことだし、FirefoxでもSafari 3でもOperaでも、普通にDOMとJavaScriptでごりごりやるのに比べて20倍以上高速に動作するという話もある。

XUL Tipsのページに書いてるけど、FirefoxではDOM3 XPathで提案されているXPath関係の機能が利用できる。詳しい解説はHawk's W3 Laboratoryの「DOMとXPathの連携」(サイトが消えてるので、インターネットアーカイブからどうぞ)を見て欲しい。リンク先では「Gecko用」と書かれてるけど、現在ではOperaとSafari 3でも利用できるようになっている。

続きを表示する ...

いざ要素名や属性名などを変えたくなった時にソースの中をあちこち探し回ったり巧みな正規表現を考えるために頭をひねったりしなくても済むようにするテク - Sep 05, 2007

拡張機能勉強会の時に焚き付けられたText Shadowのコード(textshadow.js)を教材にして拡張機能開発のノウハウを解説していくシリーズ。

Firefoxの拡張機能で、DOM要素ノードを動的に生成したり、編集したり、そうして生成したノードを後でまた収集したり、といった操作を行うような物を作る時は、必然的に、ソースの中に要素名や属性名が登場してくる。

var newNode = document.createElement('box');
newNode.setAttribute('class', 'my-custom-box');
parentBox.appendChild(newNode);

var nodes = document.evaluate('/descendant::*[@class="my-custom-box"]',
  document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0, maxi = nodes.snapshotLength; i < maxi; i++)
{
  this.processBox(nodes.snapshotItem(i));
}

こういう操作が一カ所だけにしか登場しないんなら別にいいけど、複数箇所で、似たような操作が何度もある場合は、要素名であるとか属性値・属性名であるとかノード検索の条件であるとかを、コードの冒頭で定数(定数プロパティ)として定義しておくことをお薦めしたい。

var myService = {
  CUSTOM_BOX_NODE_NAME  : 'box',
  CUSTOM_BOX_CLASS_NAME : 'my-custom-box',
  CUSTOM_BOX_EXPRESSION : '/descendant::*[@class="my-custom-box"]',
(略)

すると、さっきのような箇所はこうなる。

var newNode = document.createElement(this.CUSTOM_BOX_NODE_NAME);
newNode.setAttribute('class', this.CUSTOM_BOX_CLASS_NAME);
parentBox.appendChild(newNode);

var nodes = document.evaluate(this.CUSTOM_BOX_EXPRESSION, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0, maxi = nodes.snapshotLength; i < maxi; i++)
{
  this.processBox(nodes.snapshotItem(i));
}

textshadow.jsの冒頭箇所を見てみると、動的に生成するIDのプレフィクスとか、途中で生成する要素のクラス名であるとか、XPath式の中に埋め込む検索条件だとかを、片っ端から定数としてまとめて定義していることが分かるはずだ。

こうしておくと、いざクラス名が他の拡張機能とかぶっていたと判明した時なんかでも、ソースの頭の方をちょこっと書き換えるだけで済む。class属性の値として文字列リテラルが書かれている箇所を片っ端から探すようなことはしなくていい。

え? 一括置換を使えばすぐだろうって? まあ、確かにたいていの場合はそうなんだけど、でもそれじゃ解決できない時もある。

続きを表示する ...

他の拡張機能やFirefoxの機能を破壊しないための基本テク - Sep 04, 2007

拡張機能勉強会の時に焚き付けられたText Shadowのコード(textshadow.js)を教材にして拡張機能開発のノウハウを解説していくシリーズ。

JavaScriptでは、普通に宣言した変数や関数はグローバルな物になる。

var name = 'hoge';
function getItem(aKey) {
  return array[aKey];
}

だから、Firefoxで最初から定義されてるグローバル変数や関数と同じ名前の変数や関数を定義してしまうと、エラーが起こるし、最悪の場合はFirefoxが動かなくなってしまう。

// ステータスバーだけ表示した
// 新規ウィンドウを開く関数「loadURI」を定義。
function loadURI(aURI) {
  window.open(aURI, 'mytarget', 'status');
}
// でも、これをやってしまうと、事あるごとに
// 新しいウィンドウが開かれるようになってしまう。
// なぜなら、Firefox内で既に「loadURI」という関数が
// 「ページを現在のタブで読み込む関数」として
// 定義されているから。

// 「ブラウザの一覧」のページを新しいウィンドウで開いて、
// そのウィンドウをgBrowserという変数に格納する。
gBrowser = window.open('http://piro.sakura.ne.jp/browsers-list.html');
// でも、これをやってしまうと、Firefoxがまともに
// 動かなくなる。なぜなら、Firefoxのブラウズ領域の
// 要素ノードへの参照としてgBrowserが定義されているから。

これを防ぐ手っ取り早い方法としてお勧めしたいのが、自分の拡張機能で使う変数や関数を、「自分の拡張機能専用のサービスオブジェクト」のプロパティやメソッドとして保持するようにするというやり方だ。

続きを表示する ...

第6回拡張機能勉強会 - Sep 03, 2007

目が覚めたら14時でした。

勉強会本体の感想。

Firemacs作者の山本さんの話を聞いてると、以前の自分を思い出した。XPCOMにどんな機能があるのか知らなかった頃に、知ってる範囲の知識でどうにかして解決しようとあれこれ工夫を試みていた。そういう「工夫」を思い付くかどうか、というのが、もしかしたらある種の「分れ道」なのかもしれないなと思った。

marさんによるXUL preLoaderの話。

  • XULオーバーレイでボタンを追加したいのに、その要素にidが指定されていない、という場合、JavaScriptとDOMを使ってXUL要素を生成して埋め込むという方法をとらざるを得ない。
  • オーバーレイで読み込むXUL文書を間に一つ増やして、その「間に挟まれた」XUL文書においてid属性をスクリプトで設定してオーバーレイを適用できるようにしてから、改めて、本来オーバーレイで読み込ませたかったXUL文書をdocument.loadOverlay()で動的に読み込む。……というのが、preLoaderの発想。

preLoaderのような発想が僕に無かったのは、loadOverlayというメソッドを知らなかった・存在を忘れてたからというのも大きいんだけど、それ以前に、他の拡張機能で同じ方法を使われて異なるIDを指定されてしまったらこのテクニックは破綻してしまう、ということに気づいていたからだ。僕は以前から、拡張機能を作るときは他の拡張機能となるべく衝突しないようにということに気を付けるようにしている(TBEの時はそれで散々叩かれたし)ので、preLoaderのテクニックはあまり推奨しづらい。

ところで、今ふと思ったんだけど。E4X使ったらJavaScriptの中に普通にXUL文書片を書けるから、preLoaderあんまりいらなくね?(ぉ

誕生日を祝ってもらえて、フォクすけは幸せ者ですね。僕もこれくらい愛されてみたいです。どうでもいいですが、ケーキの周りのフィルムについたクリームを舐め取っている様子をばっちり撮られてしまっていました。

Mozilla 24のための各プログラムの番宣ビデオ?の撮影があって、Shibuya.jsのビデオに僕まで出ることになってしまった、というかほとんど僕が喋ってた。幽霊部員なのに。あとで映像見てみても、ほんとキモイなーと思った。また叩かれるんだろうなあ。いやだなあ。

続きを表示する ...

この道はいつか来た道(他の人が) - Aug 01, 2007

Bugzillaの方のコメントにも書かれてるけど、テキストシャドウを公開した後で、2年以上前に同じようなことをやってた人がいたことを知った。いやぁ、薄々「既出なんじゃね?」とは思ってはいたんですけどね。

一応、対応してる機能(CSSのセレクタをかなりまじめに解釈してる)や使い勝手(XBLを使ってるので影付きテキストのコピペで困らない、アドオンだから自動アップデートできる、など)の面でアドバンテージはあると思うけど……まあ追加のコメントにも書いたように、頑張ればそれもGreasemonkeyスクリプトで実現は可能そうではあるわけで、アドオン嫌いグリモン好きというタイプの人は頑張ってみるのもいいかもね。

Page 9/239: « 5 6 7 8 9 10 11 12 13 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のつぶやき

オススメ

Mozilla Firefox ブラウザ無料ダウンロード