[Pkg-mozext-commits] [greasemonkey] 08/55: reduce sync messages from frame scripts

David Prévot taffit at moszumanska.debian.org
Thu Oct 29 15:38:02 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 70fab3eca06006122039403cb190228d2fd872c3
Author: The 8472 <git at infinite-source.de>
Date:   Wed Aug 26 04:04:28 2015 +0200

    reduce sync messages from frame scripts
    
    - beam down IPCScripts in advance from parent when a script changes
    - do script filtering/url matching in content process
    - piggyback script change detection on http observers instead by
    checking document/sub-document loads
---
 components/greasemonkey.js | 85 ++++++++++++++++++++++++++++++++--------------
 content/framescript.js     | 11 ++----
 modules/abstractScript.js  | 54 +++++++++++++++++++++++++++++
 modules/ipcscript.js       | 82 +++++++++++++++++++++++++++++++++++++++++++-
 modules/refererSetter.js   | 84 ++++++++++++++++++++++++++++++---------------
 modules/script.js          | 37 +++++---------------
 6 files changed, 261 insertions(+), 92 deletions(-)

diff --git a/components/greasemonkey.js b/components/greasemonkey.js
index 256bdd5..5e1f909 100644
--- a/components/greasemonkey.js
+++ b/components/greasemonkey.js
@@ -16,7 +16,6 @@ Cu.import("chrome://greasemonkey-modules/content/sync.js");
 Cu.import("chrome://greasemonkey-modules/content/util.js");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("chrome://greasemonkey-modules/content/refererSetter.js", {});
 
 
 var gStartupHasRun = false;
@@ -31,9 +30,7 @@ var gTmpDir = Components.classes["@mozilla.org/file/directory_service;1"]
 var GM_GUID = "{e4a8a97b-f2ed-450b-b12d-ee082ba24781}";
 var gGreasemonkeyVersion = 'unknown';
 Cu.import("resource://gre/modules/AddonManager.jsm");
-AddonManager.getAddonByID(GM_GUID, function(addon) {
-  gGreasemonkeyVersion = '' + addon.version;
-});
+
 
 /////////////////////// Component-global Helper Functions //////////////////////
 
@@ -57,8 +54,6 @@ function startup(aService) {
       .getService(Ci.nsIMessageListenerManager);
   globalMessageManager.addMessageListener(
       'greasemonkey:script-install', aService.scriptInstall.bind(aService));
-  globalMessageManager.addMessageListener(
-      'greasemonkey:scripts-for-url', aService.getScriptsForUrl.bind(aService));
 
   var scriptValHandler = aService.handleScriptValMsg.bind(aService);
   globalMessageManager.addMessageListener(
@@ -75,6 +70,9 @@ function startup(aService) {
   parentMessageManager.addMessageListener(
       'greasemonkey:scripts-for-uuid',
       aService.getScriptsForUuid.bind(aService));
+  parentMessageManager.addMessageListener("greasemonkey:scripts-update", function(message) {
+    return aService.scriptUpdateData();
+  });
   var mm = Services.ppmm ? Services.ppmm : globalMessageManager;
   mm.addMessageListener(
       'greasemonkey:url-is-temp-file', aService.urlIsTempFile.bind(aService));
@@ -83,6 +81,27 @@ function startup(aService) {
   // Why?  Who knows!?
   globalMessageManager.loadFrameScript(
       'chrome://greasemonkey/content/framescript.js', true);
+  
+
+  
+  // beam down initial set of scripts
+  aService.broadcastScriptUpdates();
+  
+  // notification is async
+  // send the scripts again once we have our version
+  AddonManager.getAddonByID(GM_GUID, function(addon) {
+    gGreasemonkeyVersion = '' + addon.version;
+    aService.broadcastScriptUpdates();
+  });
+  
+  // beam down on updates
+  aService.config.addObserver({notifyEvent: function(script, event, data) {
+    if(["modified", "install", "move", "edit-enabled", "uninstall"].some(function(e) {return e == event;})) {
+      aService.broadcastScriptUpdates();
+    }
+  }});
+  
+  Cu.import("chrome://greasemonkey-modules/content/refererSetter.js", {});
 
   Services.obs.addObserver(aService, 'quit-application', false);
 
@@ -133,6 +152,37 @@ service.prototype.__defineGetter__('config', function() {
   return this._config;
 });
 
+service.prototype.scriptUpdateData = function() {
+  var ipcScripts = this.config.scripts.map(function(script) {
+    return new IPCScript(script, gGreasemonkeyVersion);        
+  });
+  
+  var excludes = this.config._globalExcludes;
+  
+  var data = { scripts: ipcScripts, globalExcludes: excludes};
+  
+  return data;
+}
+
+service.prototype.broadcastScriptUpdates = function() {
+  
+  var data = this.scriptUpdateData();
+  
+  var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+    .getService(Ci.nsIMessageListenerManager);
+  
+  
+  // check if initialProcessData is supported
+  // child will use sync message if not
+  if(ppmm.initialProcessData) {
+    // for new processes
+    ppmm.initialProcessData["greasemonkey:scripts-update"] = data;
+  }
+  
+  // for existing ones
+  ppmm.broadcastAsyncMessage("greasemonkey:scripts-update", data);
+}
+
 service.prototype.closeAllScriptValStores = function() {
   for (var scriptId in this.scriptValStores) {
     var scriptValStore = this.scriptValStores[scriptId];
@@ -140,33 +190,16 @@ service.prototype.closeAllScriptValStores = function() {
   }
 };
 
-service.prototype.getScriptsForUrl = function(aMessage) {
-  var url = aMessage.data.url;
-  var when = aMessage.data.when;
-  var windowId = aMessage.data.windowId;
-  var browser = aMessage.target;
+service.prototype.scriptRefresh = function(url, windowId, browser) {
 
   if (!GM_util.getEnabled() || !url) return [];
   if (!GM_util.isGreasemonkeyable(url)) return [];
 
   if (GM_prefRoot.getValue('enableScriptRefreshing')) {
-    this.config.updateModifiedScripts(when, url, windowId, browser);
+    this.config.updateModifiedScripts("document-start", url, windowId, browser);
+    this.config.updateModifiedScripts("document-end", url, windowId, browser);
   }
 
-  var scripts = this.config.getMatchingScripts(function(script) {
-    try {
-      return GM_util.scriptMatchesUrlAndRuns(script, url, when);
-    } catch (e) {
-      GM_util.logError(e, false, e.fileName, e.lineNumber);
-      // See #1692; Prevent failures like that from being so severe.
-      return false;
-    }
-  }).map(function(script) {
-    // Make the script serializable so it can be sent to the frame script.
-    return new IPCScript(script, gGreasemonkeyVersion);
-  });
-
-  return scripts;
 };
 
 service.prototype.getScriptsForUuid = function(aMessage) {
diff --git a/content/framescript.js b/content/framescript.js
index c3b7e00..6785b5f 100644
--- a/content/framescript.js
+++ b/content/framescript.js
@@ -128,16 +128,9 @@ function loadFailedScript(aMessage) {
 function runScripts(aRunWhen, aContentWin) {
   var url = urlForWin(aContentWin);
   if (!GM_util.isGreasemonkeyable(url)) return;
+  
+  var scripts = IPCScript.scriptsForUrl(url, aRunWhen, GM_util.windowId(aContentWin, 'outer'));
 
-  var response = sendSyncMessage(
-    'greasemonkey:scripts-for-url', {
-      'url': url,
-      'when': aRunWhen,
-      'windowId': GM_util.windowId(aContentWin, 'outer'),
-    });
-  if (!response || !response[0]) return;
-
-  var scripts = response[0].map(createScriptFromObject);
   injectScripts(scripts, aContentWin);
 }
 
diff --git a/modules/abstractScript.js b/modules/abstractScript.js
new file mode 100644
index 0000000..436c6f4
--- /dev/null
+++ b/modules/abstractScript.js
@@ -0,0 +1,54 @@
+'use strict';
+
+const EXPORTED_SYMBOLS = ['AbstractScript'];
+
+const gAboutBlankRegexp = /^about:blank/;
+
+const Cu = Components.utils;
+
+Cu.import('chrome://greasemonkey-modules/content/third-party/convert2RegExp.js');
+Cu.import('chrome://greasemonkey-modules/content/third-party/MatchPattern.js');
+Cu.import('chrome://greasemonkey-modules/content/util.js');
+
+function AbstractScript() {
+
+}
+
+Object.defineProperty(AbstractScript.prototype, "globalExcludes", {
+  get: function() {
+    return [];
+  },
+  configurable: true
+});
+
+AbstractScript.prototype.matchesURL = function(url) {
+  var uri = GM_util.uriFromUrl(url);
+
+  function testClude(glob) {
+    // Do not run in about:blank unless _specifically_ requested. See #1298
+    if (gAboutBlankRegexp.test(url) && !gAboutBlankRegexp.test(glob)) {
+      return false;
+    }
+
+    return GM_convert2RegExp(glob, uri).test(url);
+  }
+  function testMatch(matchPattern) {
+    if ('string' == typeof matchPattern)
+      matchPattern = new MatchPattern(matchPattern);
+    return matchPattern.doMatch(url);
+  }
+
+  // Flat deny if URL is not greaseable, or matches global excludes.
+  if (!GM_util.isGreasemonkeyable(url)) return false;
+
+  if (this.globalExcludes.some(testClude)) return false;
+
+  // Allow based on user cludes.
+  if (this.userExcludes.some(testClude)) return false;
+  if (this.userIncludes.some(testClude) || this.userMatches.some(testMatch))
+    return true;
+
+  // Finally allow based on script cludes and matches.
+  if (this.excludes.some(testClude)) return false;
+  return (this.includes.some(testClude) || this.matches.some(testMatch));
+};
diff --git a/modules/ipcscript.js b/modules/ipcscript.js
index 99f530f..b064b9b 100644
--- a/modules/ipcscript.js
+++ b/modules/ipcscript.js
@@ -1,17 +1,33 @@
 var EXPORTED_SYMBOLS = ['IPCScript'];
 
 Components.utils.import("chrome://greasemonkey-modules/content/util.js");
+Components.utils.import('chrome://greasemonkey-modules/content/abstractScript.js');
+
+
+// IPCScript class
+
 
 function IPCScript(aScript, addonVersion) {
   this.addonVersion = addonVersion;
+  this.enabled = aScript.enabled;
+  this.needsUninstall = aScript.needsUninstall;
+  this.pendingExec = {};
+  this.pendingExec.length = aScript.pendingExec.length || 0
   this.description = aScript.description;
   this.excludes = aScript.excludes;
+  this.userExcludes = aScript.userExcludes;
   this.fileURL = aScript.fileURL;
   this.grants = aScript.grants;
   this.id = aScript.id;
   this.includes = aScript.includes;
+  this.userIncludes = aScript.userIncludes;
   this.localized = aScript.localized;
-  this.matches = aScript.matches.map(function(m) { return m.pattern; });
+  this.matches = aScript.matches.map(function(m) {
+    return m.pattern;
+  });
+  this.userMatches = aScript.userMatches.map(function(m) {
+    return m.pattern;
+  });
   this.name = aScript.name;
   this.namespace = aScript.namespace;
   this.noframes = aScript.noframes;
@@ -35,6 +51,70 @@ function IPCScript(aScript, addonVersion) {
   });
 };
 
+//inheritance magic
+IPCScript.prototype = Object.create(AbstractScript.prototype, {
+  constructor: {
+    value: IPCScript 
+  }
+});
+
+
+// initialize module-scoped stuff, after prototype override
+
+var scripts = [];
+
+const cpmm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]
+    .getService(Components.interfaces.nsISyncMessageSender);
+
+function objectToScript(obj) {
+  var script = Object.create(IPCScript.prototype);
+  Object.keys(obj).forEach(function(k) {
+    script[k] = obj[k];
+  });
+  Object.freeze(script);
+  return script;
+}
+
+function updateData(data) {
+  if (!data) return;
+  var newScripts = data.scripts.map(objectToScript);
+  Object.freeze(newScripts);
+  scripts = newScripts;
+  IPCScript.prototype.globalExcludes = data.globalExcludes;
+}
+
+if (cpmm.initialProcessData) {
+  updateData(cpmm.initialProcessData["greasemonkey:scripts-update"]);
+} else {
+  // support FF < 41
+  var results = cpmm.sendSyncMessage("greasemonkey:scripts-update");
+  updateData(results[0]);
+}
+
+cpmm.addMessageListener("greasemonkey:scripts-update", function(message) {
+  updateData(message.data);
+});
+
+
+
+// static method
+
+IPCScript.scriptsForUrl = function(url, when, windowId) {
+    return scripts.filter(function(script) {
+      try {
+        return GM_util.scriptMatchesUrlAndRuns(script, url, when);
+      } catch (e) {
+        console.log(e);
+        GM_util.logError(e, false, e.fileName, e.lineNumber);
+        // See #1692; Prevent failures like that from being so severe.
+        return false;
+      }
+   });
+}
+
+// instance methods
+
+
 IPCScript.prototype.info = function() {
   var resources = {};
   for (var i = 0, r = null; r = this.resources[i]; i++) {
diff --git a/modules/refererSetter.js b/modules/refererSetter.js
index 470ecfe..a8471a6 100644
--- a/modules/refererSetter.js
+++ b/modules/refererSetter.js
@@ -1,28 +1,56 @@
-'use strict';
-
-const EXPORTED_SYMBOLS = [];
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-const observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
-
-Services.obs.addObserver({
-  observe: function(subject, topic, data) {
-    if(!(subject instanceof Components.interfaces.nsIHttpChannel))
-      return;
-    if(!(subject instanceof Components.interfaces.nsIPropertyBag))
-      return;
-
-    var channel = subject; // instanceof -> automatic QI
-    var referer;
-    
-    try{
-      referer = channel.getProperty("greasemonkey:referer-override");      
-    } catch(ex) {
-      // property not found
-      return;
-    }
-    
-    channel.setRequestHeader("Referer", referer, false);
-  }
-}, "http-on-modify-request", false);
\ No newline at end of file
+'use strict';
+
+const EXPORTED_SYMBOLS = [];
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("chrome://greasemonkey-modules/content/util.js");
+Components.utils.import("chrome://greasemonkey-modules/content/prefmanager.js");
+
+const types = Components.interfaces.nsIContentPolicy
+
+function overrideReferer(subject) {
+  if (!(subject instanceof Components.interfaces.nsIHttpChannel)) return;
+  if (!(subject instanceof Components.interfaces.nsIPropertyBag)) return;
+
+  var channel = subject; // instanceof -> automatic QI
+  var referer;
+
+  try {
+    referer = channel.getProperty("greasemonkey:referer-override");
+  } catch (ex) {
+    // property not found
+    return;
+  }
+
+  channel.setRequestHeader("Referer", referer, false);
+
+}
+
+function checkScriptRefresh(channel) {
+  if (!channel.loadInfo) return;
+
+  var type = channel.loadInfo.contentPolicyType;
+  if (type != types.TYPE_DOCUMENT && type != types.TYPE_SUBDOCUMENT) return;
+
+  // forward compatibility: https://bugzilla.mozilla.org/show_bug.cgi?id=1124477
+  var browser = channel.loadInfo.topFrameElement;
+
+  if (!browser && channel.notificationCallbacks) {
+    // current API: https://bugzilla.mozilla.org/show_bug.cgi?id=1123008#c7
+    var loadCtx = channel.notificationCallbacks.QueryInterface(
+        Components.interfaces.nsIInterfaceRequestor).getInterface(
+        Components.interfaces.nsILoadContext);
+    browser = loadCtx.topFrameElement;
+  }
+
+  var windowId = channel.loadInfo.innerWindowID;
+
+  GM_util.getService().scriptRefresh(channel.URI.spec, windowId, browser);
+}
+
+Services.obs.addObserver({
+  observe: function(subject, topic, data) {
+    overrideReferer(subject);
+    checkScriptRefresh(subject);
+  }
+}, "http-on-modify-request", false);
diff --git a/modules/script.js b/modules/script.js
index bbb1859..d64b179 100644
--- a/modules/script.js
+++ b/modules/script.js
@@ -12,8 +12,8 @@ Components.utils.import('chrome://greasemonkey-modules/content/scriptRequire.js'
 Components.utils.import('chrome://greasemonkey-modules/content/scriptResource.js');
 Components.utils.import("chrome://greasemonkey-modules/content/storageBack.js");
 Components.utils.import('chrome://greasemonkey-modules/content/third-party/MatchPattern.js');
-Components.utils.import('chrome://greasemonkey-modules/content/third-party/convert2RegExp.js');
 Components.utils.import('chrome://greasemonkey-modules/content/util.js');
+Components.utils.import('chrome://greasemonkey-modules/content/abstractScript.js');
 
 var stringBundle = Components
     .classes["@mozilla.org/intl/stringbundle;1"]
@@ -27,8 +27,6 @@ AddonManager.getAddonByID(GM_GUID, function(addon) {
   gGreasemonkeyVersion = '' + addon.version;
 });
 
-var gAboutBlankRegexp = /^about:blank/;
-
 function Script(configNode) {
   this._observers = [];
 
@@ -76,33 +74,16 @@ function Script(configNode) {
   if (configNode) this._loadFromConfigNode(configNode);
 }
 
-Script.prototype.matchesURL = function(url) {
-  var uri = GM_util.uriFromUrl(url);
-
-  function testClude(glob) {
-    // Do not run in about:blank unless _specifically_ requested.  See #1298
-    if (gAboutBlankRegexp.test(url) && !gAboutBlankRegexp.test(glob)) {
-      return false;
-    }
-
-    return GM_convert2RegExp(glob, uri).test(url);
-  }
-  function testMatch(matchPattern) {
-    return matchPattern.doMatch(url);
+// inheritance magic
+Script.prototype = Object.create(AbstractScript.prototype, {
+  constructor: {
+    value: Script 
   }
+});
 
-  // Flat deny if URL is not greaseable, or matches global excludes.
-  if (!GM_util.isGreasemonkeyable(url)) return false;
-  if (GM_util.getService().config._globalExcludes.some(testClude)) return false;
-
-  // Allow based on user cludes.
-  if (this._userExcludes.some(testClude)) return false;
-  if (this._userIncludes.some(testClude) || this._userMatches.some(testMatch)) return true;
-
-  // Finally allow based on script cludes and matches.
-  if (this._excludes.some(testClude)) return false;
-  return (this._includes.some(testClude) || this._matches.some(testMatch));
-};
+Object.defineProperty(Script.prototype, "globalExcludes", {
+  get: function(){return GM_util.getService().config._globalExcludes;}
+})
 
 Script.prototype._changed = function(event, data) {
   var dontSave = ('val-set' == event || 'val-del' == event);

-- 
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