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