クラシックまじらもじら
 Classic Mazilla-Mozilla
クラシックまじらもじら


WebShellの現状とその消滅への道



題名: WebShellの現状とその消滅への道
日付: 2000年3月2日
著者: Travis Bogard <travis@netscape.com>


みなさん、こんにちは。

この数日、数週間、数カ月、私は、WebShellの現状、何がWebShellに取って
代わるか、そして何時それは収束するのか、という多くの質問を受けました。
また、多くの人は、どのInterfaceを使うべきかで、困惑しています。
時々は、誰かが古いInterfaceを使って、新しいコードを追加しようとしている
のに出くわすこともあります。
それで、どのように事が進行しているかを皆に知ってもらう為に、このメールを
書きます。またこの記事は、新しいデザインの為に、どのInterfaceを使うのが
正しいかを知りたい人にも、役立つでしょう。
この事が片付いたら、皆で酒でも飲みながらシステムデザインを語り合いたいの
ですが、今はこの記事であなたたちの幾人かが、苦境を乗り切ってくれれば幸い
です。


目次:
1)何がWebShellに取って替わるか
2)何時WebShellは収束するのか
3)何がやり残されているか
4)どうやってembedできるか
5)どのInterfaceを使うべきか
6)典型的なコーディングの問題
7)まとめ


************************************
1)何がWebShellに取って替わるか
************************************

webshellは、今まで3つの理由で使われてきました。

その第一は、webshellは、loadされたdocumentとそのpresentationとの
基本的なconnection、frameset tree 構造の基礎、DOMとそのpresentation
とのconnection、などを提供することです。色々な意味で、例えば、システム
の一部が他の部分を必要としている時、それを見つけられるようにいろいろな
ものを管理する、交通整理のようなものです。これらの仕事は今ではdocShell
が担っています。docShellは、私達の内部的な要求を処理する為の、簡易版
webShellです。

そして 第二は、embeddingです。docShellは、Geckoをembeddingする為にも
使えますが、webShellが持っているのと同じembeddingの問題を抱えています。
その問題とは、あまりにも内部処理が多く、その中心が内部処理に片寄ってしまう
ということです。その煩雑さのあまり、embedder(プログラマー)は困惑するか、
更には、必要以上の困難な仕事を強いられることになります。
このことを解消する為に、"mozilla/embedding/browser"にembedding API
が作られました。これらがembeddingの上位I/Fとなります。embedding API
は、一般的docShellのAPIを、browser特有の視点から平易に眺めなおしたもの
に過ぎません。でも、しばしばembedding階層はbrowserとして振る舞う為に
docshellをsetupして、embedderの仕事を助けます。

第三は、歴史的にwebShellは、ゴミ捨て場に使われていたということです。
でもこれは改善せねばなりません。これは、過去においては大問題でした。
しばしば、あるコードを他の場所へ移さねばならない時、docShellが、更に
昔はwebShellが、その槍玉に揚げられました。それが正しい場所である時も
ありましたが、慎重に事を進めねばなりません。そこに入れるべきではない
コードを持ち込むと、機能と性能が損なわれます。webShell、docShellに
何かを追加したい時は、私に話してください。うまくフィットさせる為に、
喜んで議論しましょう。もしかしたらそのコードは、docshellから別れて
いったもの(uriloading、session history、progress listeners、
embedding)の方に入れるべきかもしれませんので。

****************************************************
2)何時WebShellは収束するのか
****************************************************

これは非常に答えにくい質問です、というのは、あなたがどういう意味で
"収束"というのかによるからです。現実的には、webshellは長い時間を
かけて収束しつつあり、既に色々な形で使われているということです。
しかし同時に、webshellの代価要員たちはまだ出そろっておらず、収束
していません。
これでは、webshellが生きているのか死んでいるのか分らないという混乱を
招きそうですが、結局は、webshellは、いろいろなものの単純な集合体に
なると、私は思います。

前にも述べた通り、docshellはwebShellのコアの主要代価物です。
docShellはそこにあり、いろいろな関数からコールされます。
webShellは今ではdocShellのサブクラスであり、そのインプリメンテーション
は、docShellに依存しています。まだdocShellに移し終わっていない幾つかの
事柄もあります。(section3参照)
しかし基本方針は、docShellの新機能を決め、それをwebShellから削ぎ落とし、
webShellはその機能をdocShellに完全に任せる、というものです。
docShellが成熟すればするほど、webShellが削ぎ落とされていきます。
これ以上機能をwebShellからdocShellに移せなくなったら、ゴールです。
ゴールは近い!

webShellが、その直接の親とやり取りする事柄は非常に多いので、両者には
色々な変更が発生します。
得に、nsWebShellWindowはその候補です。
ここであなたが目にする
新しいクラスnsXULWindowとインターフェースnsIXULWindowは、
古いクラスnsWebShellWindowとインターフェースnsIWebShellWindowに
取って代わるものです。
nsWebShellWindowはnsXULWindowのサブクラスであり、ここでも多くの
機能が、nsWebShellWindowからnsXULWindowに移行しています。

以上のような掃除作業を完全に遂行する為には、全ての部分を機能させる為、
更に次の事を考えねばなりません。
新しいデザインが明らかで、掃除作業の必要もなく機能にアクセスできる
ような場合には、その手法を取る。
掃除作業によって、新機能にアクセスできるような場合は、その手法を取る。
要は、機能にアクセスできるようにするという事が、(webShellを完全に
システムから消し去るなどの)小奇麗にするという事より優先される、
ということです。
私は、小奇麗さに捕われないよう注意しています。docShellとxulWindow
の両ケースとも、これらのクラスを、古いデザインを新しいデザインと区別
する為の境界線として使う、というのが真の目的です。盲目的に持っていった
古いコードで新しいクラスを汚すくらいなら、2つのクラスを暫く残しておく
ほうがましです。
しかし希望としては、M15までには、掃除作業を完了したいと思っています。

************************************
3)何がやり残されているか
************************************

webShellの掃除では、3つの主要な仕事がやり残されています。

第一は、url loading コードの掃除です。webShellを探検したことのある人
ならば、その中に url load を開始する、多くの異なった関数があり、それら
には千差万別のパラメーターを渡せることを、御存じでしょう。
これは、mscottがurl loadingに対して行った仕事と、embedding の敷居を
下げたことと、内部で一つのオブジェクトを使うようにしたことによって、
とても単純化されました。
url loading を掃除することは、新しいsession historyのコードを構築する
ことに繋がります。session history のロードと、frame navigation が、
単純化されるでしょう。
最後に、webShellが作成する native widget も取り除かなければなりません。
この作業は実は簡単なもので、私も一回やりました。しかし問題は、そこに
潜在していたバグを引っこ抜いて持ってきて、それが表に出てくることです。

embedding は、もう一つの構築しなければならないものです。
これは、webShellの主要な掃除作業に先攻して行うべきでしょう。
というのは、embedding は、viewer 取得や、先に述べたようないろいろな
抽象化や除去されるべきものたちの、移住先の候補となるからです。

これらの事柄が終われば、xulWindowは掃除を終えます。
そしてわれわれは、機構を拡張する新しいデザインへと進み、embedding が
必要とする全ての機能を提供できるようになるのです。
(context menus、focus issues、etc.)

************************************
4)どうやってembedできるか
************************************

しばしば、この質問をされます。簡単な答えは、われわれはまだそこまでいって
いない、というものです。もし、あなたが、いろいろなことが常時変わってしま
うのを気にしないなら、webshellがembeddされているのを真似て、それを
embedすることは可能でしょう。しかし、これを機能させる為には、あなたは、
古いAPIと新しいAPIを組み合わせて使用しなければなりません。
どれが生きていて、どれが死んでいるかの、ドキュメントは存在しないのです。
しかし、少し時間をかければ、 SeaMonkeyが内部的に、どの古いAPIを使い、
どの新しいAPIを使っているかを学ぶことができます。
また、section 5 を参照し、どのInterfaceを使うべきかを学べば、進むべき
方向が見えてくるでしょう。
しかし、基本的な答えとしては、もしあなたが、私がembedding object
(mozilla/embedding/browser)を組み立てるまで待てるなら(多分
1〜2週間)、あなたは、いろいろな変更から抽象化され、それを使って
embedding を開始でき、その先も少ない修正で済むでしょう。

****************************************
5)どのInterfaceを使うべきか
****************************************

さて、webShell とdocShell では、多くのInterfaceがサポートされています
が、その幾つかは新しいデザインの為で、その幾つかはそれがコールされている
全ての部分を、私が修正するチャンスがなかった為に存在します。
私は以下に、2セットのInterfaceをリストします。 *bad* と *good*
これはそれぞれ、"古い" と"新しい" に、言い換えることもできます。
もしあなたが、あなたのコード内で、古いInterfaceを使っているのを見つけた
ら、どのようにして新しいInterfaceにスイッチできるかを見つければ、
webShellをものにできます。内部的に保持していたnsIWebShellを、例えば、
nsIDocShellに変更することを、奨めます。現在は、あるコールをする為に、
nsIWebShellにQIしなければならない所がコードの随所にある為、これを
取り去ってしまうことはできません。しかし、nsIWebShellが使われて
いる所を知ることは、どこが変更されるべきかを知る手掛かりです。
でも今は、webShell方式を取り去るには、余りにも多くの場所で使用され
ています。

bad interfaces (最終的には消滅するでしょう)
-----------------------------
nsIWebShell
nsIWebShellContainer
nsIWebShellWindow
nsIWebShellServices
nsIBrowserWindow

good interfaces (docshell関連またはその親とのやり取り)
----------------------------------------------------------------------------
nsIDocShell
nsIDocShellTreeItem
nsIDocShellTreeNode
nsIDocShellTreeOwner
nsIBaseWindow
nsIWebNavigation
nsIScrollable
nsITextScroll
nsIInterfaceRequestor
nsIWebProgress
nsIWebProgressListener
nsIXULWindow (実際には、docShellからこれを得るべきではない)

good interfaces (embedding関連またはその親とのやり取り)
objects
----------------------------------------------------------------------------
nsIWebBrowser
nsIDocShellTreeItem
nsIBaseWindow
nsIWebNavigation
nsIScrollable
nsITextScroll
nsIInterfaceRequestor
nsIWebProgress
nsIWebProgressListener
nsIWebBrowserChrome

****************************************
6)典型的なコーディングの問題
****************************************

新世界では、物事をより簡単にする為や、あなたが話したがっているオブジェクトへの
パスがただ単に変わった為やで、変更が掛かるケースが数多くあります。
以下は、あなたが使いそうな幾つかの事柄の、以前はこうで、今はこうだ、という例
です。

この例の中では、nsCOMPtr<nsIDocShell> docShell; が既に存在し、これを扱う
ものとしています。

---- Getting to a domWindow from a docShell ----
nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docShell));

---- Getting an nsIPrompt ----
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterace(docShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);

nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));

nsCOMPtr<nsIPrompt> prompt(do_GetInterface(treeOwner));

---- Getting a PresShell or content Viewer----
nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell));

nsCOMPtr<nsIContentViewer> contentViewer;
docShell->GetContentViewer(getter_AddRefs(contentViewer));

---- Getting a document ----
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);

nsCOMPtr<nsIDOMDocument> domDoc;
webNav->GetDocument(getter_AddRefs(domDoc));

---- Loading a web Page from embedding ----
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);

nsAutoString myURL("http://www.mozilla.org");
webNav->LoadURI(myURL.GetUnicode()); (note this is from most loads, some
more detailed loads requiring different parameters may use more internal
nsIDocShell functions that deal with nsIURIs).

---- Any window management stuff ----
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(docShell));
NS_ENSURE_TRUE(docShellAsWin, NS_ERROR_FAILURE);

docShellAsWin->SetVisibility(PR_TRUE);
docShellAsWin->SetPositionAndSize(0, 0, 55, 99, PR_FALSE);
docShellAsWin->Destroy();
...
docShellAsWin->AnyOtherInterestingWindowManipulationFoundOnThisInterface()

---- Any interesting interaction with toplevel Window ----
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterace(docShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);

nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));

nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(treeOwner));
NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);

treeOwnerAsWin->SetPosition(8, 90); // Moves the outer window

(DON'T USE nsIWebShell::GetTopLevelWindow() or walk the nsIWebShellContainer
stack).

****************************************
7)まとめ
****************************************

この記事があなたがたのうちの幾人かの助けになれば幸いです。コードのある
部分を受け持って協力したい人は、悪いAPIから新しいのへの変更をしてくれ
ると、とても助かります。webShellは、そのうち消えるということを忘れず
に、webShellに入れ込みがある人は、気持ちを入れ替えて。
これらのコードに取り組む時は、embeddingが主要な目的であり、
embeddersがインプリメントするかもしれない、よりgenericなInterface
(nsIDocShellTreeOwner)を使用すべき時に、われわれの内部的Interface
(nsIXULWindow)を使用してembeddingを破綻させないよう、気をつけねば
なりません。
もし何か質問があれば、気軽に来て、私と話して下さい。

Travis




原文:The state of WebShell and the path to it's extinction