[Pkg-mozext-commits] [adblock-plus] 208/464: Added onShutdown object collecting shutdown handlers instead of explicit shutdown() calls

David Prévot taffit at moszumanska.debian.org
Tue Jul 22 20:44:18 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository adblock-plus.

commit e53eebf44e142b9e8ffdcd35f97b612058a7505d
Author: Wladimir Palant <trev at adblockplus.org>
Date:   Mon Jan 23 13:26:49 2012 +0100

    Added onShutdown object collecting shutdown handlers instead of explicit shutdown() calls
---
 bootstrap.js.tmpl | 52 +++++++++++++++++++++++++++++++++++++++-------------
 packager.py       | 55 +++++++++++++++++++++++++++++--------------------------
 prefs.js          | 18 +-----------------
 windowObserver.js | 51 ++++++++++++++++++++++++++++++++-------------------
 4 files changed, 101 insertions(+), 75 deletions(-)

diff --git a/bootstrap.js.tmpl b/bootstrap.js.tmpl
index 035d3e9..37748a9 100644
--- a/bootstrap.js.tmpl
+++ b/bootstrap.js.tmpl
@@ -18,14 +18,21 @@ function uninstall(params, reason) {}
 
 function startup(params, reason)
 {
+  addonData = params;
+
   {%- if hasChrome %}
   if (Services.vc.compare(Services.appinfo.platformVersion, "10.0") < 0)
+  {
     Components.manager.addBootstrappedManifestLocation(params.installPath);
+    onShutdown.add(function() Components.manager.removeBootstrappedManifestLocation(params.installPath));
+  }
+  {%- set hasShutdownHandlers = True %}
   {%- endif %}
 
-  addonData = params;
   {%- if hasChromeRequires %}
   Services.obs.addObserver(RequireObserver, "{{metadata.get('general', 'basename')}}-require", true);
+  onShutdown.add(function() Services.obs.removeObserver(RequireObserver, "{{metadata.get('general', 'basename')}}-require"));
+  {%- set hasShutdownHandlers = True %}
   {%- endif %}
 
   require("main").Main.init();
@@ -33,8 +40,6 @@ function startup(params, reason)
 
 function shutdown(params, reason)
 {
-  require("main").Main.shutdown();
-
   {%- if chromeWindows %}
   let windowNames = {{chromeWindows|json}};
   for (let i = 0; i < windowNames.length; i++)
@@ -52,18 +57,39 @@ function shutdown(params, reason)
   }
   {%- endif %}
 
-  {%- if hasChromeRequires %}
-  Services.obs.removeObserver(RequireObserver, "{{metadata.get('general', 'basename')}}-require");
-  {%- endif %}
-  addonData = null;
-  require.scopes = {__proto__: null};
-
-  {%- if hasChrome %}
-  if (Services.vc.compare(Services.appinfo.platformVersion, "10.0") < 0)
-    Components.manager.removeBootstrappedManifestLocation(params.installPath);
+  {%- if hasShutdownHandlers %}
+  for (let i = shutdownHandlers.length - 1; i >= 0; i --)
+  {
+    try
+    {
+      shutdownHandlers[i]();
+    }
+    catch (e)
+    {
+      Cu.reportError(e);
+    }
+  }
   {%- endif %}
 }
 
+{%- if hasShutdownHandlers %}
+let shutdownHandlers = [];
+let onShutdown =
+{
+  add: function(handler)
+  {
+    if (shutdownHandlers.indexOf(handler) < 0)
+      shutdownHandlers.push(handler);
+  },
+  remove: function(handler)
+  {
+    let index = shutdownHandlers.indexOf(handler);
+    if (index >= 0)
+      shutdownHandlers.splice(index, 1);
+  }
+};
+{%- endif %}
+
 function require(module)
 {
   let scopes = require.scopes;
@@ -83,7 +109,7 @@ function require(module)
     else
     {
     {%- endif %}
-      scopes[module] = {require: require, {% if hasUnrequires %}unrequire: unrequire, {% endif %}exports: {}};
+      scopes[module] = {require: require, {% if hasUnrequires %}unrequire: unrequire, {% endif %}{% if hasShutdownHandlers %}onShutdown: onShutdown, {% endif %}exports: {}};
       Services.scriptloader.loadSubScript(addonData.resourceURI.spec + module + ".js", scopes[module]);
     {%- if 'info' in requires %}
     }
diff --git a/packager.py b/packager.py
index 45b0271..5f31bd4 100644
--- a/packager.py
+++ b/packager.py
@@ -218,29 +218,41 @@ def readXPIFiles(baseDir, params, files):
       readFile(files, params, path, os.path.basename(path))
 
 def addMissingFiles(baseDir, params, files):
-  hasChrome = False
-  hasChromeRequires = False
-  hasUnrequires = False
-  chromeWindows = []
-  requires = {}
+  templateData = {
+    'hasChrome': False,
+    'hasChromeRequires': False,
+    'hasUnrequires': False,
+    'hasShutdownHandlers': False,
+    'chromeWindows': [],
+    'requires': {},
+    'metadata': params['metadata'],
+  }
+
+  def checkScript(name):
+    content = files[name]
+    for match in re.finditer(r'(?:^|\s)require\("([\w\-]+)"\)', content):
+      templateData['requires'][match.group(1)] = True
+      if name.startswith('chrome/content/'):
+        templateData['hasChromeRequires'] = True
+    if not '/' in name:
+      if re.search(r'(?:^|\s)unrequire\(', content):
+        templateData['hasUnrequires'] = True
+      elif re.search(r'(?:^|\s)onShutdown\.(?:add|remove)\(', content):
+        templateData['hasShutdownHandlers'] = True
+
   for name, content in files.iteritems():
     if name == 'chrome.manifest':
-      hasChrome = True
-    if name.startswith('chrome/content/') and name.endswith('.js') and re.search(r'\srequire\(', content):
-      hasChromeRequires = True
-    if not '/' in name and name.endswith('.js') and re.search(r'\sunrequire\(', content):
-      hasUnrequires = True
-    if name.endswith('.js'):
-      for match in re.finditer(r'\srequire\("(\w+)"\)', content):
-        requires[match.group(1)] = True
-    if name.endswith('.xul'):
+      templateData['hasChrome'] = True
+    elif name.endswith('.js'):
+      checkScript(name)
+    elif name.endswith('.xul'):
       match = re.search(r'<(?:window|dialog)\s[^>]*\bwindowtype="([^">]+)"', content)
       if match:
-        chromeWindows.append(match.group(1))
+        templateData['chromeWindows'].append(match.group(1))
 
   while True:
     missing = []
-    for module in requires:
+    for module in templateData['requires']:
       moduleFile = module + '.js'
       if not moduleFile in files:
         path = os.path.join(buildtools.__path__[0], moduleFile)
@@ -250,20 +262,11 @@ def addMissingFiles(baseDir, params, files):
       break
     for path, moduleFile in missing:
       readFile(files, params, path, moduleFile)
-      for match in re.finditer(r'\srequire\("(\w+)"\)', files[moduleFile]):
-        requires[match.group(1)] = True
+      checkScript(moduleFile)
 
   env = jinja2.Environment(loader=jinja2.FileSystemLoader(buildtools.__path__[0]))
   env.filters['json'] = json.dumps
   template = env.get_template('bootstrap.js.tmpl')
-  templateData = {
-    'hasChrome': hasChrome,
-    'hasChromeRequires': hasChromeRequires,
-    'hasUnrequires': hasUnrequires,
-    'chromeWindows': chromeWindows,
-    'requires': requires,
-    'metadata': params['metadata'],
-  }
   files['bootstrap.js'] = processFile('bootstrap.js', template.render(templateData).encode('utf-8'), params)
 
 def signFiles(files, keyFile):
diff --git a/prefs.js b/prefs.js
index 06761b9..50c65f3 100644
--- a/prefs.js
+++ b/prefs.js
@@ -98,6 +98,7 @@ let Prefs = exports.Prefs =
     {
       this.branch.QueryInterface(Ci.nsIPrefBranch2)
                  .addObserver("", this, true);
+      onShutdown.add((function() this.branch.removeObserver("", this)).bind(this));
     }
     catch (e)
     {
@@ -123,23 +124,6 @@ let Prefs = exports.Prefs =
     }
   },
 
-  shutdown: function()
-  {
-    if (!this.branch)
-      return;
-
-    try
-    {
-      this.branch.QueryInterface(Ci.nsIPrefBranch2)
-                 .removeObserver("", this);
-    }
-    catch (e)
-    {
-      Cu.reportError(e);
-    }
-    this.branch = null;
-  },
-
   observe: function(subject, topic, data)
   {
     if (this.ignorePrefChanges || topic != "nsPref:changed")
diff --git a/windowObserver.js b/windowObserver.js
index 4bd23b0..ec346ba 100644
--- a/windowObserver.js
+++ b/windowObserver.js
@@ -11,34 +11,47 @@ const Cu = Components.utils;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-let WindowObserver = exports.WindowObserver =
+exports.WindowObserver = WindowObserver;
+
+/**
+ * This class will call listener's method applyToWindow() for all new chrome
+ * windows being opened. It will also call listener's method removeFromWindow()
+ * for all windows still open when the extension is shut down.
+ * @constructor
+ */
+function WindowObserver(/**Object*/ listener)
 {
-  listener: null,
+  this._listener  = listener;
 
-  init: function(listener)
-  {
-    if (this.listener)
-      return;
-    this.listener = listener;
+  let e = Services.ww.getWindowEnumerator();
+  while (e.hasMoreElements())
+    this._listener.applyToWindow(e.getNext().QueryInterface(Ci.nsIDOMWindow));
 
+  Services.ww.registerNotification(this);
+
+  this._shutdownHandler = function()
+  {
     let e = Services.ww.getWindowEnumerator();
     while (e.hasMoreElements())
-      this.listener.applyToWindow(e.getNext().QueryInterface(Ci.nsIDOMWindow));
+      this._listener.removeFromWindow(e.getNext().QueryInterface(Ci.nsIDOMWindow));
 
-    Services.ww.registerNotification(this);
-  },
+    Services.ww.unregisterNotification(this);
+  }.bind(this);
+  onShutdown.add(this._shutdownHandler);
+}
+WindowObserver.prototype =
+{
+  _listener: null,
+  _shutdownHandler: null,
 
   shutdown: function()
   {
-    if (!this.listener)
+    if (!this._shutdownHandler)
       return;
 
-    let e = Services.ww.getWindowEnumerator();
-    while (e.hasMoreElements())
-      this.listener.removeFromWindow(e.getNext().QueryInterface(Ci.nsIDOMWindow));
-
-    Services.ww.unregisterNotification(this);
-    this.listener = null;
+    onShutdown.remove(this._shutdownHandler);
+    this._shutdownHandler();
+    this._shutdownHandler = null;
   },
 
   observe: function(subject, topic, data)
@@ -48,8 +61,8 @@ let WindowObserver = exports.WindowObserver =
       let window = subject.QueryInterface(Ci.nsIDOMWindow);
       window.addEventListener("DOMContentLoaded", function()
       {
-        if (this.listener)
-          this.listener.applyToWindow(window);
+        if (this._shutdownHandler)
+          this._listener.applyToWindow(window);
       }.bind(this), false);
     }
   },

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git



More information about the Pkg-mozext-commits mailing list