Submit Search
Upload
GeckoのDOMイベント処理の実装 (Gecko Inside ver.)
•
Download as PPTX, PDF
•
5 likes
•
2,003 views
Masayuki Nakano
Follow
GeckoのDOMイベントの実装方法、処理の流れについてのドキュメントです。対象はGeckoの開発に興味のある方なので、ソースコードをある程度知らないと内容は理解出来ません。
Read less
Read more
Technology
Report
Share
Report
Share
1 of 64
Download now
Recommended
GeckoのDOMイベント処理の実装
GeckoのDOMイベント処理の実装
Masayuki Nakano
DOMイベントの基礎から深淵まで
DOMイベントの基礎から深淵まで
Masayuki Nakano
0621 ndk game
0621 ndk game
cat kaotaro
[cb22] Hayabusa Threat Hunting and Fast Forensics in Windows environments fo...
[cb22] Hayabusa Threat Hunting and Fast Forensics in Windows environments fo...
CODE BLUE
ここが変わったTizen sdk2.0alpha
ここが変わったTizen sdk2.0alpha
Hiroshi Sakate
Cocos2d-x公開講座 in 鹿児島
Cocos2d-x公開講座 in 鹿児島
Tomoaki Shimizu
Windows クライアントのトラブルシューティングあれこれ
Windows クライアントのトラブルシューティングあれこれ
彰 村地
Client Side Cache
Client Side Cache
Toru Yamaguchi
Recommended
GeckoのDOMイベント処理の実装
GeckoのDOMイベント処理の実装
Masayuki Nakano
DOMイベントの基礎から深淵まで
DOMイベントの基礎から深淵まで
Masayuki Nakano
0621 ndk game
0621 ndk game
cat kaotaro
[cb22] Hayabusa Threat Hunting and Fast Forensics in Windows environments fo...
[cb22] Hayabusa Threat Hunting and Fast Forensics in Windows environments fo...
CODE BLUE
ここが変わったTizen sdk2.0alpha
ここが変わったTizen sdk2.0alpha
Hiroshi Sakate
Cocos2d-x公開講座 in 鹿児島
Cocos2d-x公開講座 in 鹿児島
Tomoaki Shimizu
Windows クライアントのトラブルシューティングあれこれ
Windows クライアントのトラブルシューティングあれこれ
彰 村地
Client Side Cache
Client Side Cache
Toru Yamaguchi
S2s websrv201011-presen
S2s websrv201011-presen
Kouhei Maeda
Vagrant on SoftLayer
Vagrant on SoftLayer
Yuichi Tamagawa
スマートフォンブラウザ不具合特集
スマートフォンブラウザ不具合特集
Hiroaki Wakamatsu
Web Component概要
Web Component概要
Shumpei Shiraishi
Java scriptでslideを作ってみた
Java scriptでslideを作ってみた
Katsuhito Yonao
パワーユーザー必携の海外の拡張機能20選+α
パワーユーザー必携の海外の拡張機能20選+α
Akira Maruyama
わんくまT78 mfcを始めようとしてみた
わんくまT78 mfcを始めようとしてみた
伸男 伊藤
Dev camp2012jpn day2session2
Dev camp2012jpn day2session2
Daiyu Hatakeyama
Dev camp2012jpn day2session2
Dev camp2012jpn day2session2
Developer Camp 2012 Japan Fall
Linux も動く Microsoft Azure HoloLens にも対応した次世代マルチプレイミドルウェア
Linux も動く Microsoft Azure HoloLens にも対応した次世代マルチプレイミドルウェア
Hiroko Umetsu
20060419
20060419
小野 修司
ゲームの裏側を支える人たちの裏側
ゲームの裏側を支える人たちの裏側
Riou Tomita
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Yoshito Tabuchi
Chrome DevTools.next
Chrome DevTools.next
yoshikawa_t
Angular の紹介
Angular の紹介
Neo Xrea
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
torutk
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates
koichik
Chrome Developer Toolsを使いこなそう!
Chrome Developer Toolsを使いこなそう!
yoshikawa_t
Firefoxの開発プロセス
Firefoxの開発プロセス
Makoto Kato
はこだてIKA夜間勉強会 バージョン管理#01 -Subversion編-
はこだてIKA夜間勉強会 バージョン管理#01 -Subversion編-
Seiji KOMATSU
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
WSO2
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
iPride Co., Ltd.
More Related Content
Similar to GeckoのDOMイベント処理の実装 (Gecko Inside ver.)
S2s websrv201011-presen
S2s websrv201011-presen
Kouhei Maeda
Vagrant on SoftLayer
Vagrant on SoftLayer
Yuichi Tamagawa
スマートフォンブラウザ不具合特集
スマートフォンブラウザ不具合特集
Hiroaki Wakamatsu
Web Component概要
Web Component概要
Shumpei Shiraishi
Java scriptでslideを作ってみた
Java scriptでslideを作ってみた
Katsuhito Yonao
パワーユーザー必携の海外の拡張機能20選+α
パワーユーザー必携の海外の拡張機能20選+α
Akira Maruyama
わんくまT78 mfcを始めようとしてみた
わんくまT78 mfcを始めようとしてみた
伸男 伊藤
Dev camp2012jpn day2session2
Dev camp2012jpn day2session2
Daiyu Hatakeyama
Dev camp2012jpn day2session2
Dev camp2012jpn day2session2
Developer Camp 2012 Japan Fall
Linux も動く Microsoft Azure HoloLens にも対応した次世代マルチプレイミドルウェア
Linux も動く Microsoft Azure HoloLens にも対応した次世代マルチプレイミドルウェア
Hiroko Umetsu
20060419
20060419
小野 修司
ゲームの裏側を支える人たちの裏側
ゲームの裏側を支える人たちの裏側
Riou Tomita
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Yoshito Tabuchi
Chrome DevTools.next
Chrome DevTools.next
yoshikawa_t
Angular の紹介
Angular の紹介
Neo Xrea
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
torutk
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates
koichik
Chrome Developer Toolsを使いこなそう!
Chrome Developer Toolsを使いこなそう!
yoshikawa_t
Firefoxの開発プロセス
Firefoxの開発プロセス
Makoto Kato
はこだてIKA夜間勉強会 バージョン管理#01 -Subversion編-
はこだてIKA夜間勉強会 バージョン管理#01 -Subversion編-
Seiji KOMATSU
Similar to GeckoのDOMイベント処理の実装 (Gecko Inside ver.)
(20)
S2s websrv201011-presen
S2s websrv201011-presen
Vagrant on SoftLayer
Vagrant on SoftLayer
スマートフォンブラウザ不具合特集
スマートフォンブラウザ不具合特集
Web Component概要
Web Component概要
Java scriptでslideを作ってみた
Java scriptでslideを作ってみた
パワーユーザー必携の海外の拡張機能20選+α
パワーユーザー必携の海外の拡張機能20選+α
わんくまT78 mfcを始めようとしてみた
わんくまT78 mfcを始めようとしてみた
Dev camp2012jpn day2session2
Dev camp2012jpn day2session2
Dev camp2012jpn day2session2
Dev camp2012jpn day2session2
Linux も動く Microsoft Azure HoloLens にも対応した次世代マルチプレイミドルウェア
Linux も動く Microsoft Azure HoloLens にも対応した次世代マルチプレイミドルウェア
20060419
20060419
ゲームの裏側を支える人たちの裏側
ゲームの裏側を支える人たちの裏側
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Chrome DevTools.next
Chrome DevTools.next
Angular の紹介
Angular の紹介
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
東京Node学園#3 Domains & Isolates
東京Node学園#3 Domains & Isolates
Chrome Developer Toolsを使いこなそう!
Chrome Developer Toolsを使いこなそう!
Firefoxの開発プロセス
Firefoxの開発プロセス
はこだてIKA夜間勉強会 バージョン管理#01 -Subversion編-
はこだてIKA夜間勉強会 バージョン管理#01 -Subversion編-
Recently uploaded
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
WSO2
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
iPride Co., Ltd.
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
sn679259
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
iPride Co., Ltd.
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
Toru Tamaki
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
CRI Japan, Inc.
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
atsushi061452
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
iPride Co., Ltd.
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
Toru Tamaki
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
CRI Japan, Inc.
Recently uploaded
(10)
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
GeckoのDOMイベント処理の実装 (Gecko Inside ver.)
1.
2.
中野雅之 • 肩書き • 正式:
Mozilla Japan 国際化担当マネージャ • 非公式: Mozilla Japan 大阪支部長 • 大阪の自宅で、自宅警備しながら仕事してます
3.
中野雅之 • 色んなアカウント • メールアドレス:
masayuki@d-toybox.com • Skype: masayuki-nakano • Twitter: @d_toybox • Blog: 「もずはっく日記」で検索
4.
アジェンダ • 簡単な用語解説 • DOMイベントの基礎知識 •
Geckoのイベント処理の実装 • イベントとe10s
5.
簡単な用語解説 • D3E • DOM
Level 3 Events の略 • DOM Level 4 Events にあたる仕様案の名前だった、”UI Events” に改名され、マージされた • DOM Level 3 KeyboardEvent key Values • KeyboardEvent.keyの値を定義した仕様 • 元々は D3E で定義されていたものの分割された • DOM Level 3 KeyboardEvent code Values • KeyboardEvent.codeの値を定義した仕様 • 元々は UI Events で定義されていたものが分割された
6.
簡単な用語解説 • Edit Events •
UI Events からinputイベントとbeforeinputイベントを分離した 仕様 • しかし、迷走中 • inputイベントとbeforeinputイベントはそれぞれ、editと beforeeditイベントに改名され、従来のinputイベントとの後 方互換性も無い
7.
簡単な用語解説 • PresShell • “Presentation
Shell”の略 • DOM document (window?)ひとつに対して、一つ生成される • nsPresShell.cpp で PresShellとして実装され、nsIPresShell 抽象クラスでインターフェースが定義されている • ESM • イベントの前処理や後処理、イベントによって変化するコンテ ンツの状態管理(:hover状態等)を管理している、 EventStateManagerの略 • PresShellに生成され、破棄される
8.
簡単な用語解説 • PresContext • “Presentation
Context”の略 • PresShellに生成され、破棄される • RefCountable ではないので、クラスのメンバとして保存する 時は nsCOMPtr<nsIPresShell>を保存しておき、 GetPresContext()で取得する方が安全
9.
簡単な用語解説 • dispatch、fire • 共にイベントを発火する意味で違いは無い •
default action • イベントが発生した際にブラウザが行う動作、例えば、 wheelイベントに対する、スクロールやズーム処理が wheelイベントのdefault action • consumed • Event.preventDefault()が呼び出され、default action がキャンセルされている状態
10.
DOM イベントの基礎 • フェイズと、プロパゲーション •
イベントを捕まえる • イベントの伝播を抑制する • ブラウザのイベント処理を妨害する • Gecko独自のイベントグループ
11.
capturing フェイズ 1. 最初はwindow 2.
次にdocument 3. rootからtargetの親 • targetの決定は、イベント 依存 • フォーカス • 発生位置 • ……等々
12.
target フェイズ • targetフェイズは、 capturingフェイズの一部 でもあり、bubblingフェイズ の一部でもある。 •
windowやdocumentが targetの場合も
13.
bubbling フェイズ 1. target
の親からroot 2. 次にdocument 3. 最後にwindow • Event.bubblesが falseの場 合、bubblingは発生しない
14.
イベントを捕まえる • 書式: • EventTarget.addEventListener( イベント名,
ハンドラ, Capture?); • EventTarget.removeEventListener( イベント名, ハンドラ, Capture?); • イベント名: イベントの名前 "click" とか、 "keydown" • ハンドラ: function foo(aEvent) { /* something */ }がお手軽で十分 • Capture?: trueなら、capturing フェイズと、target フェイズ、falseなら、target フェイ ズと、bubbling フェイズ
15.
イベントを捕まえる • 単純な例1: • 全ての要素で発生するkeydownイベントを知りたい •
イベントターゲットより先に知りたい • removeする必要はない document.addEventListener( "keydown", function (aEvent) { /* something */ }, true);
16.
イベントを捕まえる • 単純な例2: • 全ての要素で発生するkeydownイベントを知りたい •
イベントターゲットより後に知りたい • removeする必要がある function keydownHandler(aEvent) { /* something */ } document.addEventListener( "keydown", keydownHandler, false); … document.removeEventListener( "keydown", keydownHandler, false);
17.
イベントの伝播を抑制する • 複数のイベントリスナを登録している場合、あるイベントハンドラ で処理済みのイベントを他のイベントハンドラでは無視したい場 合が考えられる • Event.stopPropagation()か、Event.stopImmediatePropagation() を呼ぶと、それ以降のイベント発生を中止できる •
Event.stopPropagation()では、次のEventTarget以降でのイベ ントハンドラの実行を中止できる • Event.stopImmediatePropagation()では、同じEventTargetに登 録されている未処理のイベントハンドラも含めて、イベントハン ドラの実行を中止できる
18.
ブラウザのイベント処理を妨害する • ブラウザにdefault actionを実行してもらいたくない場合が考え られる •
Event.preventDefault()を呼び出すと、Event.defaultPrevented 属性値がtrueになる • defaultPrevented属性がtrueなら、ブラウザはdefault action を実行しない(ただし、タブの切替等、セキュリティ上、無視す ることはある) • Webアプリは Event.defaultPreventedの値を、処理前に確認 することで、Event.stopPropagation()の代用としても使える
19.
Gecko独自のイベントグループ • GeckoはDOMイベントを捕まえることでデフォルトアクションを 実装することがある • WebコンテンツがEvent.stopPropagation()を呼び出したもの の、Event.peventDefault()を呼び出していない場合にdefault actionを実行する必要がある •
Webコンテンツと同じ様にイベントリスナを登録していると、 Event.stopPropagation()の呼び出しだけでdefault actionの実 行が抑制されてしまう • 実はこのバグは多く、私自身も発見しては修正している
20.
Gecko独自のイベントグループ • GeckoはWebコンテンツの登録するイベントリスナをdefault event groupに登録する •
Gecko内部や、UIはイベントリスナをSystem Event Groupに 登録する(べき) • 最初にdefault event groupに登録されたリスナが実行され、そ の後、system event groupに登録されたリスナが実行される、 つまり……
21.
Gecko独自のイベントグループ 1. default event
groupのcapturing phase 2. default event groupのtarget 3. default event groupのbubbling phase 4. system event groupのcapturing phase 5. system event groupのtarget 6. system event groupのbubbling phase という順序で実行される
22.
Gecko独自のイベントグループ • Event.stopPropagation()やEvent.stopImmediatePropagation() は各event group内での伝播を止めるのみ •
default event groupで呼び出していても、system event groupでの実行は保証されている • system event group内で呼び出した場合にはdefault event groupと同様にそれ以降のイベントリスナは呼び出されない のでsystem event groupに登録しているイベントリスナ全て が実行を保証されている訳ではない
23.
Geckoのイベント処理の実装 • OSネイティブなイベントをDOMイベントとしてWebアプ リに通知するケースを解説 • 図にすると、次のように……
24.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
25.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
26.
EventListenerManager • イベントターゲットで、最初にイベントリスナが登録された時に、 インスタンスが生成され、そのノードに保存される • そのノードに登録された全てのイベントリスナを管理する •
HandleEvent()が呼び出されると、イベントの名前とフェーズ、 イベントリスナのグループがマッチするものを探し、マッチした 場合に登録されているハンドラを実行する • stopImmediatePropagation()が呼び出されたら、中断する
27.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
28.
モジュール間の処理の流れの例 1. widget/ は、各
OS のネイティブイベントをハンドリングする モジュール。ネイティブイベントが発生したら、内部イベント である、Widget*Eventクラスのインスタンスをスタックに作 成し、その値を設定する 2. PresShellにイベントを送信、PresShellが target を決定す る
29.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
30.
モジュール間の処理の流れの例 3. EventStateManager::PreHandleEvent()が前処理を行う • 後ほど詳しく……
31.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
32.
モジュール間の処理の流れの例 4. PresShellがEventDispatcher::Dispatch()を呼び出す 5. EventDispatcher::CreateEvent()でWidget*Eventのクラスに 対応した、dom::*Eventクラスを選択し、そのインスタンスを ヒープに作成する 6.
EventListenerManagerを列挙した配列を用意し、 EventTargetChainItem::HandleEventTargetChain()を呼び 出す
33.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
34.
モジュール間の処理の流れ 7. EventTargetChainItem::HandleEventTargetChain()で、受け 取った、各EventListenerManagerのHandleEvent()を実行し ていく 8. EventListenerManager::HandleEvent()は、そのノードに登 録されたイベントリスナを順に実行していく 9.
EventTargetChainItem::HandleEventTargetChain()が自身 をもう一度呼び出し、デフォルトアクションの実行のため、 System Event Groupに登録されたリスナを実行する。
35.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
36.
モジュール間の処理の流れ 10. EventStateManager::PostHandleEvent()で、デフォルトアク ションを実行したり、関連するイベントを生成したりする
37.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
38.
Widget*Event、Internal*Event • WidgetEventクラスが全てのイベントクラスの基底クラス • WidgetMouseEventや、InternalFocusEventといった派生クラ スが、イベントごとに定義・実装されている •
各クラスは、ほぼ構造体であり、メンバのカプセル化はほとん ど行われず、メンバにダイレクトにアクセスする (読み書き問 わず) • widgetから生成されるイベントは、Widget*Event、それ以外 の場合は、DOMイベントのデータを保存するためだけのもの は、Internal*Event と命名されている
39.
Widget*Event、Internal*Event • widget/ • widget/BasicEvents.h •
widget/ContentEvents.h • widget/MiscEvents.h • widget/MouseEvents.h • widget/TextEvents.h • widget/TouchEvents.h • dom/events/ • dom/events/InternalMutationEvent.h
40.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
41.
PresShell • イベントの複雑な処理はEventStateManager、表示に関わる 部分はnsPresContextに分離されている • イベント処理では
widget で生成されたイベントを受け取り、 target の決定と、発火処理を行う • PresShell::HandleEvent()や、関連メソッドを参照
42.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
43.
EventStateManager::PreHandleEvent() • PresShellがイベントを発火する直前に呼び出す • マウスの操作によって変化する:hoverや、:activeといった要素 の状態設定を行う •
マウスのクリックカウント等、状態の保存や、その値の Widget*Eventのメンバへの書き出しを行う • ホイールの速度等、設定でカスタマイズできる項目を、 Widget*Eventのメンバの値を書き換えることで実現してる
44.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
45.
EventDispatcher::CreateEvent() • Widget*Eventクラスのインスタンスや、Internal*Eventクラス のインスタンスから、DOMイベントの実装クラスを選択し、イ ンスタンスを生成する • Javascriptのdocument.createEvent()の実装でもある •
new MouseEvent(…)等は別 • EventListenerManager::HandleEventInternal()が最初のイベン トリスナを見つけた時点で呼び出される
46.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
47.
dom::Event • DOMイベントの実装クラスは、名前空間 “mozilla::dom“に、 標準仕様と同じ名前で定義 •
dom::KeyboardEvent、dom::WheelEvent等 • nsIDOMEventインターフェースを必ず継承している • dom::Eventは、WidgetEventへのポインタを持ち、イベントの属 性値はここに保存している • DOMイベントクラスは、Widget*Eventや Internal*Eventへ、 DOMからアクセスするためのラッパクラス
48.
dom::Event • 古くから実装されているDOMイベントクラスは、固有の、 nsIDOM*Eventインターフェースも継承している • 新規作成時にはほとんど定義されない •
データにアクセスするだけなら、内部イベントクラスにアクセ スする方が高速で、実装も単純化される • nsIDOM*Eventのメソッドは全て、virtual callになるためパ フォーマンスが悪い
49.
dom::Event • 内部イベントクラスを定義・実装する必要が無い、シン プルなイベントを実装する際は、webidlで定義したイ ベントから、実装コードを自動生成することも可能 • 自動生成の定義は
dom/webidl/moz.build で定義 • dom/bindings/Codegen.py によって、ビルド時に cppファイルが自動的に生成される
50.
dom::Event • 実装例 • dom/events/ •
dom/events/Event.cpp • dom/events/UIEvent.cpp • dom/events/WheelEvent.cpp • dom/svg/ • dom/svg/SVGZoomEvent.cpp
51.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
52.
EventDispatcher::Dispatch() • PresShellから呼び出される • 最初に、
targetのPreHandleEvent()を実行する • windowからtargetノードまで辿り、作成されている全ての EventListenerManagerを列挙し、配列に格納 • EventTargetChainItem::HandleEventTargetChain()にその配 列を渡す • その後、 targetのPostHandleEvent()を実行する • 発火が終了しても、DOM イベントが JS の変数等から参照 されている場合、内部イベントをヒープにコピーする • 発火処理後、スタックにある内部イベントは破棄されるた め
53.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
54.
EventTargetChainItem::HandleEventTargetChain() • EventDispatcher::Dispatch()に呼び出される • 列挙されている、windowからtargetの親ノードまでの EventListenerManagerの、HandleEvent()を実行していく (capturingフェーズ) •
Event.stopPropagation()がHandleEvent()実行中に呼び出さ れていたら、ループを中断する
55.
EventTargetChainItem::HandleEventTargetChain() • 次に、targetのEventListenerManagerのHandleEvent()を呼び 出す (targetフェーズ) •
Event.stopPropagation()か、 Event.stopImmediatePropagation()が既に呼び出されていた 場合、実行しない • Event.stopPropagation()がHandleEvent()実行中に呼び出さ れていたら、ループを中断する
56.
EventTargetChainItem::HandleEventTargetChain() • 次に、列挙された、targetの親から、windowまでの EventListenerManagerの、HandleEvent() を実行していく (bubbling
フェーズ) • Event.bubblesがfalseなら実行しない • Event.stopPropagation()か、 Event.stopImmediatePropagation()が既に呼び出されていた 場合、実行しない • Event.stopPropagation()がHandleEvent()実行中に呼び出さ れていたら、ループを中断する
57.
EventTargetChainItem::HandleEventTargetChain() • 次に、イベントターゲットが生成した、CSS boxを実装している、 nsIFrame::HandleEvent()を呼び出す •
PresShellがEventDispatcher::Dispatch()に渡したcallbackク ラス経由で呼び出し • default actionの実装に利用可能
58.
EventTargetChainItem::HandleEventTargetChain() • 最後に、System Event
Groupのイベントリスナが登録されて いる場合、capturing、target、bubblingフェーズを再度、処理 する • 通常のWebコンテンツからは登録不可 • Web コンテンツにEvent.stopPropagation()等を呼び出されて いても実行される • default actionの実装に利用可能 • System Event Group 内のリスナで、stopPropagation()等を 呼ぶと中断される
59.
Geckoのイベント処理の実装 nsDocument PresShell widget EventDispatcher EventStateManager Widget*Event dom::*Event PreHandleEvent() PostHandleEvent() Dispatch() CreateEvent() 2 3 4 5 6 EventTargetChainItem nsINode EventListenerManager HandleEvent()
handler2 handler1 nsINode EventListenerManager HandleEvent() handler2 handler1 7 8 10 1 9
60.
EventStateManager::PostHandleEvent() • PresShellが最後に呼び出す • イベントの後処理や、default
actionを実行 • マウスホイールによるスクロール処理やズーム処理 • mouseupからclickイベントや、dblclickイベントの生成 • mousemoveから、 mouseover、mouseout、mouseenter、 mouseleaveイベントの生成
61.
イベントとe10s PresShell widget EventStateManager PostHandleEvent() 1 2 5 6 TabParent 3 4 PuppetWidget 7 PresShell 9 EventStateManager EventDispatcher etc. 11 12 TabChild 8 10 13
62.
イベントとe10s • e10sではネイティブのイベント入力は全てchromeプロセスで 処理し、Widget*Eventをwidget/からdispatchする • フォーカスを持った要素が子プロセス内にある場合、 EventStateManager::PostHandleEvent()がイベントを TabParent経由で子プロセスへ送信する •
一部例外のイベントもあり(WidgetCompositionEvent等) • 子要素ではTabChildがイベントを受け取ると、PuppetWidget へ送信し、PuppetWidgetから子プロセス内のPresShellにイベ ントを送信し同様に処理される • つまり……
63.
イベントとe10s • 子プロセスに送信されるイベントは、親プロセスのdefault actionの一部 • 子プロセスには非同期で送信されているため、親プロセスは そのイベントがconsumedとなったかどうかを知ることができ ない •
OS側に非同期でイベントの処理結果を返す方法が無い限り、 嘘の結果しか返せない • 各OSがモダンな結果になることを期待したい • IMEのみ、即座にコンテンツの情報を返したりする必要があ るため、ContentCacheという仕組みを用意している
64.
Text Q&A?
Download now