diff options
Diffstat (limited to 'data/extensions/spyblock@gnu.org/lib/windowObserver.js')
-rw-r--r-- | data/extensions/spyblock@gnu.org/lib/windowObserver.js | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/data/extensions/spyblock@gnu.org/lib/windowObserver.js b/data/extensions/spyblock@gnu.org/lib/windowObserver.js new file mode 100644 index 0000000..eb0b13a --- /dev/null +++ b/data/extensions/spyblock@gnu.org/lib/windowObserver.js @@ -0,0 +1,112 @@ +/* + * This file is part of the Adblock Plus build tools, + * Copyright (C) 2006-2014 Eyeo GmbH + * + * Adblock Plus is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Adblock Plus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. + */ + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +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. + * @param {Object} listener + * @param {String} [when] when to execute applyToWindow(). "start" means immediately + * when the window opens, "ready" when its contents are available + * and "end" (default) means to wait until the "load" event. + * @constructor + */ +function WindowObserver(listener, when) +{ + this._listener = listener; + this._when = when; + + let windows = []; + let e = Services.wm.getZOrderDOMWindowEnumerator(null, true); + while (e.hasMoreElements()) + windows.push(e.getNext()); + + // Check if there are any windows that we missed + let eAll = Services.ww.getWindowEnumerator(); + while (eAll.hasMoreElements()) + { + let element = eAll.getNext(); + if (windows.indexOf(element) < 0) + windows.push(element); + } + + for (let i = 0; i < windows.length; i++) + { + let window = windows[i].QueryInterface(Ci.nsIDOMWindow); + if (when == "start" || window.document.readyState == "complete") + this._listener.applyToWindow(window); + else + this.observe(window, "chrome-document-global-created", null); + } + + Services.obs.addObserver(this, "chrome-document-global-created", true); + + this._shutdownHandler = function() + { + let e = Services.ww.getWindowEnumerator(); + while (e.hasMoreElements()) + this._listener.removeFromWindow(e.getNext().QueryInterface(Ci.nsIDOMWindow)); + + Services.obs.removeObserver(this, "chrome-document-global-created"); + }.bind(this); + onShutdown.add(this._shutdownHandler); +} +WindowObserver.prototype = +{ + _listener: null, + _when: null, + _shutdownHandler: null, + + shutdown: function() + { + if (!this._shutdownHandler) + return; + + onShutdown.remove(this._shutdownHandler); + this._shutdownHandler(); + this._shutdownHandler = null; + }, + + observe: function(subject, topic, data) + { + if (topic == "chrome-document-global-created") + { + let window = subject.QueryInterface(Ci.nsIDOMWindow); + if (this._when == "start") + { + this._listener.applyToWindow(window); + return; + } + + let event = (this._when == "ready" ? "DOMContentLoaded" : "load"); + let listener = function() + { + window.removeEventListener(event, listener, false); + if (this._shutdownHandler) + this._listener.applyToWindow(window); + }.bind(this); + window.addEventListener(event, listener, false); + } + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObserver]) +}; |