Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Start splitting content/utils.js into separate modules.

Primary goal: reduce global-namespace pollution.
Also revamp GM_apiLeakCheck() to deal with the new paths involved.

Refs #1156 #1401
  • Loading branch information...
commit 7612b46a1e28138da90be25a75bcf0eddb8f89d3 1 parent 02126f1
@arantius arantius authored
View
20 components/greasemonkey.js
@@ -402,19 +402,19 @@ service.prototype.injectScripts = function(
sandbox.GM_addStyle = function(css) {
GM_addStyle(wrappedContentWin.document, css);
};
- sandbox.GM_log = GM_hitch(logger, "log");
+ sandbox.GM_log = GM_util.hitch(logger, "log");
sandbox.console = console;
- sandbox.GM_setValue = GM_hitch(storage, "setValue");
- sandbox.GM_getValue = GM_hitch(storage, "getValue");
- sandbox.GM_deleteValue = GM_hitch(storage, "deleteValue");
- sandbox.GM_listValues = GM_hitch(storage, "listValues");
- sandbox.GM_getResourceURL = GM_hitch(resources, "getResourceURL");
- sandbox.GM_getResourceText = GM_hitch(resources, "getResourceText");
- sandbox.GM_openInTab = GM_hitch(
+ sandbox.GM_setValue = GM_util.hitch(storage, "setValue");
+ sandbox.GM_getValue = GM_util.hitch(storage, "getValue");
+ sandbox.GM_deleteValue = GM_util.hitch(storage, "deleteValue");
+ sandbox.GM_listValues = GM_util.hitch(storage, "listValues");
+ sandbox.GM_getResourceURL = GM_util.hitch(resources, "getResourceURL");
+ sandbox.GM_getResourceText = GM_util.hitch(resources, "getResourceText");
+ sandbox.GM_openInTab = GM_util.hitch(
this, "_openInTab", wrappedContentWin, chromeWin);
- sandbox.GM_xmlhttpRequest = GM_hitch(xmlhttpRequester,
+ sandbox.GM_xmlhttpRequest = GM_util.hitch(xmlhttpRequester,
"contentStartRequest");
- sandbox.GM_registerMenuCommand = GM_hitch(
+ sandbox.GM_registerMenuCommand = GM_util.hitch(
this, "_registerMenuCommand", wrappedContentWin, chromeWin, script);
// Re-wrap the window before assigning it to the sandbox.__proto__
View
3  content/config.js
@@ -1,4 +1,5 @@
Components.utils.import("resource://greasemonkey/third-party/MatchPattern.js");
+Components.utils.import("resource://greasemonkey/util.js");
function Config() {
this._saveTimer = null;
@@ -97,7 +98,7 @@ Config.prototype._save = function(saveNow) {
this._saveTimer = Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
- var _save = GM_hitch(this, "_save"); // dereference 'this' for the closure
+ var _save = GM_util.hitch(this, "_save"); // dereference 'this' for the closure
this._saveTimer.initWithCallback(
{'notify': function() { _save(true); }}, 250,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
View
12 content/scriptdownloader.js
@@ -1,3 +1,5 @@
+Components.utils.import("resource://greasemonkey/util.js");
+
var GM_ScriptDownloader;
(function private_scope() {
@@ -43,8 +45,8 @@ GM_ScriptDownloader.prototype.startDownload = function() {
this.req_ = new XMLHttpRequest();
this.req_.overrideMimeType("text/plain");
this.req_.open("GET", this.uri_.spec, true);
- this.req_.onreadystatechange = GM_hitch(this, "checkContentTypeBeforeDownload");
- this.req_.onload = GM_hitch(this, "handleScriptDownloadComplete");
+ this.req_.onreadystatechange = GM_util.hitch(this, "checkContentTypeBeforeDownload");
+ this.req_.onload = GM_util.hitch(this, "handleScriptDownloadComplete");
// Fixes #1359. See: http://goo.gl/EJ3FN
var httpChannel = null;
@@ -112,7 +114,7 @@ GM_ScriptDownloader.prototype.handleScriptDownloadComplete = function() {
}
GM_writeToFile(source, file,
- GM_hitch(this, 'handleScriptDownloadWriteComplete', file));
+ GM_util.hitch(this, 'handleScriptDownloadWriteComplete', file));
} catch (e) {
// NOTE: unlocalized string
alert("Script could not be installed " + e);
@@ -123,7 +125,7 @@ GM_ScriptDownloader.prototype.handleScriptDownloadComplete = function() {
GM_ScriptDownloader.prototype.handleScriptDownloadWriteComplete = function(file) {
this.script.setDownloadedFile(file);
- window.setTimeout(GM_hitch(this, "fetchDependencies"), 0);
+ window.setTimeout(GM_util.hitch(this, "fetchDependencies"), 0);
if (this.installing_) {
this.showInstallDialog();
@@ -316,7 +318,7 @@ GM_ScriptDownloader.prototype.cleanupTempFiles = function() {
GM_ScriptDownloader.prototype.showInstallDialog = function(timer) {
if (!timer) {
// otherwise, the status bar stays in the loading state.
- this.win_.setTimeout(GM_hitch(this, "showInstallDialog", true), 0);
+ this.win_.setTimeout(GM_util.hitch(this, "showInstallDialog", true), 0);
return;
}
this.win_.openDialog("chrome://greasemonkey/content/install.xul", "",
View
21 content/utils.js
@@ -27,27 +27,6 @@ function GM_getConfig() {
return GM_getService().config;
}
-function GM_hitch(obj, meth) {
- if (!obj[meth]) {
- throw "method '" + meth + "' does not exist on object '" + obj + "'";
- }
-
- var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length);
-
- return function() {
- // make a copy of staticArgs (don't modify it because it gets reused for
- // every invocation).
- var args = Array.prototype.slice.call(staticArgs);
-
- // add all the new arguments
- Array.prototype.push.apply(args, arguments);
-
- // invoke the original function with the correct this obj and the combined
- // list of static and dynamic arguments.
- return obj[meth].apply(obj, args);
- };
-}
-
/**
* Utility to create an error message in the log without throwing an error.
*/
View
8 content/xmlhttprequester.js
@@ -1,3 +1,5 @@
+Components.utils.import("resource://greasemonkey/util.js");
+
function GM_xmlhttpRequester(wrappedContentWin, chromeWindow, originUrl) {
this.wrappedContentWin = wrappedContentWin;
this.chromeWindow = chromeWindow;
@@ -33,7 +35,7 @@ GM_xmlhttpRequester.prototype.contentStartRequest = function(details) {
case "https":
case "ftp":
var req = new this.chromeWindow.XMLHttpRequest();
- GM_hitch(this, "chromeStartRequest", url, details, req)();
+ GM_util.hitch(this, "chromeStartRequest", url, details, req)();
break;
default:
throw new Error("Disallowed scheme in URL: " + details.url);
@@ -57,7 +59,7 @@ GM_xmlhttpRequester.prototype.chromeStartRequest =
function(safeUrl, details, req) {
this.setupReferer(details, req);
- var setupRequestEvent = GM_hitch(this, 'setupRequestEvent', this.wrappedContentWin);
+ var setupRequestEvent = GM_util.hitch(this, 'setupRequestEvent', this.wrappedContentWin);
setupRequestEvent(req, "abort", details);
setupRequestEvent(req, "error", details);
@@ -159,7 +161,7 @@ function(wrappedContentWin, req, event, details) {
}
// Pop back onto browser thread and call event handler.
- // Have to use nested function here instead of GM_hitch because
+ // Have to use nested function here instead of GM_util.hitch because
// otherwise details[event].apply can point to window.setTimeout, which
// can be abused to get increased privileges.
new XPCNativeWrapper(wrappedContentWin, "setTimeout()")
View
30 modules/util.js
@@ -0,0 +1,30 @@
+const EXPORTED_SYMBOLS = ['GM_util'];
+
+/*
+This "util" module separates all the methods into individual files, and lazily
+imports them automatically, the first time each method is called. Simply import
+this top-level module:
+
+Components.utils.import("resource://greasemonkey/util.js");
+
+Then call one of its methods (e.g.):
+
+GM_util.log('foo');
+
+The module 'util/foo.js' will be imported, and the 'foo' function it defines
+will be called for you. In the future that method will exist directly. Thus
+all modules inside 'util/' should define and export exactly one function, with
+the same name as the file. All other contents are privates to that method's
+module.
+*/
+var GM_util = {
+ __noSuchMethod__ : function(aName, aArguments) {
+ try {
+ Components.utils.import('resource://greasemonkey/util/' + aName + '.js',
+ GM_util);
+ return GM_util[aName].apply(GM_util, aArguments);
+ } catch (e) {
+ throw new Error('Could not import util ' + aName + ':\n' + e);
+ }
+ }
+}
View
22 modules/util/hitch.js
@@ -0,0 +1,22 @@
+const EXPORTED_SYMBOLS = ['hitch'];
+
+function hitch(obj, meth) {
+ if (!obj[meth]) {
+ throw "method '" + meth + "' does not exist on object '" + obj + "'";
+ }
+
+ var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length);
+
+ return function() {
+ // make a copy of staticArgs (don't modify it because it gets reused for
+ // every invocation).
+ var args = Array.prototype.slice.call(staticArgs);
+
+ // add all the new arguments
+ Array.prototype.push.apply(args, arguments);
+
+ // invoke the original function with the correct this obj and the combined
+ // list of static and dynamic arguments.
+ return obj[meth].apply(obj, args);
+ };
+}
Please sign in to comment.
Something went wrong with that request. Please try again.