2012-10-01 13:33:26 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2013-05-21 11:16:49 -07:00
|
|
|
let Ci = Components.interfaces;
|
|
|
|
let Cu = Components.utils;
|
|
|
|
|
|
|
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
|
|
|
|
'resource://gre/modules/accessibility/Utils.jsm');
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
|
|
|
|
'resource://gre/modules/accessibility/Presentation.jsm');
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules',
|
|
|
|
'resource://gre/modules/accessibility/TraversalRules.jsm');
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
|
|
|
|
'resource://gre/modules/accessibility/Utils.jsm');
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'EventManager',
|
|
|
|
'resource://gre/modules/accessibility/EventManager.jsm');
|
2014-03-04 17:49:27 -08:00
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'ContentControl',
|
|
|
|
'resource://gre/modules/accessibility/ContentControl.jsm');
|
2013-11-19 10:17:43 -08:00
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
|
|
|
|
'resource://gre/modules/accessibility/Constants.jsm');
|
2012-10-01 13:33:26 -07:00
|
|
|
|
|
|
|
Logger.debug('content-script.js');
|
|
|
|
|
2013-05-21 11:16:49 -07:00
|
|
|
let eventManager = null;
|
2014-03-04 17:49:27 -08:00
|
|
|
let contentControl = null;
|
2013-07-16 11:45:17 -07:00
|
|
|
|
|
|
|
function forwardToParent(aMessage) {
|
|
|
|
// XXX: This is a silly way to make a deep copy
|
|
|
|
let newJSON = JSON.parse(JSON.stringify(aMessage.json));
|
|
|
|
newJSON.origin = 'child';
|
|
|
|
sendAsyncMessage(aMessage.name, newJSON);
|
|
|
|
}
|
|
|
|
|
|
|
|
function forwardToChild(aMessage, aListener, aVCPosition) {
|
|
|
|
let acc = aVCPosition || Utils.getVirtualCursor(content.document).position;
|
|
|
|
|
2013-11-19 10:17:43 -08:00
|
|
|
if (!Utils.isAliveAndVisible(acc) || acc.role != Roles.INTERNAL_FRAME) {
|
2013-07-16 11:45:17 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-27 07:42:45 -08:00
|
|
|
Logger.debug(() => {
|
|
|
|
return ['forwardToChild', Logger.accessibleToString(acc),
|
|
|
|
aMessage.name, JSON.stringify(aMessage.json, null, ' ')];
|
|
|
|
});
|
2013-07-16 11:45:17 -07:00
|
|
|
|
|
|
|
let mm = Utils.getMessageManager(acc.DOMNode);
|
2014-02-11 10:41:02 -08:00
|
|
|
|
|
|
|
if (aListener) {
|
|
|
|
mm.addMessageListener(aMessage.name, aListener);
|
|
|
|
}
|
|
|
|
|
2013-07-16 11:45:17 -07:00
|
|
|
// XXX: This is a silly way to make a deep copy
|
|
|
|
let newJSON = JSON.parse(JSON.stringify(aMessage.json));
|
|
|
|
newJSON.origin = 'parent';
|
|
|
|
if (Utils.isContentProcess) {
|
|
|
|
// XXX: OOP content's screen offset is 0,
|
|
|
|
// so we remove the real screen offset here.
|
|
|
|
newJSON.x -= content.mozInnerScreenX;
|
|
|
|
newJSON.y -= content.mozInnerScreenY;
|
|
|
|
}
|
|
|
|
mm.sendAsyncMessage(aMessage.name, newJSON);
|
|
|
|
return true;
|
2012-10-01 13:33:26 -07:00
|
|
|
}
|
|
|
|
|
2013-06-03 11:29:14 -07:00
|
|
|
function activateContextMenu(aMessage) {
|
|
|
|
function sendContextMenuCoordinates(aAccessible) {
|
2013-07-16 04:49:00 -07:00
|
|
|
let bounds = Utils.getBounds(aAccessible);
|
2013-07-17 13:41:29 -07:00
|
|
|
sendAsyncMessage('AccessFu:ActivateContextMenu', {bounds: bounds});
|
2013-06-03 11:29:14 -07:00
|
|
|
}
|
|
|
|
|
2013-07-16 04:49:00 -07:00
|
|
|
let position = Utils.getVirtualCursor(content.document).position;
|
|
|
|
if (!forwardToChild(aMessage, activateContextMenu, position)) {
|
|
|
|
sendContextMenuCoordinates(position);
|
2013-07-16 11:45:17 -07:00
|
|
|
}
|
2013-06-03 11:29:14 -07:00
|
|
|
}
|
|
|
|
|
2013-07-03 15:20:11 -07:00
|
|
|
function presentCaretChange(aText, aOldOffset, aNewOffset) {
|
|
|
|
if (aOldOffset !== aNewOffset) {
|
|
|
|
let msg = Presentation.textSelectionChanged(aText, aNewOffset, aNewOffset,
|
2013-07-11 12:55:40 -07:00
|
|
|
aOldOffset, aOldOffset, true);
|
2013-06-19 13:11:46 -07:00
|
|
|
sendAsyncMessage('AccessFu:Present', msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-01 13:33:26 -07:00
|
|
|
function scroll(aMessage) {
|
2013-07-26 08:18:12 -07:00
|
|
|
function sendScrollCoordinates(aAccessible) {
|
|
|
|
let bounds = Utils.getBounds(aAccessible);
|
|
|
|
sendAsyncMessage('AccessFu:DoScroll',
|
|
|
|
{ bounds: bounds,
|
|
|
|
page: aMessage.json.page,
|
|
|
|
horizontal: aMessage.json.horizontal });
|
2012-10-01 13:33:26 -07:00
|
|
|
}
|
|
|
|
|
2013-07-26 08:18:12 -07:00
|
|
|
let position = Utils.getVirtualCursor(content.document).position;
|
|
|
|
if (!forwardToChild(aMessage, scroll, position)) {
|
|
|
|
sendScrollCoordinates(position);
|
2012-10-01 13:33:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-06 09:43:53 -08:00
|
|
|
function adjustRange(aMessage) {
|
|
|
|
function sendUpDownKey(aAccessible) {
|
2014-01-23 10:37:38 -08:00
|
|
|
let acc = Utils.getEmbeddedControl(aAccessible) || aAccessible;
|
2014-01-27 10:38:06 -08:00
|
|
|
let elem = acc.DOMNode;
|
|
|
|
if (elem) {
|
|
|
|
if (elem.tagName === 'INPUT' && elem.type === 'range') {
|
|
|
|
elem[aMessage.json.direction === 'forward' ? 'stepDown' : 'stepUp']();
|
|
|
|
let changeEvent = content.document.createEvent('UIEvent');
|
|
|
|
changeEvent.initEvent('change', true, true);
|
|
|
|
elem.dispatchEvent(changeEvent);
|
|
|
|
} else {
|
|
|
|
let evt = content.document.createEvent('KeyboardEvent');
|
|
|
|
let keycode = aMessage.json.direction == 'forward' ?
|
|
|
|
content.KeyEvent.DOM_VK_DOWN : content.KeyEvent.DOM_VK_UP;
|
|
|
|
evt.initKeyEvent(
|
|
|
|
"keypress", false, true, null, false, false, false, false, keycode, 0);
|
|
|
|
elem.dispatchEvent(evt);
|
|
|
|
}
|
2013-11-06 09:43:53 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let position = Utils.getVirtualCursor(content.document).position;
|
|
|
|
if (!forwardToChild(aMessage, adjustRange, position)) {
|
|
|
|
sendUpDownKey(position);
|
|
|
|
}
|
|
|
|
}
|
2012-10-01 13:33:26 -07:00
|
|
|
addMessageListener(
|
|
|
|
'AccessFu:Start',
|
|
|
|
function(m) {
|
2014-04-01 13:46:02 -07:00
|
|
|
if (m.json.logLevel) {
|
|
|
|
Logger.logLevel = Logger[m.json.logLevel];
|
|
|
|
}
|
|
|
|
|
2013-04-23 10:39:15 -07:00
|
|
|
Logger.debug('AccessFu:Start');
|
2012-10-01 13:33:26 -07:00
|
|
|
if (m.json.buildApp)
|
|
|
|
Utils.MozBuildApp = m.json.buildApp;
|
|
|
|
|
2013-06-03 11:29:14 -07:00
|
|
|
addMessageListener('AccessFu:ContextMenu', activateContextMenu);
|
2013-04-23 10:39:15 -07:00
|
|
|
addMessageListener('AccessFu:Scroll', scroll);
|
2013-11-06 09:43:53 -08:00
|
|
|
addMessageListener('AccessFu:AdjustRange', adjustRange);
|
2013-04-23 10:39:15 -07:00
|
|
|
|
2014-03-04 17:49:27 -08:00
|
|
|
if (!contentControl) {
|
|
|
|
contentControl = new ContentControl(this);
|
|
|
|
}
|
|
|
|
contentControl.start();
|
|
|
|
|
2014-06-13 10:56:38 -07:00
|
|
|
if (!eventManager) {
|
|
|
|
eventManager = new EventManager(this, contentControl);
|
|
|
|
}
|
|
|
|
eventManager.start();
|
|
|
|
|
2014-02-26 16:39:14 -08:00
|
|
|
sendAsyncMessage('AccessFu:ContentStarted');
|
2012-10-01 13:33:26 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
addMessageListener(
|
|
|
|
'AccessFu:Stop',
|
|
|
|
function(m) {
|
|
|
|
Logger.debug('AccessFu:Stop');
|
|
|
|
|
2013-06-03 11:29:14 -07:00
|
|
|
removeMessageListener('AccessFu:ContextMenu', activateContextMenu);
|
2013-04-23 10:39:15 -07:00
|
|
|
removeMessageListener('AccessFu:Scroll', scroll);
|
|
|
|
|
2013-05-21 11:16:49 -07:00
|
|
|
eventManager.stop();
|
2014-03-04 17:49:27 -08:00
|
|
|
contentControl.stop();
|
2012-10-01 13:33:26 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
sendAsyncMessage('AccessFu:Ready');
|