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) |
| 34 return; |
| 35 |
| 36 // Attach our handlers to all browser windows |
| 37 typoWindowObserver = new WindowObserver( |
32 { | 38 { |
33 if (!appIntegration.isKnownWindow(window)) | 39 applyToWindow: function(window) |
34 return; | 40 { |
| 41 if (!appIntegration.isKnownWindow(window)) |
| 42 return; |
| 43 |
| 44 netError.applyToWindow(window); |
| 45 appIntegration.applyToWindow(window, correctURL); |
| 46 }, |
35 | 47 |
36 let browser = appIntegration.getBrowser(window); | 48 removeFromWindow: function(window) |
37 if (browser) | 49 { |
38 browser.addEventListener("DOMContentLoaded", handlePageLoad, false); | 50 if (!appIntegration.isKnownWindow(window)) |
| 51 return; |
| 52 |
| 53 netError.removeFromWindow(window); |
| 54 appIntegration.removeFromWindow(window); |
| 55 } |
| 56 }); |
| 57 } |
| 58 attachWindowObserver(); |
39 | 59 |
40 appIntegration.applyToWindow(window, correctURL); | 60 exports.detachWindowObserver = detachWindowObserver; |
41 }, | 61 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 { | 62 { |
73 netErrorOverlay = event.target.responseXML; | 63 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; | 64 return; |
85 } | 65 |
86 | 66 // Detach our handlers from all browser windows |
87 if (!netErrorOverlay || document.getElementById("url-fixer-section")) | 67 typoWindowObserver.shutdown(); |
88 return; | 68 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 } | 69 } |
141 | 70 |
142 function parseURL(url) | 71 function parseURL(url) |
143 { | 72 { |
144 if (/^\s*((?:\w+:)?\/*(?:[^\/#]*@)?)([^\/:#]*)/.test(url)) | 73 if (/^\s*((?:\w+:)?\/*(?:[^\/#]*@)?)([^\/:#]*)/.test(url)) |
145 return [RegExp.$1, RegExp.$2.toLowerCase(), RegExp.rightContext]; | 74 return [RegExp.$1, RegExp.$2.toLowerCase(), RegExp.rightContext]; |
146 else | 75 else |
147 return [url, null, null]; | 76 return [url, null, null]; |
148 } | 77 } |
149 | 78 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 suffix += "?" + referral; | 167 suffix += "?" + referral; |
239 } | 168 } |
240 | 169 |
241 suffix += anchor; | 170 suffix += anchor; |
242 } | 171 } |
243 } | 172 } |
244 } | 173 } |
245 | 174 |
246 if (!hasCorrection) | 175 if (!hasCorrection) |
247 return null; | 176 return null; |
| 177 |
| 178 if (!appIntegration.isTypoCorrectionEnabled(window, prefix, domain, suffix)) |
| 179 return null; |
248 | 180 |
249 // Show infobar to inform and ask about correction | 181 // Show infobar to inform and ask about correction |
250 let [message, yes, no] = getInfobarTexts(); | 182 let [message, yes, no] = getInfobarTexts(); |
251 message = message.replace(/\?1\?/g, prefix+domain); | 183 message = message.replace(/\?1\?/g, prefix+domain); |
252 let buttons = [ | 184 let buttons = [ |
253 { | 185 { |
254 label: yes, | 186 label: yes, |
255 accessKey: null, | 187 accessKey: null, |
256 callback: function() | 188 callback: function() |
257 { | 189 { |
258 // Yes: Do nothing | 190 // Yes: Do nothing |
259 } | 191 } |
260 }, | 192 }, |
261 { | 193 { |
262 label: no, | 194 label: no, |
263 accessKey: null, | 195 accessKey: null, |
264 callback: function() | 196 callback: function() |
265 { | 197 { |
266 // No: Add to list of corrections (ignore) | 198 // No: Add to list of corrections (ignore) |
267 let {onWhitelistEntryAdded} = require("typoRules"); | |
268 let entry = oldDomain.replace(/^www\./, ""); | 199 let entry = oldDomain.replace(/^www\./, ""); |
269 Prefs.whitelist[entry] = true; | 200 Prefs.whitelist[entry] = true; |
270 onWhitelistEntryAdded(entry); | 201 onWhitelistEntryAdded(entry); |
271 Prefs.whitelist = JSON.parse(JSON.stringify(Prefs.whitelist)); | 202 Prefs.whitelist = JSON.parse(JSON.stringify(Prefs.whitelist)); |
272 | 203 |
273 appIntegration.loadURI(window, value); | 204 appIntegration.loadURI(window, value); |
274 processFalsePositive(domain, oldDomain); | 205 processFalsePositive(domain, oldDomain); |
275 } | 206 } |
276 } | 207 } |
277 ]; | 208 ]; |
278 // We need to have persistence being set to 1 due to redirect which happens af
terwards | 209 // 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); | 210 appIntegration.openInfobar(window, require("info").addonName + "-infobar-askaf
ter", message, buttons, 1); |
280 | 211 |
281 require("survey").incrementCorrectionsCounter(); | 212 require("typoSurvey").incrementCorrectionsCounter(); |
282 | 213 |
283 return prefix + domain + suffix; | 214 return prefix + domain + suffix; |
284 } | 215 } |
285 | 216 |
286 let stringBundle = null; | 217 let stringBundle = null; |
287 | 218 |
288 function getInfobarTexts() | 219 function getInfobarTexts() |
289 { | 220 { |
290 // Randomize URI to work around bug 719376 | 221 // Randomize URI to work around bug 719376 |
291 if (!stringBundle) | 222 if (!stringBundle) |
292 stringBundle = Services.strings.createBundle("chrome://url-fixer/locale/typo
.properties?" + Math.random()); | 223 stringBundle = Services.strings.createBundle("chrome://" + require("info").a
ddonName + "/locale/typo.properties?" + Math.random()); |
293 let result = [ | 224 let result = [ |
294 stringBundle.GetStringFromName("urlfixer.isItCorrect"), | 225 stringBundle.GetStringFromName("urlfixer.isItCorrect"), |
295 stringBundle.GetStringFromName("urlfixer.yes"), | 226 stringBundle.GetStringFromName("urlfixer.yes"), |
296 stringBundle.GetStringFromName("urlfixer.no") | 227 stringBundle.GetStringFromName("urlfixer.no") |
297 ]; | 228 ]; |
298 | 229 |
299 getInfobarTexts = function() result; | 230 getInfobarTexts = function() result; |
300 return getInfobarTexts(); | 231 return getInfobarTexts(); |
301 } | 232 } |
OLD | NEW |