accessible/src/jsat/content-script.js

branch
TOR_BUG_9701
changeset 3
141e0f1194b1
equal deleted inserted replaced
-1:000000000000 0:40b50d2f7ea5
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 let Ci = Components.interfaces;
6 let Cu = Components.utils;
7
8 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
9 XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
10 'resource://gre/modules/accessibility/Utils.jsm');
11 XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
12 'resource://gre/modules/accessibility/Presentation.jsm');
13 XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules',
14 'resource://gre/modules/accessibility/TraversalRules.jsm');
15 XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
16 'resource://gre/modules/accessibility/Utils.jsm');
17 XPCOMUtils.defineLazyModuleGetter(this, 'EventManager',
18 'resource://gre/modules/accessibility/EventManager.jsm');
19 XPCOMUtils.defineLazyModuleGetter(this, 'ContentControl',
20 'resource://gre/modules/accessibility/ContentControl.jsm');
21 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
22 'resource://gre/modules/accessibility/Constants.jsm');
23
24 Logger.debug('content-script.js');
25
26 let eventManager = null;
27 let contentControl = null;
28
29 function forwardToParent(aMessage) {
30 // XXX: This is a silly way to make a deep copy
31 let newJSON = JSON.parse(JSON.stringify(aMessage.json));
32 newJSON.origin = 'child';
33 sendAsyncMessage(aMessage.name, newJSON);
34 }
35
36 function forwardToChild(aMessage, aListener, aVCPosition) {
37 let acc = aVCPosition || Utils.getVirtualCursor(content.document).position;
38
39 if (!Utils.isAliveAndVisible(acc) || acc.role != Roles.INTERNAL_FRAME) {
40 return false;
41 }
42
43 Logger.debug(() => {
44 return ['forwardToChild', Logger.accessibleToString(acc),
45 aMessage.name, JSON.stringify(aMessage.json, null, ' ')];
46 });
47
48 let mm = Utils.getMessageManager(acc.DOMNode);
49
50 if (aListener) {
51 mm.addMessageListener(aMessage.name, aListener);
52 }
53
54 // XXX: This is a silly way to make a deep copy
55 let newJSON = JSON.parse(JSON.stringify(aMessage.json));
56 newJSON.origin = 'parent';
57 if (Utils.isContentProcess) {
58 // XXX: OOP content's screen offset is 0,
59 // so we remove the real screen offset here.
60 newJSON.x -= content.mozInnerScreenX;
61 newJSON.y -= content.mozInnerScreenY;
62 }
63 mm.sendAsyncMessage(aMessage.name, newJSON);
64 return true;
65 }
66
67 function activateContextMenu(aMessage) {
68 function sendContextMenuCoordinates(aAccessible) {
69 let bounds = Utils.getBounds(aAccessible);
70 sendAsyncMessage('AccessFu:ActivateContextMenu', {bounds: bounds});
71 }
72
73 let position = Utils.getVirtualCursor(content.document).position;
74 if (!forwardToChild(aMessage, activateContextMenu, position)) {
75 sendContextMenuCoordinates(position);
76 }
77 }
78
79 function presentCaretChange(aText, aOldOffset, aNewOffset) {
80 if (aOldOffset !== aNewOffset) {
81 let msg = Presentation.textSelectionChanged(aText, aNewOffset, aNewOffset,
82 aOldOffset, aOldOffset, true);
83 sendAsyncMessage('AccessFu:Present', msg);
84 }
85 }
86
87 function scroll(aMessage) {
88 function sendScrollCoordinates(aAccessible) {
89 let bounds = Utils.getBounds(aAccessible);
90 sendAsyncMessage('AccessFu:DoScroll',
91 { bounds: bounds,
92 page: aMessage.json.page,
93 horizontal: aMessage.json.horizontal });
94 }
95
96 let position = Utils.getVirtualCursor(content.document).position;
97 if (!forwardToChild(aMessage, scroll, position)) {
98 sendScrollCoordinates(position);
99 }
100 }
101
102 function adjustRange(aMessage) {
103 function sendUpDownKey(aAccessible) {
104 let acc = Utils.getEmbeddedControl(aAccessible) || aAccessible;
105 let elem = acc.DOMNode;
106 if (elem) {
107 if (elem.tagName === 'INPUT' && elem.type === 'range') {
108 elem[aMessage.json.direction === 'forward' ? 'stepDown' : 'stepUp']();
109 let changeEvent = content.document.createEvent('UIEvent');
110 changeEvent.initEvent('change', true, true);
111 elem.dispatchEvent(changeEvent);
112 } else {
113 let evt = content.document.createEvent('KeyboardEvent');
114 let keycode = aMessage.json.direction == 'forward' ?
115 content.KeyEvent.DOM_VK_DOWN : content.KeyEvent.DOM_VK_UP;
116 evt.initKeyEvent(
117 "keypress", false, true, null, false, false, false, false, keycode, 0);
118 elem.dispatchEvent(evt);
119 }
120 }
121 }
122
123 let position = Utils.getVirtualCursor(content.document).position;
124 if (!forwardToChild(aMessage, adjustRange, position)) {
125 sendUpDownKey(position);
126 }
127 }
128 addMessageListener(
129 'AccessFu:Start',
130 function(m) {
131 if (m.json.logLevel) {
132 Logger.logLevel = Logger[m.json.logLevel];
133 }
134
135 Logger.debug('AccessFu:Start');
136 if (m.json.buildApp)
137 Utils.MozBuildApp = m.json.buildApp;
138
139 addMessageListener('AccessFu:ContextMenu', activateContextMenu);
140 addMessageListener('AccessFu:Scroll', scroll);
141 addMessageListener('AccessFu:AdjustRange', adjustRange);
142
143 if (!eventManager) {
144 eventManager = new EventManager(this);
145 }
146 eventManager.start();
147
148 if (!contentControl) {
149 contentControl = new ContentControl(this);
150 }
151 contentControl.start();
152
153 sendAsyncMessage('AccessFu:ContentStarted');
154 });
155
156 addMessageListener(
157 'AccessFu:Stop',
158 function(m) {
159 Logger.debug('AccessFu:Stop');
160
161 removeMessageListener('AccessFu:ContextMenu', activateContextMenu);
162 removeMessageListener('AccessFu:Scroll', scroll);
163
164 eventManager.stop();
165 contentControl.stop();
166 });
167
168 sendAsyncMessage('AccessFu:Ready');

mercurial