[Pkg-mozext-commits] [greasemonkey] 03/43: [WIP] GM_rmc
David Prévot
taffit at moszumanska.debian.org
Sun Feb 22 21:56:09 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository greasemonkey.
commit f93513725b51bb84b1d6f16f4085b2e1ceeb3c1c
Author: Ventero <ventero at ventero.de>
Date: Sat Sep 27 05:20:30 2014 +0200
[WIP] GM_rmc
---
content/browser.js | 3 ++
content/framescript.js | 66 +++++++++++++++++++++++++++++++++-
content/menucommander.js | 93 +++++++++++++++++++++++++++++++++++++++---------
modules/menucommand.js | 41 ++++++---------------
modules/sandbox.js | 22 ++++++------
5 files changed, 167 insertions(+), 58 deletions(-)
diff --git a/content/browser.js b/content/browser.js
index f34a564..4e2328d 100644
--- a/content/browser.js
+++ b/content/browser.js
@@ -73,6 +73,9 @@ GM_BrowserUI.chromeLoad = function(e) {
// initialization routines will run, no matter what.
GM_BrowserUI.gmSvc.config;
+ // Initialize the chrome side handling of menu commands.
+ GM_MenuCommander.initialize();
+
GM_BrowserUI.showToolbarButton();
// Make sure this is imported at least once, so its internal timer starts.
diff --git a/content/framescript.js b/content/framescript.js
index 6033172..e6df7e9 100644
--- a/content/framescript.js
+++ b/content/framescript.js
@@ -13,7 +13,9 @@ var gStripUserPassRegexp = new RegExp('(://)([^:/]+)(:[^@/]+)?@');
var gScriptRunners = {};
function ScriptRunner(aWindow, aUrl) {
+ this.menuCommands = [];
this.window = aWindow;
+ this.windowId = GM_util.windowId(this.window);
this.url = aUrl;
}
@@ -27,11 +29,23 @@ ScriptRunner.prototype.injectScripts = function(aScripts) {
}
for (var i = 0, script = null; script = aScripts[i]; i++) {
- var sandbox = createSandbox(script, this.window, this.url);
+ var sandbox = createSandbox(script, this);
runScriptInSandbox(script, sandbox);
}
}
+ScriptRunner.prototype.registeredMenuCommand = function(aCommand) {
+ var length = this.menuCommands.push(aCommand);
+
+ sendAsyncMessage("greasemonkey:menu-command-registered", {
+ accessKey: aCommand.accessKey,
+ frozen: aCommand.frozen,
+ index: length - 1,
+ name: aCommand.name,
+ windowId: aCommand.contentWindowId
+ });
+}
+
var observer = {
observe: function(aSubject, aTopic, aData) {
if (!GM_util.getEnabled()) return;
@@ -68,6 +82,40 @@ var observer = {
this.runScripts('document-end', contentWin);
},
+ pagehide: function(aEvent) {
+ var contentWin = aEvent.target.defaultView;
+ var windowId = GM_util.windowId(contentWin);
+ if (!windowId || !gScriptRunners[windowId]) return;
+
+ // Small optimization: only send a notification if there's a menu command
+ // for this window.
+ if (!gScriptRunners[windowId].menuCommands.length) return;
+
+ if (aEvent.persisted) {
+ sendAsyncMessage("greasemonkey:toggle-menu-commands", {
+ frozen: true,
+ windowId: windowId
+ });
+ } else {
+ sendAsyncMessage("greasemonkey:clear-menu-commands", {
+ windowId: windowId
+ });
+ }
+ },
+
+ pageshow: function(aEvent) {
+ var contentWin = aEvent.target.defaultView;
+ var windowId = GM_util.windowId(contentWin);
+ if (!windowId || !gScriptRunners[windowId]) return;
+
+ if (!gScriptRunners[windowId].menuCommands.length) return;
+
+ sendAsyncMessage("greasemonkey:toggle-menu-commands", {
+ frozen: false,
+ windowId: windowId
+ });
+ },
+
runScripts: function(aRunWhen, aWrappedContentWin) {
// See #1970
// When content does (e.g.) history.replacestate() in an inline script,
@@ -109,6 +157,18 @@ var observer = {
gScriptRunners[windowId].injectScripts([script]);
},
+ runMenuCommand: function(aMessage) {
+ var windowId = aMessage.data.windowId;
+ if (!gScriptRunners[windowId]) return;
+
+ var index = aMessage.data.index;
+ var command = gScriptRunners[windowId].menuCommands[index];
+ if (!command || !command.commandFunc) return;
+
+ // Ensure |this| is set to the sandbox object inside the command function.
+ command.commandFunc.call(null);
+ },
+
createScriptFromObject: function(aObject) {
var script = Object.create(IPCScript.prototype);
// TODO: better way for this? Object.create needs property descriptors.
@@ -126,6 +186,10 @@ observerService.addObserver(observer, 'inner-window-destroyed', false);
addEventListener("DOMContentLoaded", observer.contentLoad.bind(observer));
addEventListener("load", observer.contentLoad.bind(observer));
+addEventListener("pagehide", observer.pagehide.bind(observer));
+addEventListener("pageshow", observer.pageshow.bind(observer));
addMessageListener("greasemonkey:inject-script",
observer.runDelayedScript.bind(observer));
+addMessageListener("greasemonkey:menu-command-clicked",
+ observer.runMenuCommand.bind(observer));
diff --git a/content/menucommander.js b/content/menucommander.js
index b66fa03..dfd1d9d 100644
--- a/content/menucommander.js
+++ b/content/menucommander.js
@@ -1,17 +1,62 @@
Components.utils.import('resource://greasemonkey/util.js');
-var GM_MenuCommander = {};
+var GM_MenuCommander = {
+ menuCommands: {}
+};
+
+GM_MenuCommander.initialize = function() {
+ var messageManager = Components.classes["@mozilla.org/globalmessagemanager;1"]
+ .getService(Components.interfaces.nsIMessageListenerManager);
+
+ messageManager.addMessageListener('greasemonkey:menu-command-registered',
+ GM_MenuCommander.menuCommandRegistered);
+ messageManager.addMessageListener('greasemonkey:clear-menu-commands',
+ GM_MenuCommander.clearMenuCommands);
+ messageManager.addMessageListener('greasemonkey:toggle-menu-commands',
+ GM_MenuCommander.toggleMenuCommands);
+}
-// Mix in menucommand.js so we don't pollute the global scope
-Components.utils.import('resource://greasemonkey/menucommand.js',
- GM_MenuCommander);
+GM_MenuCommander.menuCommandRegistered = function(aMessage) {
+ var windowId = aMessage.data.windowId;
+
+ if (!GM_MenuCommander.menuCommands[windowId]) {
+ GM_MenuCommander.menuCommands[windowId] = [];
+ }
+
+ var command = aMessage.data;
+ command.browser = aMessage.target;
+ GM_MenuCommander.menuCommands[windowId].push(command);
+}
+
+GM_MenuCommander.clearMenuCommands = function(aMessage) {
+ var windowId = aMessage.data.windowId;
+ if (!windowId) return;
+
+ delete GM_MenuCommander.menuCommands[windowId];
+}
+
+GM_MenuCommander.toggleMenuCommands = function(aMessage) {
+ var frozen = aMessage.data.frozen;
+ var windowId = aMessage.data.windowId;
+
+ GM_MenuCommander.withAllMenuCommandsForWindowId(windowId, function(command) {
+ command.frozen = frozen;
+ });
+}
+
+GM_MenuCommander.commandClicked = function(aCommand) {
+ aCommand.browser.messageManager.sendAsyncMessage("greasemonkey:menu-command-clicked", {
+ index: aCommand.index,
+ windowId: aCommand.windowId
+ });
+}
GM_MenuCommander.createMenuItem = function(command) {
var menuItem = document.createElement("menuitem");
menuItem.setAttribute("label", command.name);
- if ('function' == typeof command.commandFunc) {
- menuItem.addEventListener("command", command.commandFunc, true);
- }
+ menuItem.addEventListener("command", function() {
+ GM_MenuCommander.commandClicked(command);
+ }, false);
if (command.accessKey) {
menuItem.setAttribute("accesskey", command.accessKey);
@@ -25,16 +70,7 @@ GM_MenuCommander.onPageHide = function(aWindowId, aPersisted) {
GM_MenuCommander.withAllMenuCommandsForWindowId(aWindowId,
function(index, command) { command.frozen = true; });
} else {
- GM_MenuCommander.removeMatchingMenuCommands(
- null,
- function(index, command) {
- return (
- // Remove the reference if either the window is closed, ...
- GM_util.windowIsClosed(command.contentWindow)
- // ... or the window id of the destroyed page matches.
- || (aWindowId && command.contentWindowId == aWindowId));
- },
- true); // Don't forget the aForced=true passed here!
+ delete GM_MenuCommander.menuCommands[aWindowId];
}
}
@@ -67,3 +103,26 @@ GM_MenuCommander.onPopupShowing = function(aMenuPopup) {
aMenuPopup.parentNode.disabled = !haveCommands;
};
+
+GM_MenuCommander.withAllMenuCommandsForWindowId = function(
+ aContentWindowId, aCallback, aForce) {
+
+ var targetWindowIds = null;
+ if (aForce) {
+ targetWindowIds = Object.keys(GM_MenuCommander.menuCommands);
+ } else if (aContentWindowId) {
+ targetWindowIds = [aContentWindowId];
+ } else {
+ return;
+ }
+
+ for each (var windowId in targetWindowIds) {
+ var commands = GM_MenuCommander.menuCommands[windowId];
+ if (!commands) return;
+
+ var l = commands.length - 1;
+ for (var i = l, command = null; command = commands[i]; i--) {
+ aCallback(i, command);
+ }
+ }
+};
diff --git a/modules/menucommand.js b/modules/menucommand.js
index aea292d..606436d 100644
--- a/modules/menucommand.js
+++ b/modules/menucommand.js
@@ -1,5 +1,4 @@
-var EXPORTED_SYMBOLS = ['registerMenuCommand', 'removeMatchingMenuCommands',
- 'withAllMenuCommandsForWindowId'];
+var EXPORTED_SYMBOLS = ['registerMenuCommand'];
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import('resource://greasemonkey/util.js');
@@ -9,10 +8,10 @@ var gStringBundle = Services.strings.createBundle(
"chrome://greasemonkey/locale/greasemonkey.properties");
function registerMenuCommand(
- wrappedContentWin, script,
+ scriptRunner,
commandName, commandFunc, accessKey, unused, accessKey2
) {
- if (wrappedContentWin.top != wrappedContentWin) {
+ if (scriptRunner.window.top != scriptRunner.window) {
// Only register menu commands for the top level window.
return;
}
@@ -33,30 +32,12 @@ function registerMenuCommand(
}
var command = {
- name: commandName,
- accessKey: accessKey,
- commandFunc: commandFunc,
- contentWindow: wrappedContentWin,
- contentWindowId: GM_util.windowId(wrappedContentWin),
- frozen: false};
- gMenuCommands.push(command);
+ name: commandName,
+ accessKey: accessKey,
+ commandFunc: commandFunc,
+ contentWindowId: scriptRunner.windowId,
+ frozen: false
+ };
+
+ scriptRunner.registeredMenuCommand(command);
};
-
-function withAllMenuCommandsForWindowId(aContentWindowId, aCallback, aForce) {
- if(!aContentWindowId && !aForce) return;
-
- var l = gMenuCommands.length - 1;
- for (var i = l, command = null; command = gMenuCommands[i]; i--) {
- if (aForce || command.contentWindowId == aContentWindowId) {
- aCallback(i, command);
- }
- }
-};
-
-function removeMatchingMenuCommands(aContentWindowId, aCallback, aForce) {
- withAllMenuCommandsForWindowId(aContentWindowId, function(index, command) {
- if (aCallback(index, command)) {
- gMenuCommands.splice(index, 1);
- }
- }, aForce)
-}
diff --git a/modules/sandbox.js b/modules/sandbox.js
index d19dbe2..b81f4ef 100644
--- a/modules/sandbox.js
+++ b/modules/sandbox.js
@@ -22,15 +22,18 @@ function alert(msg) {
.alert(null, "Greasemonkey alert", msg);
}
-function createSandbox(aScript, aContentWin, aUrl) {
+function createSandbox(aScript, aScriptRunner) {
+ var contentWin = aScriptRunner.window;
+ var url = aScriptRunner.url;
+
if (GM_util.inArray(aScript.grants, 'none')) {
// If there is an explicit none grant, use a plain unwrapped sandbox
// with no other content.
var contentSandbox = new Components.utils.Sandbox(
- aContentWin,
+ contentWin,
{
'sandboxName': aScript.id,
- 'sandboxPrototype': aContentWin,
+ 'sandboxPrototype': contentWin,
'wantXrays': false,
});
// GM_info is always provided.
@@ -51,10 +54,10 @@ function createSandbox(aScript, aContentWin, aUrl) {
}
var sandbox = new Components.utils.Sandbox(
- [aContentWin],
+ [contentWin],
{
'sandboxName': aScript.id,
- 'sandboxPrototype': aContentWin,
+ 'sandboxPrototype': contentWin,
'wantXrays': true,
});
@@ -70,14 +73,13 @@ function createSandbox(aScript, aContentWin, aUrl) {
sandbox.exportFunction = Cu.exportFunction;
if (GM_util.inArray(aScript.grants, 'GM_addStyle')) {
- sandbox.GM_addStyle = GM_util.hitch(null, GM_addStyle, aContentWin.document);
+ sandbox.GM_addStyle = GM_util.hitch(null, GM_addStyle, contentWin.document);
}
if (GM_util.inArray(aScript.grants, 'GM_log')) {
sandbox.GM_log = GM_util.hitch(new GM_ScriptLogger(aScript), 'log');
}
if (GM_util.inArray(aScript.grants, 'GM_registerMenuCommand')) {
- var gmrmc = GM_util.hitch(
- null, registerMenuCommand, aContentWin, aScript);
+ var gmrmc = GM_util.hitch(null, registerMenuCommand, aScriptRunner);
sandbox.GM_registerMenuCommand = gmrmc;
}
@@ -109,11 +111,11 @@ function createSandbox(aScript, aContentWin, aUrl) {
}
if (GM_util.inArray(aScript.grants, 'GM_openInTab')) {
sandbox.GM_openInTab = GM_util.hitch(
- null, GM_openInTab, aContentWin);
+ null, GM_openInTab, contentWin);
}
if (GM_util.inArray(aScript.grants, 'GM_xmlhttpRequest')) {
sandbox.GM_xmlhttpRequest = GM_util.hitch(
- new GM_xmlhttpRequester(aContentWin, aUrl, sandbox),
+ new GM_xmlhttpRequester(contentWin, aScriptRunner.url, sandbox),
'contentStartRequest');
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/greasemonkey.git
More information about the Pkg-mozext-commits
mailing list