toolkit/content/browser-child.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 let Cc = Components.classes;
michael@0 6 let Ci = Components.interfaces;
michael@0 7 let Cu = Components.utils;
michael@0 8
michael@0 9 Cu.import("resource://gre/modules/Services.jsm");
michael@0 10 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
michael@0 11 Cu.import("resource://gre/modules/RemoteAddonsChild.jsm");
michael@0 12 Cu.import("resource://gre/modules/Timer.jsm");
michael@0 13
michael@0 14 let SyncHandler = {
michael@0 15 init: function() {
michael@0 16 sendAsyncMessage("SetSyncHandler", {}, {handler: this});
michael@0 17 },
michael@0 18
michael@0 19 getFocusedElementAndWindow: function() {
michael@0 20 let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
michael@0 21
michael@0 22 let focusedWindow = {};
michael@0 23 let elt = fm.getFocusedElementForWindow(content, true, focusedWindow);
michael@0 24 return [elt, focusedWindow.value];
michael@0 25 },
michael@0 26 };
michael@0 27
michael@0 28 SyncHandler.init();
michael@0 29
michael@0 30 let WebProgressListener = {
michael@0 31 init: function() {
michael@0 32 let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
michael@0 33 .getInterface(Ci.nsIWebProgress);
michael@0 34 webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL);
michael@0 35 },
michael@0 36
michael@0 37 _requestSpec: function (aRequest) {
michael@0 38 if (!aRequest || !(aRequest instanceof Ci.nsIChannel))
michael@0 39 return null;
michael@0 40 return aRequest.QueryInterface(Ci.nsIChannel).URI.spec;
michael@0 41 },
michael@0 42
michael@0 43 _setupJSON: function setupJSON(aWebProgress, aRequest) {
michael@0 44 return {
michael@0 45 isTopLevel: aWebProgress.isTopLevel,
michael@0 46 isLoadingDocument: aWebProgress.isLoadingDocument,
michael@0 47 requestURI: this._requestSpec(aRequest),
michael@0 48 loadType: aWebProgress.loadType,
michael@0 49 documentContentType: content.document && content.document.contentType
michael@0 50 };
michael@0 51 },
michael@0 52
michael@0 53 _setupObjects: function setupObjects(aWebProgress) {
michael@0 54 return {
michael@0 55 contentWindow: content,
michael@0 56 // DOMWindow is not necessarily the content-window with subframes.
michael@0 57 DOMWindow: aWebProgress.DOMWindow
michael@0 58 };
michael@0 59 },
michael@0 60
michael@0 61 onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
michael@0 62 let json = this._setupJSON(aWebProgress, aRequest);
michael@0 63 let objects = this._setupObjects(aWebProgress);
michael@0 64
michael@0 65 json.stateFlags = aStateFlags;
michael@0 66 json.status = aStatus;
michael@0 67
michael@0 68 sendAsyncMessage("Content:StateChange", json, objects);
michael@0 69 },
michael@0 70
michael@0 71 onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
michael@0 72 },
michael@0 73
michael@0 74 onLocationChange: function onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
michael@0 75 let json = this._setupJSON(aWebProgress, aRequest);
michael@0 76 let objects = this._setupObjects(aWebProgress);
michael@0 77
michael@0 78 json.location = aLocationURI ? aLocationURI.spec : "";
michael@0 79 json.flags = aFlags;
michael@0 80
michael@0 81 if (json.isTopLevel) {
michael@0 82 json.canGoBack = docShell.canGoBack;
michael@0 83 json.canGoForward = docShell.canGoForward;
michael@0 84 json.documentURI = content.document.documentURIObject.spec;
michael@0 85 json.charset = content.document.characterSet;
michael@0 86 }
michael@0 87
michael@0 88 sendAsyncMessage("Content:LocationChange", json, objects);
michael@0 89 },
michael@0 90
michael@0 91 onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {
michael@0 92 let json = this._setupJSON(aWebProgress, aRequest);
michael@0 93 let objects = this._setupObjects(aWebProgress);
michael@0 94
michael@0 95 json.status = aStatus;
michael@0 96 json.message = aMessage;
michael@0 97
michael@0 98 sendAsyncMessage("Content:StatusChange", json, objects);
michael@0 99 },
michael@0 100
michael@0 101 onSecurityChange: function onSecurityChange(aWebProgress, aRequest, aState) {
michael@0 102 let json = this._setupJSON(aWebProgress, aRequest);
michael@0 103 let objects = this._setupObjects(aWebProgress);
michael@0 104
michael@0 105 json.state = aState;
michael@0 106 json.status = SecurityUI.getSSLStatusAsString();
michael@0 107
michael@0 108 sendAsyncMessage("Content:SecurityChange", json, objects);
michael@0 109 },
michael@0 110
michael@0 111 QueryInterface: function QueryInterface(aIID) {
michael@0 112 if (aIID.equals(Ci.nsIWebProgressListener) ||
michael@0 113 aIID.equals(Ci.nsISupportsWeakReference) ||
michael@0 114 aIID.equals(Ci.nsISupports)) {
michael@0 115 return this;
michael@0 116 }
michael@0 117
michael@0 118 throw Components.results.NS_ERROR_NO_INTERFACE;
michael@0 119 }
michael@0 120 };
michael@0 121
michael@0 122 WebProgressListener.init();
michael@0 123
michael@0 124 let WebNavigation = {
michael@0 125 _webNavigation: docShell.QueryInterface(Ci.nsIWebNavigation),
michael@0 126
michael@0 127 init: function() {
michael@0 128 addMessageListener("WebNavigation:GoBack", this);
michael@0 129 addMessageListener("WebNavigation:GoForward", this);
michael@0 130 addMessageListener("WebNavigation:GotoIndex", this);
michael@0 131 addMessageListener("WebNavigation:LoadURI", this);
michael@0 132 addMessageListener("WebNavigation:Reload", this);
michael@0 133 addMessageListener("WebNavigation:Stop", this);
michael@0 134
michael@0 135 // Send a CPOW for the sessionHistory object.
michael@0 136 let history = this._webNavigation.sessionHistory;
michael@0 137 sendAsyncMessage("WebNavigation:setHistory", {}, {history: history});
michael@0 138 },
michael@0 139
michael@0 140 receiveMessage: function(message) {
michael@0 141 switch (message.name) {
michael@0 142 case "WebNavigation:GoBack":
michael@0 143 this.goBack();
michael@0 144 break;
michael@0 145 case "WebNavigation:GoForward":
michael@0 146 this.goForward();
michael@0 147 break;
michael@0 148 case "WebNavigation:GotoIndex":
michael@0 149 this.gotoIndex(message.data.index);
michael@0 150 break;
michael@0 151 case "WebNavigation:LoadURI":
michael@0 152 this.loadURI(message.data.uri, message.data.flags);
michael@0 153 break;
michael@0 154 case "WebNavigation:Reload":
michael@0 155 this.reload(message.data.flags);
michael@0 156 break;
michael@0 157 case "WebNavigation:Stop":
michael@0 158 this.stop(message.data.flags);
michael@0 159 break;
michael@0 160 }
michael@0 161 },
michael@0 162
michael@0 163 goBack: function() {
michael@0 164 if (this._webNavigation.canGoBack)
michael@0 165 this._webNavigation.goBack();
michael@0 166 },
michael@0 167
michael@0 168 goForward: function() {
michael@0 169 if (this._webNavigation.canGoForward)
michael@0 170 this._webNavigation.goForward();
michael@0 171 },
michael@0 172
michael@0 173 gotoIndex: function(index) {
michael@0 174 this._webNavigation.gotoIndex(index);
michael@0 175 },
michael@0 176
michael@0 177 loadURI: function(uri, flags) {
michael@0 178 this._webNavigation.loadURI(uri, flags, null, null, null);
michael@0 179 },
michael@0 180
michael@0 181 reload: function(flags) {
michael@0 182 this._webNavigation.reload(flags);
michael@0 183 },
michael@0 184
michael@0 185 stop: function(flags) {
michael@0 186 this._webNavigation.stop(flags);
michael@0 187 }
michael@0 188 };
michael@0 189
michael@0 190 WebNavigation.init();
michael@0 191
michael@0 192 let SecurityUI = {
michael@0 193 getSSLStatusAsString: function() {
michael@0 194 let status = docShell.securityUI.QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
michael@0 195
michael@0 196 if (status) {
michael@0 197 let helper = Cc["@mozilla.org/network/serialization-helper;1"]
michael@0 198 .getService(Ci.nsISerializationHelper);
michael@0 199
michael@0 200 status.QueryInterface(Ci.nsISerializable);
michael@0 201 return helper.serializeToString(status);
michael@0 202 }
michael@0 203
michael@0 204 return null;
michael@0 205 }
michael@0 206 };
michael@0 207
michael@0 208 let ControllerCommands = {
michael@0 209 init: function () {
michael@0 210 addMessageListener("ControllerCommands:Do", this);
michael@0 211 },
michael@0 212
michael@0 213 receiveMessage: function(message) {
michael@0 214 switch(message.name) {
michael@0 215 case "ControllerCommands:Do":
michael@0 216 if (docShell.isCommandEnabled(message.data))
michael@0 217 docShell.doCommand(message.data);
michael@0 218 break;
michael@0 219 }
michael@0 220 }
michael@0 221 }
michael@0 222
michael@0 223 ControllerCommands.init()
michael@0 224
michael@0 225 addEventListener("DOMTitleChanged", function (aEvent) {
michael@0 226 let document = content.document;
michael@0 227 switch (aEvent.type) {
michael@0 228 case "DOMTitleChanged":
michael@0 229 if (!aEvent.isTrusted || aEvent.target.defaultView != content)
michael@0 230 return;
michael@0 231
michael@0 232 sendAsyncMessage("DOMTitleChanged", { title: document.title });
michael@0 233 break;
michael@0 234 }
michael@0 235 }, false);
michael@0 236
michael@0 237 addEventListener("DOMWindowClose", function (aEvent) {
michael@0 238 if (!aEvent.isTrusted)
michael@0 239 return;
michael@0 240 sendAsyncMessage("DOMWindowClose");
michael@0 241 aEvent.preventDefault();
michael@0 242 }, false);
michael@0 243
michael@0 244 addEventListener("ImageContentLoaded", function (aEvent) {
michael@0 245 if (content.document instanceof Ci.nsIImageDocument) {
michael@0 246 let req = content.document.imageRequest;
michael@0 247 if (!req.image)
michael@0 248 return;
michael@0 249 sendAsyncMessage("ImageDocumentLoaded", { width: req.image.width,
michael@0 250 height: req.image.height });
michael@0 251 }
michael@0 252 }, false);
michael@0 253
michael@0 254 let DocumentObserver = {
michael@0 255 init: function() {
michael@0 256 Services.obs.addObserver(this, "document-element-inserted", false);
michael@0 257 addEventListener("unload", () => {
michael@0 258 Services.obs.removeObserver(this, "document-element-inserted");
michael@0 259 });
michael@0 260 },
michael@0 261
michael@0 262 observe: function(aSubject, aTopic, aData) {
michael@0 263 if (aSubject == content.document) {
michael@0 264 sendAsyncMessage("DocumentInserted", {synthetic: aSubject.mozSyntheticDocument});
michael@0 265 }
michael@0 266 },
michael@0 267 };
michael@0 268 DocumentObserver.init();
michael@0 269
michael@0 270 const ZoomManager = {
michael@0 271 get fullZoom() {
michael@0 272 return this._cache.fullZoom;
michael@0 273 },
michael@0 274
michael@0 275 get textZoom() {
michael@0 276 return this._cache.textZoom;
michael@0 277 },
michael@0 278
michael@0 279 set fullZoom(value) {
michael@0 280 this._cache.fullZoom = value;
michael@0 281 this._markupViewer.fullZoom = value;
michael@0 282 },
michael@0 283
michael@0 284 set textZoom(value) {
michael@0 285 this._cache.textZoom = value;
michael@0 286 this._markupViewer.textZoom = value;
michael@0 287 },
michael@0 288
michael@0 289 refreshFullZoom: function() {
michael@0 290 return this._refreshZoomValue('fullZoom');
michael@0 291 },
michael@0 292
michael@0 293 refreshTextZoom: function() {
michael@0 294 return this._refreshZoomValue('textZoom');
michael@0 295 },
michael@0 296
michael@0 297 /**
michael@0 298 * Retrieves specified zoom property value from markupViewer and refreshes
michael@0 299 * cache if needed.
michael@0 300 * @param valueName Either 'fullZoom' or 'textZoom'.
michael@0 301 * @returns Returns true if cached value was actually refreshed.
michael@0 302 * @private
michael@0 303 */
michael@0 304 _refreshZoomValue: function(valueName) {
michael@0 305 let actualZoomValue = this._markupViewer[valueName];
michael@0 306 if (actualZoomValue != this._cache[valueName]) {
michael@0 307 this._cache[valueName] = actualZoomValue;
michael@0 308 return true;
michael@0 309 }
michael@0 310 return false;
michael@0 311 },
michael@0 312
michael@0 313 get _markupViewer() {
michael@0 314 return docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
michael@0 315 },
michael@0 316
michael@0 317 _cache: {
michael@0 318 fullZoom: NaN,
michael@0 319 textZoom: NaN
michael@0 320 }
michael@0 321 };
michael@0 322
michael@0 323 addMessageListener("FullZoom", function (aMessage) {
michael@0 324 ZoomManager.fullZoom = aMessage.data.value;
michael@0 325 });
michael@0 326
michael@0 327 addMessageListener("TextZoom", function (aMessage) {
michael@0 328 ZoomManager.textZoom = aMessage.data.value;
michael@0 329 });
michael@0 330
michael@0 331 addEventListener("FullZoomChange", function () {
michael@0 332 if (ZoomManager.refreshFullZoom()) {
michael@0 333 sendAsyncMessage("FullZoomChange", { value: ZoomManager.fullZoom});
michael@0 334 }
michael@0 335 }, false);
michael@0 336
michael@0 337 addEventListener("TextZoomChange", function (aEvent) {
michael@0 338 if (ZoomManager.refreshTextZoom()) {
michael@0 339 sendAsyncMessage("TextZoomChange", { value: ZoomManager.textZoom});
michael@0 340 }
michael@0 341 }, false);
michael@0 342
michael@0 343 RemoteAddonsChild.init(this);
michael@0 344
michael@0 345 addMessageListener("NetworkPrioritizer:AdjustPriority", (msg) => {
michael@0 346 let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
michael@0 347 let loadGroup = webNav.QueryInterface(Ci.nsIDocumentLoader)
michael@0 348 .loadGroup.QueryInterface(Ci.nsISupportsPriority);
michael@0 349 loadGroup.adjustPriority(msg.data.adjustment);
michael@0 350 });
michael@0 351
michael@0 352 let AutoCompletePopup = {
michael@0 353 QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]),
michael@0 354
michael@0 355 init: function() {
michael@0 356 // Hook up the form fill autocomplete controller.
michael@0 357 let controller = Cc["@mozilla.org/satchel/form-fill-controller;1"]
michael@0 358 .getService(Ci.nsIFormFillController);
michael@0 359
michael@0 360 controller.attachToBrowser(docShell, this.QueryInterface(Ci.nsIAutoCompletePopup));
michael@0 361
michael@0 362 this._input = null;
michael@0 363 this._popupOpen = false;
michael@0 364
michael@0 365 addMessageListener("FormAutoComplete:HandleEnter", message => {
michael@0 366 this.selectedIndex = message.data.selectedIndex;
michael@0 367
michael@0 368 let controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
michael@0 369 getService(Components.interfaces.nsIAutoCompleteController);
michael@0 370 controller.handleEnter(message.data.isPopupSelection);
michael@0 371 });
michael@0 372 },
michael@0 373
michael@0 374 get input () { return this._input; },
michael@0 375 get overrideValue () { return null; },
michael@0 376 set selectedIndex (index) { },
michael@0 377 get selectedIndex () {
michael@0 378 // selectedIndex getter must be synchronous because we need the
michael@0 379 // correct value when the controller is in controller::HandleEnter.
michael@0 380 // We can't easily just let the parent inform us the new value every
michael@0 381 // time it changes because not every action that can change the
michael@0 382 // selectedIndex is trivial to catch (e.g. moving the mouse over the
michael@0 383 // list).
michael@0 384 return sendSyncMessage("FormAutoComplete:GetSelectedIndex", {});
michael@0 385 },
michael@0 386 get popupOpen () {
michael@0 387 return this._popupOpen;
michael@0 388 },
michael@0 389
michael@0 390 openAutocompletePopup: function (input, element) {
michael@0 391 this._input = input;
michael@0 392 this._popupOpen = true;
michael@0 393 },
michael@0 394
michael@0 395 closePopup: function () {
michael@0 396 this._popupOpen = false;
michael@0 397 sendAsyncMessage("FormAutoComplete:ClosePopup", {});
michael@0 398 },
michael@0 399
michael@0 400 invalidate: function () {
michael@0 401 },
michael@0 402
michael@0 403 selectBy: function(reverse, page) {
michael@0 404 this._index = sendSyncMessage("FormAutoComplete:SelectBy", {
michael@0 405 reverse: reverse,
michael@0 406 page: page
michael@0 407 });
michael@0 408 }
michael@0 409 }
michael@0 410
michael@0 411 let [initData] = sendSyncMessage("Browser:Init");
michael@0 412 docShell.useGlobalHistory = initData.useGlobalHistory;
michael@0 413 if (initData.initPopup) {
michael@0 414 setTimeout(function() AutoCompletePopup.init(), 0);
michael@0 415 }

mercurial