Skip to content

Commit 4776b30

Browse files
committed
Enable multi-process and avoid CPOW
1 parent adf5292 commit 4776b30

File tree

3 files changed

+62
-37
lines changed

3 files changed

+62
-37
lines changed

content-script.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const createFrame = (window, src, allowScripts, loadFun) => {
8787
frame.removeEventListener("load", loadHandler, false);
8888
log(LOG_INFO, "frame loaded, going to process");
8989
try {
90-
loadFun.call(frame);
90+
loadFun(frame);
9191
}
9292
catch (ex) {
9393
log(LOG_ERROR, "failed to invoke callback on frame", ex);
@@ -103,7 +103,7 @@ const createFrame = (window, src, allowScripts, loadFun) => {
103103
frame.removeEventListener("abort", errorHandler, false);
104104
log(LOG_ERROR, "frame err'ed out, giving up");
105105
try {
106-
loadFun.call(frame);
106+
loadFun(frame);
107107
}
108108
catch (ex) {
109109
log(LOG_ERROR, "failed to invoke callback on frame", ex);
@@ -279,28 +279,44 @@ Repaginator.prototype = {
279279
delete this._title;
280280
}
281281
},
282+
unregister: function R_unregister() {
283+
sendAsyncMessage("repagination:unregister", {id: this.frameId});
284+
if (this._window) {
285+
this._window.document.body.removeAttribute("repagination");
286+
this._window.removeEventListener("beforeunload", this.unload, true);
287+
}
288+
},
282289
repaginate: function R_repaginate() {
283290
this.setTitle();
284291
let wnd = this._window;
285292
if (!wnd) {
286293
log(LOG_INFO, "window is gone!");
287294
return;
288295
}
296+
this.frameId = wnd.QueryInterface(Ci.nsIInterfaceRequestor).
297+
getInterface(Ci.nsIDOMWindowUtils).
298+
outerWindowID;
299+
sendAsyncMessage("repagination:register", {id: this.frameId});
300+
this.unload = () => {
301+
log(LOG_DEBUG, "unload");
302+
this.unregister();
303+
};
304+
wnd.addEventListener("beforeunload", this.unload, true);
305+
289306
try {
290307
let node = wnd.document.evaluate(
291308
this.query, wnd.document, null, 9, null).singleNodeValue;
292309
if (!node) {
293310
throw new Error("no node");
294311
}
295312
wnd.document.body.setAttribute("repagination", "true");
296-
let self = this;
297-
createFrame(wnd, node.href, this.allowScripts, function() {
298-
self.loadNext(this, 0);
313+
createFrame(wnd, node.href, this.allowScripts, frame => {
314+
this.loadNext(frame, 0);
299315
});
300316
}
301317
catch (ex) {
318+
this.unregister();
302319
this.restoreTitle();
303-
wnd.document.body.removeAttribute("repagination");
304320
log(LOG_ERROR, "repaginate failed", ex);
305321
}
306322
},
@@ -365,6 +381,7 @@ Repaginator.prototype = {
365381
let ownerDoc = element.ownerDocument;
366382
if (!ownerDoc || !this._window) {
367383
yield true;
384+
this.unregister();
368385
this.restoreTitle();
369386
log(LOG_INFO, "gone, giving up!");
370387
return;
@@ -474,28 +491,28 @@ Repaginator.prototype = {
474491

475492
this.setTitle();
476493
log(LOG_INFO, "next please");
477-
let self = this;
478494
createFrame(ownerDoc.defaultView, node.href, this.allowScripts,
479-
function continueLoadNext() {
480-
if (!self || !self._window || self._window.closed) {
495+
frame => {
496+
if (!this._window || this._window.closed) {
481497
log(LOG_DEBUG, "self is gone by now");
482-
self.restoreTitle();
498+
this.unregister();
499+
this.restoreTitle();
483500
return;
484501
}
485-
if (self.slideshow && self.seconds) {
486-
log(LOG_INFO, "slideshow; delay: " + self.seconds * 1000);
487-
self.loadNext(this, self.seconds * 1000);
502+
if (this.slideshow && this.seconds) {
503+
log(LOG_INFO, "slideshow; delay: " + this.seconds * 1000);
504+
this.loadNext(frame, this.seconds * 1000);
488505
}
489506
else {
490507
log(LOG_INFO, "regular; no-delay");
491-
self.loadNext(this, 0);
508+
this.loadNext(frame, 0);
492509
}
493510
});
494511
}
495512
catch (ex) {
496513
log(LOG_INFO, "loadNext complete", ex);
514+
this.unregister();
497515
this.restoreTitle();
498-
ownerDoc.body.removeAttribute("repagination");
499516
}
500517
}
501518
finally {

install.rdf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<em:version>2015.10.11</em:version>
1111

1212
<em:bootstrap>true</em:bootstrap>
13+
<em:multiprocessCompatible>true</em:multiprocessCompatible>
1314
<em:type>2</em:type>
1415

1516
<em:optionsURL>chrome://repagination/content/options.xul</em:optionsURL>

main.js

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@
55

66
const {registerOverlay, unloadWindow} = require("sdk/windows");
77

8+
const RUNNING = new Set();
9+
const globalMM = Cc["@mozilla.org/globalmessagemanager;1"].
10+
getService(Ci.nsIMessageListenerManager);
11+
12+
function registerRunning(m) {
13+
RUNNING.add(m.data.id);
14+
log(LOG_DEBUG, `added ${m.data.id} to running`);
15+
}
16+
17+
function unregisterRunning(m) {
18+
RUNNING.delete(m.data.id);
19+
log(LOG_DEBUG, `removed ${m.data.id} from running`);
20+
}
21+
globalMM.addMessageListener("repagination:register", registerRunning);
22+
globalMM.addMessageListener("repagination:unregister", unregisterRunning);
23+
unload(() => {
24+
globalMM.removeMessageListener("repagination:register", registerRunning);
25+
globalMM.removeMessageListener("repagination:unregister", unregisterRunning);
26+
});
27+
828
/* globals _ */
929
lazy(this, "_", function() {
1030
let bundle = require("sdk/strings").
@@ -14,26 +34,15 @@ lazy(this, "_", function() {
1434
};
1535
});
1636

17-
function checkSameOrigin(node, tryLoadUri) {
37+
function checkSameOrigin(principal, tryLoadUri) {
1838
try {
1939
if (!(tryLoadUri instanceof Ci.nsIURI)) {
2040
tryLoadUri = Services.io.newURI(tryLoadUri, null, null);
2141
}
2242
if (tryLoadUri.schemeIs("data")) {
2343
return true;
2444
}
25-
let pr = node.nodePrincipal;
26-
pr = Cc["@mozilla.org/scriptsecuritymanager;1"].
27-
getService(Ci.nsIScriptSecurityManager).
28-
getAppCodebasePrincipal(pr.URI,
29-
pr.appId,
30-
pr.isInBrowserElement);
31-
if (pr.checkMayLoad.length == 3) {
32-
pr.checkMayLoad(tryLoadUri, false, false);
33-
}
34-
else {
35-
pr.checkMayLoad(tryLoadUri, false);
36-
}
45+
principal.checkMayLoad(tryLoadUri, false, true);
3746
return true;
3847
}
3948
catch (ex) {
@@ -196,14 +205,13 @@ function main(window, document) {
196205
menuCurrent.allDomainMenu.hidden || !prefs.showalldomain;
197206
}
198207

199-
log(LOG_DEBUG, "context menu showing!");
208+
let {gContextMenu} = window;
209+
log(LOG_DEBUG, `context menu showing for ${gContextMenu.frameOuterWindowID}!`);
200210
try {
201-
if (window.gContextMenu.onLink &&
202-
/^https?$/.test(window.gContextMenu.linkURI.scheme)) {
203-
setMenuHidden(!checkSameOrigin(window.gContextMenu.target.ownerDocument,
204-
window.gContextMenu.linkURL));
205-
let body = window.gContextMenu.target.ownerDocument.body;
206-
if (!body.hasAttribute("repagination")) {
211+
if (gContextMenu.onLink && /^https?$/.test(gContextMenu.linkURI.scheme)) {
212+
setMenuHidden(!checkSameOrigin(gContextMenu.principal,
213+
gContextMenu.linkURL));
214+
if (!RUNNING.has(gContextMenu.frameOuterWindowID)) {
207215
menuCurrent.stopMenu.hidden = true;
208216
}
209217
return;
@@ -214,8 +222,7 @@ function main(window, document) {
214222
}
215223
try {
216224
setMenuHidden(true);
217-
let body = window.gContextMenu.target.ownerDocument.body;
218-
if (body.hasAttribute("repagination")) {
225+
if (RUNNING.has(gContextMenu.frameOuterWindowID)) {
219226
menuCurrent.menu.hidden = menuCurrent.stopMenu.hidden = false;
220227
}
221228
}

0 commit comments

Comments
 (0)