aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/main.js24
-rw-r--r--lib/persistent-page-mod.js56
-rw-r--r--lib/unload-2.js72
3 files changed, 141 insertions, 11 deletions
diff --git a/lib/main.js b/lib/main.js
index 608f820..cd4de54 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -1,15 +1,17 @@
-// access context menu API
-jetpack.future.import("menu");
-jetpack.future.import("clipboard");
-
-/*
-I love me some pageMods, but right now there are multiple-invocations issues
-
-jetpack.future.import("pageMods");
+exports.main = function(options, callback) {
+ require("tab-browser").whenContentLoaded(
+ function(window) {
+ if (window.location.protocol == "https" &&
+ /bugzilla(-[a-zA-Z]+)*\.mozilla\.org/.test(window.location.href)) {
+ require("persistent-page-mod").register(window, function() {
+ tweakBugzilla(window.document);
+ });
+ }
+ }
+ );
+};
-jetpack.pageMods.add(function(d) {
-*/
-jetpack.tabs.onReady(function(d) {
+function tweakBugzilla(d) {
// run on both bugzilla.m.o and bugzilla-stage-tip.m.o
if (!/bugzilla(-[a-zA-Z]+)*\.mozilla\.org/.test(d.location.href))
return;
diff --git a/lib/persistent-page-mod.js b/lib/persistent-page-mod.js
new file mode 100644
index 0000000..5c00a8f
--- /dev/null
+++ b/lib/persistent-page-mod.js
@@ -0,0 +1,56 @@
+var timer = require("timer");
+
+function PersistentPageMod(window, callback) {
+ memory.track(this);
+ this.window = window;
+ this.callback = callback;
+ this.window.addEventListener("unload", this, false);
+ this.window.addEventListener("DOMSubtreeModified", this, false);
+ this.doMod();
+ require("unload-2").ensure(this);
+}
+
+PersistentPageMod.prototype = {
+ REPLACE_DELAY: 100,
+ doMod: function doMod() {
+ try {
+ this.callback.call(undefined, this.window);
+ } catch (e) {
+ console.exception(e);
+ }
+ this.timerID = null;
+ },
+ handleEvent: function handleEvent(event) {
+ switch (event.type) {
+ case "unload":
+ if (event.target == this.window.document)
+ this.unload();
+ break;
+ case "DOMSubtreeModified":
+ if (this.timerID == null) {
+ // Wait a bit to do the replacing. Otherwise, we just get called
+ // tons of times in a tiny period and end up hanging the browser
+ // for a while.
+ var self = this;
+ this.timerID = timer.setTimeout(function() self.doMod(),
+ this.REPLACE_DELAY);
+ }
+ break;
+ }
+ },
+ unload: function unload() {
+ if (this.timerID != null) {
+ timer.clearTimeout(this.timerID);
+ this.timerID = null;
+ }
+ this.window.removeEventListener("DOMSubtreeModified", this, false);
+ this.window.removeEventListener("unload", this, false);
+ }
+};
+
+require("errors").catchAndLogProps(PersistentPageMod.prototype,
+ "handleEvent");
+
+var register = exports.register = function register(window, callback) {
+ new PersistentPageMod(window, callback);
+};
diff --git a/lib/unload-2.js b/lib/unload-2.js
new file mode 100644
index 0000000..c4cbdcb
--- /dev/null
+++ b/lib/unload-2.js
@@ -0,0 +1,72 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Jetpack.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Atul Varma <atul@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// TODO: Consider adding all this to the unload module.
+
+var unloaders = [];
+
+var addMethod = exports.addMethod = function addMethod(obj, unloader) {
+ var called = false;
+
+ function unloadWrapper() {
+ if (!called) {
+ called = true;
+ var index = unloaders.indexOf(unloadWrapper);
+ if (index == -1)
+ throw new Error("assertion failure");
+ unloaders.splice(index, 1);
+ unloader.apply(obj, []);
+ }
+ };
+
+ unloaders.push(unloadWrapper);
+ obj.unload = unloadWrapper;
+};
+
+var ensure = exports.ensure = function ensure(obj) {
+ if (!("unload" in obj))
+ throw new Error("object has no 'unload' property");
+
+ addMethod(obj, obj.unload);
+};
+
+require("unload").when(
+ function() {
+ unloaders.slice().forEach(
+ function(unloadWrapper) {
+ unloadWrapper();
+ });
+ });