大規模ソフトウェア(Chromium)を手探る - 設定画面(settings)を手探る2 -

大規模ソフトウェア(Chromium)を手探る - 設定画面(settings)を手探る1 - の続きです。

elecho.hatenablog.com

実験で取り組んだことの概要については、 大規模ソフトウェア(Chromium)を手探る 導入・ビルド編 - あさりさんの作業日記 をご参照ください。

課題3: 設定画面をちゃんと入力画面にしよう

課題2で、設定画面に項目を追加することができました。

ただ、そこでは単純に文字を表示できただけなので、ちゃんと入力欄を作ろうと思います。

入力欄を追加するだけなら<input></input>タグをつけても良いんですが、せっかくならchromiumで使われているものに合わせたいなと思いました。そこでそれっぽいパーツがないか設定画面のなかで探してみると、スタートアップページの追加欄

f:id:elecho:20171030015615p:plain

とか良さそう!

となったので、この画面を作っていた

src/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html

内の

<paper-input ...></paper-input>

というパーツを拝借することにしました。

そして、restrict_keyword.html, restrick_keyword.jsを以下のように書き加えます。
(注:startup_url_dialog.htmlからかなりパクってきているので、おそらく不要な変数や関数が残っています。)

src/chrome/browser/resources/settings/restrict_keyword/restrict_keyword.html

src/chrome/browser/resources/settings/restrict_keyword/restrict_keyword.js

そうすると、

f:id:elecho:20171030021730p:plain

というような入力欄が無事表示されました!

課題4: キーワードをC++で書かれたChromium処理部本体に渡す

入力画面ができたところで、このデータをC++側に渡す必要があります。

この処理部も、src/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.jsを参照して追加文字列を渡す関数呼び出しを追っていくと、

src/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js (L.59〜L.60)

    this.browserProxy_.editStartupPage(this.model.modelIndex, this.url_) :
    this.browserProxy_.addStartupPage(this.url_);

src/chrome/browser/resources/settings/on_startup_page/startup_urls_page_browser_proxy.js (L.65〜L.73)

    /** @override */
    addStartupPage(url) {
      return cr.sendWithPromise('addStartupPage', url);
    }

    /** @override */
    editStartupPage(modelIndex, url) {
      return cr.sendWithPromise('editStartupPage', modelIndex, url);
    }

となっていて、どうやらcr.jsの中で定義されているsendWithPromiseメソッドでC++とデータをやり取りしているようです。

そして、C++側の実装を見てみると、cr.sendWithPromiseの第一引数をキーとしてC++側の各種handlerを呼び出していました。
つまり、cr.sendWithPromiseを追加し、C++側に適切な改修を加えれば制限キーワードを渡せるようになりそうです。(実装は大規模ソフトウェア(Chromium)を手探る callbackハンドラを追加する・全体の感想 - あさりさんの作業日記をご覧ください。)

JavascriptC++側でのデータのやり取りをまとめた概念図は以下のようになります。

f:id:elecho:20171031002224p:plain

また、sendWithPromiseというメソッド名から、Promiseという仕組みを使っていそうだということが分かります。

Promiseというのは、Wikipediaさんによると

future, promise, delay とは、プログラミング言語における並列処理のデザインパターン。何らかの処理を別のスレッドで処理させる際、その処理結果の取得を必要になるところまで後回しにする手法。処理をパイプライン化させる。1977年に考案され、現在ではほとんどのプログラミング言語で利用可能。 future - Wikipedia

なものらしいのですが、そこら辺はとりあえず置いといて

cr.sendWithPromise(hogehoge).then(fugafuga)

とやると、hogehogeのhandlerをC++側で回してもらい、結果をfugafugaで処理するという流れになります。

ということで、restrict_keyword.html, restrick_keyword.jsをキーワードのやり取りに対応するように修正して、

src/chrome/browser/resources/settings/restrict_keyword/restrict_keyword.html

src/chrome/browser/resources/settings/restrict_keyword/restrict_keyword.js

これで、HTML, JavaScript側の変更は終わりです。

次の記事ははこちら→大規模ソフトウェア(Chromium)を手探る callbackハンドラを追加する・全体の感想 - あさりさんの作業日記