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; |
Wladimir Palant
2012/11/09 08:26:15
No, this flag should only be set once the user mak
|
+ |
+ return false; |
Wladimir Palant
2012/11/09 08:26:15
This line is unnecessary - if you remove it we wil
|
+ } |
+ |
+ 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; |
+ } |
+} |