Sat, 03 Jan 2015 20:18:00 +0100
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.
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 (function () { // bug 673569 workaround :(
7 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
9 Cu.import("resource://gre/modules/PageThumbs.jsm");
10 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
11 Cu.import("resource://gre/modules/Services.jsm");
13 const STATE_LOADING = 1;
14 const STATE_CAPTURING = 2;
15 const STATE_CANCELED = 3;
17 const backgroundPageThumbsContent = {
19 init: function () {
20 Services.obs.addObserver(this, "document-element-inserted", true);
22 // We want a low network priority for this service - lower than b/g tabs
23 // etc - so set it to the lowest priority available.
24 this._webNav.QueryInterface(Ci.nsIDocumentLoader).
25 loadGroup.QueryInterface(Ci.nsISupportsPriority).
26 priority = Ci.nsISupportsPriority.PRIORITY_LOWEST;
28 docShell.allowMedia = false;
29 docShell.allowPlugins = false;
30 docShell.allowContentRetargeting = false;
31 let defaultFlags = Ci.nsIRequest.LOAD_ANONYMOUS |
32 Ci.nsIRequest.LOAD_BYPASS_CACHE |
33 Ci.nsIRequest.INHIBIT_CACHING |
34 Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY;
35 docShell.defaultLoadFlags = defaultFlags;
37 addMessageListener("BackgroundPageThumbs:capture",
38 this._onCapture.bind(this));
39 docShell.
40 QueryInterface(Ci.nsIInterfaceRequestor).
41 getInterface(Ci.nsIWebProgress).
42 addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
43 },
45 observe: function (subj, topic, data) {
46 // Arrange to prevent (most) popup dialogs for this window - popups done
47 // in the parent (eg, auth) aren't prevented, but alert() etc are.
48 // disableDialogs only works on the current inner window, so it has
49 // to be called every page load, but before scripts run.
50 if (subj == content.document) {
51 content.
52 QueryInterface(Ci.nsIInterfaceRequestor).
53 getInterface(Ci.nsIDOMWindowUtils).
54 disableDialogs();
55 }
56 },
58 get _webNav() {
59 return docShell.QueryInterface(Ci.nsIWebNavigation);
60 },
62 _onCapture: function (msg) {
63 this._nextCapture = {
64 id: msg.data.id,
65 url: msg.data.url,
66 };
67 if (this._currentCapture) {
68 if (this._state == STATE_LOADING) {
69 // Cancel the current capture.
70 this._state = STATE_CANCELED;
71 this._loadAboutBlank();
72 }
73 // Let the current capture finish capturing, or if it was just canceled,
74 // wait for onStateChange due to the about:blank load.
75 return;
76 }
77 this._startNextCapture();
78 },
80 _startNextCapture: function () {
81 if (!this._nextCapture)
82 return;
83 this._currentCapture = this._nextCapture;
84 delete this._nextCapture;
85 this._state = STATE_LOADING;
86 this._currentCapture.pageLoadStartDate = new Date();
87 this._webNav.loadURI(this._currentCapture.url,
88 Ci.nsIWebNavigation.LOAD_FLAGS_STOP_CONTENT,
89 null, null, null);
90 },
92 onStateChange: function (webProgress, req, flags, status) {
93 if (webProgress.isTopLevel &&
94 (flags & Ci.nsIWebProgressListener.STATE_STOP) &&
95 this._currentCapture) {
96 if (req.name == "about:blank") {
97 if (this._state == STATE_CAPTURING) {
98 // about:blank has loaded, ending the current capture.
99 this._finishCurrentCapture();
100 delete this._currentCapture;
101 this._startNextCapture();
102 }
103 else if (this._state == STATE_CANCELED) {
104 // A capture request was received while the current capture's page
105 // was still loading.
106 delete this._currentCapture;
107 this._startNextCapture();
108 }
109 }
110 else if (this._state == STATE_LOADING) {
111 // The requested page has loaded. Capture it.
112 this._state = STATE_CAPTURING;
113 this._captureCurrentPage();
114 }
115 }
116 },
118 _captureCurrentPage: function () {
119 let capture = this._currentCapture;
120 capture.finalURL = this._webNav.currentURI.spec;
121 capture.pageLoadTime = new Date() - capture.pageLoadStartDate;
123 let canvas = PageThumbs._createCanvas(content);
124 let canvasDrawDate = new Date();
125 PageThumbs._captureToCanvas(content, canvas);
126 capture.canvasDrawTime = new Date() - canvasDrawDate;
128 canvas.toBlob(blob => {
129 capture.imageBlob = blob;
130 // Load about:blank to finish the capture and wait for onStateChange.
131 this._loadAboutBlank();
132 });
133 },
135 _finishCurrentCapture: function () {
136 let capture = this._currentCapture;
137 let fileReader = Cc["@mozilla.org/files/filereader;1"].
138 createInstance(Ci.nsIDOMFileReader);
139 fileReader.onloadend = () => {
140 sendAsyncMessage("BackgroundPageThumbs:didCapture", {
141 id: capture.id,
142 imageData: fileReader.result,
143 finalURL: capture.finalURL,
144 telemetry: {
145 CAPTURE_PAGE_LOAD_TIME_MS: capture.pageLoadTime,
146 CAPTURE_CANVAS_DRAW_TIME_MS: capture.canvasDrawTime,
147 },
148 });
149 };
150 fileReader.readAsArrayBuffer(capture.imageBlob);
151 },
153 // We load about:blank to finish all captures, even canceled captures. Two
154 // reasons: GC the captured page, and ensure it can't possibly load any more
155 // resources.
156 _loadAboutBlank: function _loadAboutBlank() {
157 this._webNav.loadURI("about:blank",
158 Ci.nsIWebNavigation.LOAD_FLAGS_STOP_CONTENT,
159 null, null, null);
160 },
162 QueryInterface: XPCOMUtils.generateQI([
163 Ci.nsIWebProgressListener,
164 Ci.nsISupportsWeakReference,
165 Ci.nsIObserver,
166 ]),
167 };
169 backgroundPageThumbsContent.init();
171 })();