Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/typoAppIntegration.js

Issue 8559070: Integrated URL Fixer into Adblock Plus (Closed)
Patch Set: Added ability to opt-in and opt-out Created Oct. 19, 2012, 9:14 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/main.js ('k') | lib/typoCollector.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/typoAppIntegration.js
===================================================================
new file mode 100644
--- /dev/null
+++ b/lib/typoAppIntegration.js
@@ -0,0 +1,353 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+let {hook} = require("hooks");
+let {application, addonName} = require("info");
+
+let functionHooks = new WeakMap();
+
+exports.removeFromWindow = function(window)
+{
+ if (functionHooks.has(window))
+ {
+ let unhook = functionHooks.get(window);
+ unhook();
+ functionHooks.delete(window);
+ }
+};
+
+switch (addonName)
+{
+ case "url-fixer":
+ {
+ // URL Fixer
+ exports.isTypoCorrectionEnabled = function(window, prefix, domain, suffix) true;
+
+ break;
+ }
+ case "adblockplus":
+ {
+ // Adblock Plus
+ exports.isTypoCorrectionEnabled = function(window, prefix, domain, suffix)
+ {
+ let {Prefs} = require("prefs");
+
+ if (!Prefs.correctTyposAsk && !Prefs.correctTypos)
+ {
+ let {Utils} = require("utils");
+ let message = Utils.getString("typo_optin_message").replace(/\?1\?/, domain);
+ let yes = Utils.getString("typo_optin_yes");
+ let no = Utils.getString("typo_optin_no");
+ let buttons = [
+ {
+ label: yes,
+ accessKey: null,
+ callback: function()
+ {
+ // Yes: Enable typo correction
+ Prefs.correctTypos = true;
+
+ exports.loadURI(window, prefix + domain + suffix);
+ }
+ },
+ {
+ label: no,
+ accessKey: null,
+ callback: function()
+ {
+ // No: Do nothing
+ }
+ }
+ ];
+ // We need to have persistence being set to 1 due to redirect which happens afterwards
+ exports.openInfobar(window, "adblockplus-infobar-correct-typos-ask", message, buttons, 1);
+
+ Prefs.correctTyposAsk = true;
+
+ return false;
+ }
+
+ return Prefs.correctTypos;
+ };
+
+ break;
+ }
+}
+
+switch (application)
+{
+ case "firefox":
+ {
+ // Firefox
+ exports.isKnownWindow = function(window) window.document.documentElement.getAttribute("windowtype") == "navigator:browser";
+
+ exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null;
+
+ exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null;
+
+ exports.applyToWindow = function(window, corrector)
+ {
+ let urlbar = exports.getURLBar(window);
+ if (urlbar && urlbar.handleCommand && !functionHooks.has(window))
+ {
+ // Handle new URLs being entered
+ let unhook = hook(urlbar, "handleCommand", function()
+ {
+ let correction = corrector(window, urlbar.value);
+ if (correction)
+ urlbar.value = correction;
+ });
+ functionHooks.set(window, unhook);
+ }
+ };
+
+ exports.openInfobar = function(window, id, message, buttons, persistence)
+ {
+ let browser = exports.getBrowser(window);
+ let infobar = browser.getNotificationBox();
+ let notification = infobar.getNotificationWithValue(id);
+
+ if (notification)
+ {
+ infobar.removeNotification(notification);
+ }
+ notification = infobar.appendNotification(
+ message,
+ id,
+ "chrome://" + addonName + "/skin/icon16.png",
+ infobar.PRIORITY_INFO_HIGH,
+ buttons
+ );
+ notification.persistence = persistence;
+ };
+
+ exports.loadURI = function(window, uri)
+ {
+ exports.getBrowser(window).loadURI(uri);
+ };
+
+ break;
+ }
+ case "seamonkey":
+ {
+ let eventListeners = new WeakMap();
+
+ // SeaMonkey
+ exports.isKnownWindow = function(window) window.document.documentElement.getAttribute("windowtype") == "navigator:browser";
+
+ exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null;
+
+ exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null;
+
+ exports.applyToWindow = function(window, corrector)
+ {
+ let urlbar = exports.getURLBar(window);
+ let goButton = window.document.getElementById("go-button-container");
+
+ if (urlbar && urlbar._fireEvent && !functionHooks.has(window))
+ {
+ function correctURL()
+ {
+ let correction = corrector(window, urlbar.value);
+ if (correction)
+ urlbar.value = correction;
+ }
+
+ let unhook = hook(urlbar, "_fireEvent", function(eventType)
+ {
+ if (eventType == "textentered")
+ {
+ correctURL();
+ }
+ });
+ functionHooks.set(window, unhook);
+
+ if (goButton)
+ {
+ goButton.addEventListener("command", correctURL, true);
+ eventListeners.set(window, {
+ "listener": correctURL,
+ "element": goButton
+ });
+ }
+ }
+ };
+
+ let basicRemove = exports.removeFromWindow;
+ exports.removeFromWindow = function(window)
+ {
+ basicRemove(window);
+
+ if (eventListeners.has(window))
+ {
+ let eventListener = eventListeners.get(window);
+ eventListener.element.removeEventListener("command", eventListener.listener, true);
+ eventListeners.delete(window);
+ }
+ };
+
+ exports.openInfobar = function(window, id, message, buttons, persistence)
+ {
+ let browser = exports.getBrowser(window);
+ let infobar = browser.getNotificationBox();
+ let notification = infobar.getNotificationWithValue(id);
+
+ if (notification)
+ {
+ infobar.removeNotification(notification);
+ }
+
+ notification = infobar.appendNotification(
+ message,
+ id,
+ "chrome://" + addonName + "/skin/icon16.png",
+ infobar.PRIORITY_INFO_HIGH,
+ buttons
+ );
+ notification.persistence = persistence;
+ };
+
+ exports.loadURI = function(window, uri)
+ {
+ exports.getBrowser(window).loadURI(uri);
+ };
+
+ break;
+ }
+ case "fennec":
+ {
+ // XUL Fennec
+ exports.isKnownWindow = function(window) window.document.documentElement.getAttribute("windowtype") == "navigator:browser";
+
+ exports.getURLBar = function(window) null;
+
+ exports.getBrowser = function(window) null;
+
+ exports.applyToWindow = function(window, corrector)
+ {
+ if ("BrowserUI" in window && window.BrowserUI.goToURI && !functionHooks.has(window))
+ {
+ // Handle new URLs being entered
+ let unhook = hook(window.BrowserUI, "goToURI", function(url)
+ {
+ url = url || this._edit.value;
+
+ let correction = corrector(window, url);
+ if (correction)
+ url = correction;
+
+ return [url];
+ });
+ functionHooks.set(window, unhook);
+ }
+ };
+
+ exports.openInfobar = function(window, id, message, buttons, persistence)
+ {
+ if ("getNotificationBox" in window)
+ {
+ let infobar = window.getNotificationBox();
+ let notification = infobar.getNotificationWithValue(id);
+
+ if (notification)
+ {
+ infobar.removeNotification(notification);
+ }
+
+ notification = infobar.appendNotification(
+ message,
+ id,
+ "chrome://" + addonName + "/skin/icon16.png",
+ infobar.PRIORITY_INFO_HIGH,
+ buttons
+ );
+ notification.persistence = persistence;
+ }
+ };
+
+ exports.loadURI = function(window, uri)
+ {
+ if ("BrowserUI" in window && "goToURI" in window.BrowserUI)
+ {
+ window.BrowserUI.goToURI(uri);
+ }
+ };
+
+ break;
+ }
+ case "fennec2":
+ {
+ // Native Fennec
+ exports.isKnownWindow = function(window) window.document.documentElement.getAttribute("windowtype") == "navigator:browser";
+
+ exports.getURLBar = function(window) null;
+
+ exports.getBrowser = function(window) null;
+
+ exports.applyToWindow = function(window, corrector)
+ {
+ if ("BrowserApp" in window && window.BrowserApp.observe && !functionHooks.has(window))
+ {
+ let innerUnhook = null;
+ function cleanup()
+ {
+ if (innerUnhook)
+ innerUnhook();
+
+ innerUnhook = null;
+ }
+
+ let unhook = hook(window.BrowserApp, "observe", function(subject, topic, data)
+ {
+ // Huge hack: we replace addTab/loadURI when the observer is
+ // triggered. This seems to be the only way to know that the calls
+ // originate from user input.
+ let method = null;
+ if (topic == "Tab:Add")
+ method = "addTab";
+ else if (topic == "Tab:Load")
+ method = "loadURI";
+
+ if (method)
+ {
+ innerUnhook = hook(this, method, function()
+ {
+ let params = Array.prototype.slice.apply(arguments);
+ let correction = corrector(window, params[0]);
+ if (correction)
+ params[0] = correction;
+ return params;
+ });
+ }
+ }, cleanup);
+ functionHooks.set(window, unhook);
+ }
+ };
+
+ exports.openInfobar = function(window, id, message, buttons, persistence)
+ {
+ if ("BrowserApp" in window && "selectedTab" in window.BrowserApp)
+ {
+ window.NativeWindow.doorhanger.show(message, id, buttons, window.BrowserApp.selectedTab.id,
+ {
+ persistence: persistence
+ }
+ );
+ }
+ };
+
+ exports.loadURI = function(window, uri)
+ {
+ if ("BrowserApp" in window && "loadURI" in window.BrowserApp)
+ window.BrowserApp.loadURI(uri);
+ };
+
+ break;
+ }
+ default:
+ {
+ exports.isKnownWindow = function(window) false;
+ break;
+ }
+}
« no previous file with comments | « lib/main.js ('k') | lib/typoCollector.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld