| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of the URL Fixer, | 2 * This file is part of the URL Fixer, |
| 3 * Copyright (C) 2006-2012 Eyeo GmbH | 3 * Copyright (C) 2006-2012 Eyeo GmbH |
| 4 * | 4 * |
| 5 * URL Fixer is free software: you can redistribute it and/or modify | 5 * URL Fixer is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * URL Fixer is distributed in the hope that it will be useful, | 9 * URL Fixer is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
| 15 * along with URL Fixer. If not, see <http://www.gnu.org/licenses/>. | 15 * along with URL Fixer. If not, see <http://www.gnu.org/licenses/>. |
| 16 */ | 16 */ |
| 17 | 17 |
| 18 Cu.import("resource://gre/modules/Services.jsm"); | 18 Cu.import("resource://gre/modules/Services.jsm"); |
| 19 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); | 19 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
| 20 | 20 |
| 21 let {Prefs} = require("prefs"); | 21 let {Prefs} = require("prefs"); |
| 22 let {WindowObserver} = require("windowObserver"); | 22 let {WindowObserver} = require("windowObserver"); |
| 23 let {getSchemeCorrection, isKnownScheme, getDomainCorrection, getDomainReferral,
onWhitelistEntryRemoved} = require("typoRules"); | 23 let {getSchemeCorrection, isKnownScheme, getDomainCorrection, getDomainReferral,
onWhitelistEntryAdded} = require("typoRules"); |
| 24 let {processTypedDomain, processDomainCorrection, | 24 let {processTypedDomain, processDomainCorrection, processFalsePositive} = requir
e("typoCollector"); |
| 25 processUserCorrection, processFalsePositive} = require("typedItCollector"); | |
| 26 let appIntegration = require("typoAppIntegration"); | 25 let appIntegration = require("typoAppIntegration"); |
| 26 let netError = require("typoNetError"); |
| 27 | 27 |
| 28 // Attach our handlers to all browser windows | 28 let typoWindowObserver = null; |
| 29 new WindowObserver( | 29 |
| 30 exports.attachWindowObserver = attachWindowObserver; |
| 31 function attachWindowObserver() |
| 30 { | 32 { |
| 31 applyToWindow: function(window) | 33 if (typoWindowObserver) |
| 32 { | 34 return; |
| 33 if (!appIntegration.isKnownWindow(window)) | 35 |
| 34 return; | 36 // Attach our handlers to all browser windows |
| 37 typoWindowObserver = new WindowObserver({ |
| 38 applyToWindow: function(window) |
| 39 { |
| 40 if (!appIntegration.isKnownWindow(window)) |
| 41 return; |
| 42 |
| 43 appIntegration.applyToWindow(window, correctURL); |
| 44 }, |
| 35 | 45 |
| 36 let browser = appIntegration.getBrowser(window); | 46 removeFromWindow: function(window) |
| 37 if (browser) | 47 { |
| 38 browser.addEventListener("DOMContentLoaded", handlePageLoad, false); | 48 if (!appIntegration.isKnownWindow(window)) |
| 49 return; |
| 50 |
| 51 appIntegration.removeFromWindow(window); |
| 52 } |
| 53 }); |
| 54 } |
| 55 attachWindowObserver(); |
| 39 | 56 |
| 40 appIntegration.applyToWindow(window, correctURL); | 57 exports.detachWindowObserver = detachWindowObserver; |
| 41 }, | 58 function detachWindowObserver() |
| 42 | |
| 43 removeFromWindow: function(window) | |
| 44 { | |
| 45 if (!appIntegration.isKnownWindow(window)) | |
| 46 return; | |
| 47 | |
| 48 let browser = appIntegration.getBrowser(window); | |
| 49 if (browser) | |
| 50 { | |
| 51 browser.removeEventListener("DOMContentLoaded", handlePageLoad, false); | |
| 52 if (browser.browsers) | |
| 53 { | |
| 54 for (let i = 0; i < browser.browsers.length; i++) | |
| 55 { | |
| 56 let contentWnd = browser.browsers[i].contentWindow; | |
| 57 if (contentWnd.document.documentURI.indexOf("about:neterror?") == 0) | |
| 58 removeFromNetErrorPage(contentWnd); | |
| 59 } | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 appIntegration.removeFromWindow(window); | |
| 64 } | |
| 65 }); | |
| 66 | |
| 67 // Load HTML code to add to network error pages | |
| 68 let netErrorOverlay = null; | |
| 69 let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.ns
IXMLHttpRequest); | |
| 70 request.open("GET", "chrome://url-fixer/content/netError.xhtml"); | |
| 71 request.addEventListener("load", function(event) | |
| 72 { | 59 { |
| 73 netErrorOverlay = event.target.responseXML; | 60 if (!typoWindowObserver) |
| 74 }, false); | |
| 75 request.send(null) | |
| 76 | |
| 77 function handlePageLoad(event) | |
| 78 { | |
| 79 let document = event.target; | |
| 80 if (document.documentURI.indexOf("about:neterror?") != 0 || | |
| 81 document.documentURI.indexOf("e=netOffline") > 0 || | |
| 82 document.documentURI.indexOf("e=notCached") > 0) | |
| 83 { | |
| 84 return; | 61 return; |
| 85 } | 62 |
| 86 | 63 // Detach our handlers from all browser windows |
| 87 if (!netErrorOverlay || document.getElementById("url-fixer-section")) | 64 typoWindowObserver.shutdown(); |
| 88 return; | 65 typoWindowObserver = null; |
| 89 | |
| 90 let container = document.getElementById("errorPageContainer"); | |
| 91 if (!container) | |
| 92 return; | |
| 93 | |
| 94 container.appendChild(netErrorOverlay.documentElement.cloneNode(true)); | |
| 95 | |
| 96 let textField = document.getElementById("url-fixer-intention"); | |
| 97 textField.value = document.defaultView.location.href; | |
| 98 | |
| 99 let retryButton = document.getElementById("url-fixer-retry"); | |
| 100 retryButton.addEventListener("click", function() | |
| 101 { | |
| 102 let newURL = textField.value.replace(/^\s+/, "").replace(/\s+$/, ""); | |
| 103 if (!newURL.length) | |
| 104 return; | |
| 105 | |
| 106 let [prefix, newHost, suffix] = parseURL(newURL); | |
| 107 let oldHost = document.defaultView.location.hostname.toLowerCase(); | |
| 108 | |
| 109 processUserCorrection(oldHost, newHost); | |
| 110 | |
| 111 if (newHost.indexOf("www.") == 0 && oldHost.indexOf("www.") == 0) | |
| 112 { | |
| 113 // Ignore www. prefix if they both start with it | |
| 114 newHost = newHost.substr(4); | |
| 115 oldHost = oldHost.substr(4); | |
| 116 } | |
| 117 if (oldHost && newHost != oldHost) | |
| 118 { | |
| 119 Prefs.custom_replace[oldHost] = newHost; | |
| 120 Prefs.custom_replace = JSON.parse(JSON.stringify(Prefs.custom_replace)); | |
| 121 } | |
| 122 | |
| 123 // Remove from whitelist | |
| 124 if (oldHost in Prefs.whitelist) | |
| 125 { | |
| 126 delete Prefs.whitelist[oldHost]; | |
| 127 onWhitelistEntryRemoved(oldHost); | |
| 128 Prefs.whitelist = JSON.parse(JSON.stringify(Prefs.whitelist)); | |
| 129 } | |
| 130 | |
| 131 document.defaultView.location.replace(newURL); | |
| 132 }, false); | |
| 133 } | |
| 134 | |
| 135 function removeFromNetErrorPage(window) | |
| 136 { | |
| 137 let overlay = window.document.getElementById("url-fixer-section"); | |
| 138 if (overlay) | |
| 139 overlay.parentNode.removeChild(overlay); | |
| 140 } | 66 } |
| 141 | 67 |
| 142 function parseURL(url) | 68 function parseURL(url) |
| 143 { | 69 { |
| 144 if (/^\s*((?:\w+:)?\/*(?:[^\/#]*@)?)([^\/:#]*)/.test(url)) | 70 if (/^\s*((?:\w+:)?\/*(?:[^\/#]*@)?)([^\/:#]*)/.test(url)) |
| 145 return [RegExp.$1, RegExp.$2.toLowerCase(), RegExp.rightContext]; | 71 return [RegExp.$1, RegExp.$2.toLowerCase(), RegExp.rightContext]; |
| 146 else | 72 else |
| 147 return [url, null, null]; | 73 return [url, null, null]; |
| 148 } | 74 } |
| 149 | 75 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 suffix += "?" + referral; | 164 suffix += "?" + referral; |
| 239 } | 165 } |
| 240 | 166 |
| 241 suffix += anchor; | 167 suffix += anchor; |
| 242 } | 168 } |
| 243 } | 169 } |
| 244 } | 170 } |
| 245 | 171 |
| 246 if (!hasCorrection) | 172 if (!hasCorrection) |
| 247 return null; | 173 return null; |
| 174 |
| 175 if (!appIntegration.isTypoCorrectionEnabled(window, prefix, domain, suffix)) |
| 176 return null; |
| 248 | 177 |
| 249 // Show infobar to inform and ask about correction | 178 // Show infobar to inform and ask about correction |
| 250 let [message, yes, no] = getInfobarTexts(); | 179 let [message, yes, no] = getInfobarTexts(); |
| 251 message = message.replace(/\?1\?/g, prefix+domain); | 180 message = message.replace(/\?1\?/g, prefix+domain); |
| 252 let buttons = [ | 181 let buttons = [ |
| 253 { | 182 { |
| 254 label: yes, | 183 label: yes, |
| 255 accessKey: null, | 184 accessKey: null, |
| 256 callback: function() | 185 callback: function() |
| 257 { | 186 { |
| 258 // Yes: Do nothing | 187 // Yes: Do nothing |
| 259 } | 188 } |
| 260 }, | 189 }, |
| 261 { | 190 { |
| 262 label: no, | 191 label: no, |
| 263 accessKey: null, | 192 accessKey: null, |
| 264 callback: function() | 193 callback: function() |
| 265 { | 194 { |
| 266 // No: Add to list of corrections (ignore) | 195 // No: Add to list of corrections (ignore) |
| 267 let {onWhitelistEntryAdded} = require("typoRules"); | |
| 268 let entry = oldDomain.replace(/^www\./, ""); | 196 let entry = oldDomain.replace(/^www\./, ""); |
| 269 Prefs.whitelist[entry] = true; | 197 Prefs.whitelist[entry] = true; |
| 270 onWhitelistEntryAdded(entry); | 198 onWhitelistEntryAdded(entry); |
| 271 Prefs.whitelist = JSON.parse(JSON.stringify(Prefs.whitelist)); | 199 Prefs.whitelist = JSON.parse(JSON.stringify(Prefs.whitelist)); |
| 272 | 200 |
| 273 appIntegration.loadURI(window, value); | 201 appIntegration.loadURI(window, value); |
| 274 processFalsePositive(domain, oldDomain); | 202 processFalsePositive(domain, oldDomain); |
| 275 } | 203 } |
| 276 } | 204 } |
| 277 ]; | 205 ]; |
| 278 // We need to have persistence being set to 1 due to redirect which happens af
terwards | 206 // We need to have persistence being set to 1 due to redirect which happens af
terwards |
| 279 appIntegration.openInfobar(window, "url-fixer-infobar-askafter", message, butt
ons, 1); | 207 appIntegration.openInfobar(window, require("info").addonName + "-infobar-askaf
ter", message, buttons, 1); |
| 280 | 208 |
| 281 require("survey").incrementCorrectionsCounter(); | 209 require("typoSurvey").incrementCorrectionsCounter(); |
| 282 | 210 |
| 283 return prefix + domain + suffix; | 211 return prefix + domain + suffix; |
| 284 } | 212 } |
| 285 | 213 |
| 286 let stringBundle = null; | 214 let stringBundle = null; |
| 287 | 215 |
| 288 function getInfobarTexts() | 216 function getInfobarTexts() |
| 289 { | 217 { |
| 290 // Randomize URI to work around bug 719376 | 218 // Randomize URI to work around bug 719376 |
| 291 if (!stringBundle) | 219 if (!stringBundle) |
| 292 stringBundle = Services.strings.createBundle("chrome://url-fixer/locale/typo
.properties?" + Math.random()); | 220 stringBundle = Services.strings.createBundle("chrome://" + require("info").a
ddonName + "/locale/typo.properties?" + Math.random()); |
| 293 let result = [ | 221 let result = [ |
| 294 stringBundle.GetStringFromName("urlfixer.isItCorrect"), | 222 stringBundle.GetStringFromName("urlfixer.isItCorrect"), |
| 295 stringBundle.GetStringFromName("urlfixer.yes"), | 223 stringBundle.GetStringFromName("urlfixer.yes"), |
| 296 stringBundle.GetStringFromName("urlfixer.no") | 224 stringBundle.GetStringFromName("urlfixer.no") |
| 297 ]; | 225 ]; |
| 298 | 226 |
| 299 getInfobarTexts = function() result; | 227 getInfobarTexts = function() result; |
| 300 return getInfobarTexts(); | 228 return getInfobarTexts(); |
| 301 } | 229 } |
| OLD | NEW |