Permalink
Browse files

Merge remote-tracking branch 'upstream/master'

  • Loading branch information...
2 parents 04191a8 + 454efec commit 6ba6a55d9ff62d84428b8924d628e07234752721 @meh committed Mar 26, 2011
Showing with 139 additions and 60 deletions.
  1. +32 −21 components/greasemonkey.js
  2. +7 −3 content/addons4-overlay.js
  3. +35 −24 content/browser.js
  4. +15 −7 content/browser.xul
  5. +49 −4 content/menucommander.js
  6. +1 −1 content/statusbar.xul
View
@@ -87,6 +87,7 @@ GM_GreasemonkeyService.prototype = {
entry: CONTRACTID,
value: CONTRACTID,
service: true}],
+ menuCommandId: 0,
menuCommands: [],
// nsISupports
@@ -122,7 +123,6 @@ GM_GreasemonkeyService.prototype = {
}
},
-
// gmIGreasemonkeyService
domContentLoaded: function(wrappedContentWin, chromeWin) {
var url = wrappedContentWin.document.location.href;
@@ -131,12 +131,21 @@ GM_GreasemonkeyService.prototype = {
if (scripts.length > 0) {
this.injectScripts(scripts, url, wrappedContentWin, chromeWin);
}
+ },
- // Clean out obsolete commands.
- // TODO: This doesn't remove commands until the content window is gone.
- // If the script is edited, old commands hang around.
- for (var i = 0, command = null; command = this.menuCommands[i]; i++) {
- if (command.window.closed) delete this.menuCommands[i--];
+ contentUnloaded: function(wrappedContentWin, chromeWin) {
+ var l = this.menuCommands.length - 1;
+ for (var i = l, command = null; command = this.menuCommands[i]; i--) {
+ var closed = false;
+ try {
+ closed = command.contentWindow.closed;
+ } catch (e) { }
+
+ if (closed ||
+ (command.contentWindow == wrappedContentWin)
+ ) {
+ this.menuCommands.splice(i, 1);
+ }
}
},
@@ -176,10 +185,6 @@ GM_GreasemonkeyService.prototype = {
if (ct == Ci.nsIContentPolicy.TYPE_DOCUMENT &&
cl.spec.match(/\.user\.js$/)) {
-
- dump("shouldload: " + cl.spec + "\n");
- dump("ignorescript: " + this.ignoreNextScript_ + "\n");
-
if (!this.ignoreNextScript_
&& !this.isTempScript(cl)
&& GM_installUri(cl, ctx.contentWindow)
@@ -197,7 +202,6 @@ GM_GreasemonkeyService.prototype = {
},
ignoreNextScript: function() {
- dump("ignoring next script...\n");
this.ignoreNextScript_ = true;
},
@@ -274,9 +278,8 @@ GM_GreasemonkeyService.prototype = {
this, "openInTab", wrappedContentWin, chromeWin);
sandbox.GM_xmlhttpRequest = GM_hitch(xmlhttpRequester,
"contentStartRequest");
- sandbox.GM_registerMenuCommand = GM_hitch(this,
- "registerMenuCommand",
- unsafeContentWin);
+ sandbox.GM_registerMenuCommand = GM_hitch(
+ this, "registerMenuCommand", wrappedContentWin, chromeWin, script);
// Re-wrap the window before assigning it to the sandbox.__proto__
// This is a workaround for a bug in which the Security Manager
@@ -314,17 +317,25 @@ GM_GreasemonkeyService.prototype = {
}
},
- registerMenuCommand: function(unsafeContentWin, commandName, commandFunc,
- accelKey, accelModifiers, accessKey) {
+ registerMenuCommand: function(
+ wrappedContentWin, chromeWin, script,
+ commandName, commandFunc, accelKey, accelModifiers, accessKey) {
if (!GM_apiLeakCheck("GM_registerMenuCommand")) {
return;
}
- var command = {name: commandName,
+ var command = {id: "userscript-command-" + this.menuCommandId++,
+ script: script,
+ name: commandName,
accelKey: accelKey,
accelModifiers: accelModifiers,
accessKey: accessKey,
commandFunc: commandFunc,
- window: unsafeContentWin};
+ contentWindow: wrappedContentWin.top,
+ chromeWindow: chromeWin,
+ key: null};
+ if (accelKey) {
+ command.key = chromeWin.GM_MenuCommander.createKey(command);
+ }
this.menuCommands.push(command);
},
@@ -363,8 +374,8 @@ GM_GreasemonkeyService.prototype = {
// try to find the line of the actual error line
var line = e && e.lineNumber;
- if (4294967295 == line) {
- // Line number is reported as max int in edge cases. Sometimes
+ if (line > 0xFFFFFF00) {
+ // Line number is reported as a huge int in edge cases. Sometimes
// the right one is in the "location", instead. Look there.
if (e.location && e.location.lineNumber) {
line = e.location.lineNumber;
@@ -381,7 +392,7 @@ GM_GreasemonkeyService.prototype = {
e, // error obj
0, // 0 = error (1 = warning)
err.uri,
- err.lineNumber
+ line
);
} else {
GM_logError(
View
@@ -96,11 +96,15 @@ function init() {
function onContextPopupShowing(aEvent) {
var popup = aEvent.target;
- var viewIsUserScripts = (
- 'addons://list/user-script' == gViewController.currentViewId);
+ var selectedItem = gListView._listBox.selectedItem ||
+ gSearchView._listBox.selectedItem;
+ var selectedIsUserScript = (selectedItem &&
+ 'user-script' == selectedItem.getAttribute('type')
+ );
+
for (var i = 0, menuitem = null; menuitem = popup.children[i]; i++) {
var menuitemIsUserScript = ('user-script' == menuitem.getAttribute('type'));
- menuitem.collapsed = viewIsUserScripts != menuitemIsUserScript;
+ menuitem.collapsed = selectedIsUserScript != menuitemIsUserScript;
}
};
View
@@ -45,12 +45,15 @@ GM_BrowserUI.chromeLoad = function(e) {
// Update visual status when enabled state changes.
GM_prefRoot.watch("enabled", GM_BrowserUI.refreshStatus);
+ GM_BrowserUI.refreshStatus();
+
+ gBrowser.addEventListener("DOMContentLoaded", GM_BrowserUI.contentLoad, true);
+ gBrowser.addEventListener("pagehide", GM_BrowserUI.contentUnload, true);
+
+ var sidebar = document.getElementById("sidebar");
+ sidebar.addEventListener("DOMContentLoaded", GM_BrowserUI.contentLoad, true);
+ sidebar.addEventListener("pagehide", GM_BrowserUI.contentUnload, true);
- // hook various events
- document.getElementById("appcontent")
- .addEventListener("DOMContentLoaded", GM_BrowserUI.contentLoad, true);
- document.getElementById("sidebar")
- .addEventListener("DOMContentLoaded", GM_BrowserUI.contentLoad, true);
document.getElementById("contentAreaContextMenu")
.addEventListener("popupshowing", GM_BrowserUI.contextMenuShowing, false);
@@ -88,15 +91,15 @@ GM_BrowserUI.openInTab = function(domWindow, url) {
* If that document is in in the top-level window of the focused tab, find
* it's menu items and activate them.
*/
-GM_BrowserUI.contentLoad = function(e) {
+GM_BrowserUI.contentLoad = function(event) {
if (!GM_getEnabled()) return;
- var safeWin = e.target.defaultView;
- var unsafeWin = safeWin.wrappedJSObject;
+ var safeWin = event.target.defaultView;
var href = safeWin.location.href;
if (GM_isGreasemonkeyable(href)) {
GM_BrowserUI.gmSvc.domContentLoaded(safeWin, window);
+ GM_MenuCommander.attachKeys();
}
// Show the greasemonkey install banner if we are navigating to a .user.js
@@ -110,6 +113,16 @@ GM_BrowserUI.contentLoad = function(e) {
}
};
+GM_BrowserUI.contentUnload = function(event) {
+ if (event.persisted) return; // http://goo.gl/qeY5W
+
+ var safeWin = event.target.defaultView;
+
+ if (GM_isGreasemonkeyable(safeWin.location.href)) {
+ GM_BrowserUI.gmSvc.contentUnloaded(safeWin, window);
+ GM_MenuCommander.detachKeys();
+ }
+};
/**
* Shows the install banner across the top of the tab that is displayed when
@@ -267,19 +280,17 @@ GM_BrowserUI.isMyWindow = function(domWindow) {
return false;
};
-function GM_handleMenuPopupshowing(aMenupopup) {
- var enabledMenuitem = aMenupopup.getElementsByClassName('gm-enabled-item')[0];
- enabledMenuitem.setAttribute("checked", GM_getEnabled());
-}
-
GM_BrowserUI.refreshStatus = function() {
- if (!GM_BrowserUI.toolbarButton) return;
- GM_BrowserUI.toolbarButton.setAttribute(
- 'disabled', GM_getEnabled() ? 'no' : 'yes');
-};
+ var enabledEl = document.getElementById("gm_toggle_enabled");
+ var checkedEl = document.getElementById("gm_toggle_checked");
-GM_BrowserUI.toggleStatus = function() {
- GM_setEnabled(!GM_getEnabled());
+ if (GM_getEnabled()) {
+ checkedEl.setAttribute('checked', true);
+ enabledEl.removeAttribute('disabled');
+ } else {
+ checkedEl.removeAttribute('checked');
+ enabledEl.setAttribute('disabled', 'yes');
+ }
};
GM_BrowserUI.viewContextItemClicked = function() {
@@ -292,13 +303,13 @@ GM_BrowserUI.viewContextItemClicked = function() {
GM_BrowserUI.nodeInserted = function(aEvent) {
if ('greasemonkey-tbb' == aEvent.target.id) {
- GM_BrowserUI.toolbarButton = aEvent.target;
+ var toolbarButton = aEvent.target;
- // Set the icon properly.
- GM_BrowserUI.refreshStatus();
// Duplicate the tools menu popup inside the toolbar button.
- var menupopup = document.getElementById('gm_general_menu').firstChild;
- GM_BrowserUI.toolbarButton.appendChild(menupopup.cloneNode(true));
+ if (!toolbarButton.firstChild) {
+ var menupopup = document.getElementById('gm_general_menu').firstChild;
+ toolbarButton.appendChild(menupopup.cloneNode(true));
+ }
}
};
View
@@ -15,13 +15,23 @@
<script type="application/x-javascript" src="chrome://greasemonkey/content/scriptdownloader.js" />
<script type="application/x-javascript" src="chrome://greasemonkey/content/browser.js" />
+ <commandset>
+ <!-- sync the 'disabled' attribute for toolbar button -->
+ <command id="gm_toggle_enabled" oncommand="GM_setEnabled(!GM_getEnabled());"/>
+ <!-- sync the 'checked' attribute for menu items -->
+ <command id="gm_toggle_checked" oncommand="GM_setEnabled(!GM_getEnabled());"/>
+ </commandset>
+
+ <window id="main-window">
+ <keyset id="userscript-command-keys" insertafter="mainKeyset"></keyset>
+ </window>
+
<toolbarpalette id='BrowserToolbarPalette'>
<toolbarbutton id='greasemonkey-tbb' type='menu-button'
class='toolbarbutton-1 chromeclass-toolbar-additional'
- oncommand='GM_BrowserUI.toggleStatus();'
+ command="gm_toggle_enabled"
label='Greasemonkey' tooltiptext='Greasemonkey'
- >
- </toolbarbutton>
+ />
</toolbarpalette>
<popup id="contentAreaContextMenu">
@@ -46,14 +56,12 @@
accesskey="G"
label="Greasemonkey"
>
- <menupopup onpopupshowing="GM_handleMenuPopupshowing(this);"
- oncommand="event.stopPropagation();"
- >
+ <menupopup oncommand="event.stopPropagation();">
<menuitem class='gm-enabled-item'
accesskey="&statusbar.enabled.accesskey;"
label="&statusbar.enabled;"
type="checkbox"
- oncommand="GM_BrowserUI.toggleStatus();" />
+ command="gm_toggle_checked"/>
<menuseparator />
<menuitem
accesskey="&menu.manage.accesskey;"
View
@@ -3,6 +3,7 @@ var GM_MenuCommander = {};
GM_MenuCommander.createMenuItem = function(command) {
var menuItem = document.createElement("menuitem");
menuItem._commandFunc = command.commandFunc;
+ menuItem.setAttribute("key", command.id);
menuItem.setAttribute("label", command.name);
menuItem.setAttribute("oncommand", "this._commandFunc()");
@@ -12,13 +13,40 @@ GM_MenuCommander.createMenuItem = function(command) {
) {
menuItem.setAttribute("accesskey", command.accessKey);
} else {
- throw "accessKey must be a single character";
+ GM_logError(new Error('Error with menu command "'
+ + command.name + '": accessKey must be a single character'));
}
}
return menuItem;
};
+GM_MenuCommander.createKey = function(command) {
+ var key = document.createElement("key");
+
+ if ((typeof command.accelKey) == "number") {
+ key.setAttribute("keycode", command.accelKey);
+ } else if ((typeof command.accelKey) == "string"
+ && command.accelKey.length == 1
+ ) {
+ key.setAttribute("key", command.accelKey);
+ } else {
+ GM_logError(new Error(
+ command.script.name + ":\n" +
+ "accelKey must be a numerical keycode or a single character"));
+ }
+
+ key.setAttribute("modifiers", command.accelModifiers);
+
+ // hack, because listen("oncommand", commandFunc) does not work!
+ key._commandFunc = command.commandFunc;
+ key.setAttribute("oncommand", "this._commandFunc()");
+
+ key.setAttribute("id", command.id);
+
+ return key;
+};
+
GM_MenuCommander.onPopupShowing = function(aMenuPopup) {
var allCommands = GM_BrowserUI.gmSvc.menuCommands;
@@ -30,17 +58,34 @@ GM_MenuCommander.onPopupShowing = function(aMenuPopup) {
// Add menu items for commands for the active window.
var flag = false;
for (var i = 0, command = null; command = allCommands[i]; i++) {
- // Firefox 4 must unwrap this document to compare equal.
- if (command.window.document == content.document.wrappedJSObject) {
+ if (command.contentWindow.document == gBrowser.contentDocument) {
aMenuPopup.appendChild(GM_MenuCommander.createMenuItem(command));
flag = true;
}
}
if (!flag) {
var warning = document.createElement("menuitem");
warning.setAttribute(
- "label", GM_BrowserUI.bundle.getString('menuitem.nocommands'));
+ "label", GM_BrowserUI.bundle.getString("menuitem.nocommands"));
warning.setAttribute("disabled", "true");
aMenuPopup.appendChild(warning);
}
};
+
+GM_MenuCommander.attachKeys = function() {
+ GM_MenuCommander.detachKeys();
+
+ var keyset = document.getElementById("userscript-command-keys");
+ var gmSvc = GM_BrowserUI.gmSvc;
+ for (var i = 0, command = null; command = gmSvc.menuCommands[i]; i++) {
+ if (!command.key) continue;
+ if (command.contentWindow.document == gBrowser.contentDocument) {
+ keyset.appendChild(command.key);
+ }
+ }
+};
+
+GM_MenuCommander.detachKeys = function() {
+ var keyset = document.getElementById("userscript-command-keys");
+ while (keyset.firstChild) keyset.removeChild(keyset.firstChild);
+};
View
@@ -41,7 +41,7 @@
accesskey="&statusbar.enabled.accesskey;"
label="&statusbar.enabled;"
type="checkbox"
- oncommand="GM_setEnabled(!GM_getEnabled());" />
+ command="gm_toggle_checked" />
</menupopup>
</statusbar>

0 comments on commit 6ba6a55

Please sign in to comment.