| OLD | NEW | 
| (Empty) |  | 
 |    1 /* This Source Code Form is subject to the terms of the Mozilla Public | 
 |    2  * License, v. 2.0. If a copy of the MPL was not distributed with this file, | 
 |    3  * You can obtain one at http://mozilla.org/MPL/2.0/. */ | 
 |    4  | 
 |    5 Cu.import("resource://gre/modules/Services.jsm"); | 
 |    6 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); | 
 |    7  | 
 |    8 let {Prefs} = require("prefs"); | 
 |    9 let {WindowObserver} = require("windowObserver"); | 
 |   10 let {getSchemeCorrection, isKnownScheme, getDomainCorrection, getDomainReferral,
      onWhitelistEntryAdded} = require("typoRules"); | 
 |   11 let {processTypedDomain, processDomainCorrection, processFalsePositive} = requir
     e("typoCollector"); | 
 |   12 let appIntegration = require("typoAppIntegration"); | 
 |   13 let netError = require("typoNetError"); | 
 |   14  | 
 |   15 // Attach our handlers to all browser windows | 
 |   16 new WindowObserver( | 
 |   17 { | 
 |   18   applyToWindow: function(window) | 
 |   19   { | 
 |   20     if (!appIntegration.isKnownWindow(window)) | 
 |   21       return; | 
 |   22      | 
 |   23     netError.applyToWindow(window); | 
 |   24     appIntegration.applyToWindow(window, correctURL); | 
 |   25   }, | 
 |   26  | 
 |   27   removeFromWindow: function(window) | 
 |   28   { | 
 |   29     if (!appIntegration.isKnownWindow(window)) | 
 |   30       return; | 
 |   31      | 
 |   32     netError.removeFromWindow(window); | 
 |   33     appIntegration.removeFromWindow(window); | 
 |   34   } | 
 |   35 }); | 
 |   36  | 
 |   37 function parseURL(url) | 
 |   38 { | 
 |   39   if (/^\s*((?:\w+:)?\/*(?:[^\/#]*@)?)([^\/:#]*)/.test(url)) | 
 |   40     return [RegExp.$1, RegExp.$2.toLowerCase(), RegExp.rightContext]; | 
 |   41   else | 
 |   42     return [url, null, null]; | 
 |   43 } | 
 |   44  | 
 |   45 function isIPAddress(domain) | 
 |   46 { | 
 |   47   try | 
 |   48   { | 
 |   49     Services.eTLD.getBaseDomainFromHost(domain); | 
 |   50     return false; | 
 |   51   } | 
 |   52   catch (e) | 
 |   53   { | 
 |   54     return (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS); | 
 |   55   } | 
 |   56 } | 
 |   57  | 
 |   58 function correctURL(window, value) | 
 |   59 { | 
 |   60   let hasCorrection = false; | 
 |   61  | 
 |   62   value = value.trim(); | 
 |   63   if (value.length == 0) | 
 |   64     return null; | 
 |   65  | 
 |   66   // Replace backslashes | 
 |   67   value = value.replace(/\\/g, "/"); | 
 |   68  | 
 |   69   // Does the URL scheme need correcting? | 
 |   70   if (/^([^\/]+)(\/.*)/.test(value)) | 
 |   71   { | 
 |   72     let scheme = RegExp.$1; | 
 |   73     let suffix = RegExp.$2; | 
 |   74     let correction = getSchemeCorrection(scheme) | 
 |   75     if (correction != scheme) | 
 |   76     { | 
 |   77       value = correction + suffix; | 
 |   78       hasCorrection = true; | 
 |   79     } | 
 |   80   } | 
 |   81  | 
 |   82   // Ignore URL schemes that we don't know | 
 |   83   if (/^([\w\-]+:)/.test(value) && !isKnownScheme(RegExp.$1)) | 
 |   84     return null; | 
 |   85  | 
 |   86   // Ignore search keywords and such | 
 |   87   if ("getShortcutOrURI" in window && window.getShortcutOrURI(value) != value) | 
 |   88     return null; | 
 |   89  | 
 |   90   // Spaces before the first slash or period is probably a quick search | 
 |   91   if (/^[^\/\.\s]+\s/.test(value)) | 
 |   92     return null; | 
 |   93  | 
 |   94   let [prefix, domain, suffix] = parseURL(value); | 
 |   95   if (!domain) | 
 |   96     return null; | 
 |   97  | 
 |   98   let oldDomain = domain; | 
 |   99   if (!isIPAddress(domain)) | 
 |  100   { | 
 |  101     processTypedDomain(domain); | 
 |  102  | 
 |  103     let newDomain = getDomainCorrection(domain); | 
 |  104     if (newDomain != domain) | 
 |  105     { | 
 |  106       processDomainCorrection(domain, newDomain); | 
 |  107       domain = newDomain; | 
 |  108       hasCorrection = true; | 
 |  109  | 
 |  110       let referral = getDomainReferral(domain.replace(/^www\./, "")); | 
 |  111       if (referral) | 
 |  112       { | 
 |  113         // We need to add a query string parameter when sending users to this do
     main | 
 |  114         let anchorIndex = suffix.indexOf("#"); | 
 |  115         let anchor = ""; | 
 |  116         if (anchorIndex >= 0) | 
 |  117         { | 
 |  118           anchor = suffix.substr(anchorIndex); | 
 |  119           suffix = suffix.substr(0, anchorIndex); | 
 |  120         } | 
 |  121  | 
 |  122         let queryIndex = suffix.indexOf("?"); | 
 |  123         if (queryIndex >= 0) | 
 |  124         { | 
 |  125           if (!/&$/.test(suffix)) | 
 |  126             suffix += "&"; | 
 |  127           suffix += referral; | 
 |  128         } | 
 |  129         else | 
 |  130         { | 
 |  131           if (suffix.indexOf("/") < 0) | 
 |  132             suffix += "/"; | 
 |  133           suffix += "?" + referral; | 
 |  134         } | 
 |  135  | 
 |  136         suffix += anchor; | 
 |  137       } | 
 |  138     } | 
 |  139   } | 
 |  140  | 
 |  141   if (!hasCorrection) | 
 |  142     return null; | 
 |  143    | 
 |  144   if (!appIntegration.isTypoCorrectionEnabled(window, prefix, domain, suffix)) | 
 |  145     return null; | 
 |  146  | 
 |  147   // Show infobar to inform and ask about correction | 
 |  148   let [message, yes, no] = getInfobarTexts(); | 
 |  149   message = message.replace(/\?1\?/g, prefix+domain); | 
 |  150   let buttons = [ | 
 |  151     { | 
 |  152       label:      yes, | 
 |  153       accessKey:  null, | 
 |  154       callback:   function() | 
 |  155       { | 
 |  156         // Yes: Do nothing | 
 |  157       } | 
 |  158     }, | 
 |  159     { | 
 |  160       label:      no, | 
 |  161       accessKey:  null, | 
 |  162       callback:   function() | 
 |  163       { | 
 |  164         // No: Add to list of corrections (ignore) | 
 |  165         let entry = oldDomain.replace(/^www\./, ""); | 
 |  166         Prefs.whitelist[entry] = true; | 
 |  167         onWhitelistEntryAdded(entry); | 
 |  168         Prefs.whitelist = JSON.parse(JSON.stringify(Prefs.whitelist)); | 
 |  169  | 
 |  170         appIntegration.loadURI(window, value); | 
 |  171         processFalsePositive(domain, oldDomain); | 
 |  172       } | 
 |  173     } | 
 |  174   ]; | 
 |  175   // We need to have persistence being set to 1 due to redirect which happens af
     terwards | 
 |  176   appIntegration.openInfobar(window, require("info").addonName + "-infobar-askaf
     ter", message, buttons, 1); | 
 |  177  | 
 |  178   require("typoSurvey").incrementCorrectionsCounter(); | 
 |  179  | 
 |  180   return prefix + domain + suffix; | 
 |  181 } | 
 |  182  | 
 |  183 let stringBundle = null; | 
 |  184  | 
 |  185 function getInfobarTexts() | 
 |  186 { | 
 |  187   // Randomize URI to work around bug 719376 | 
 |  188   if (!stringBundle) | 
 |  189     stringBundle = Services.strings.createBundle("chrome://" + require("info").a
     ddonName + "/locale/typo.properties?" + Math.random()); | 
 |  190   let result = [ | 
 |  191     stringBundle.GetStringFromName("urlfixer.isItCorrect"), | 
 |  192     stringBundle.GetStringFromName("urlfixer.yes"), | 
 |  193     stringBundle.GetStringFromName("urlfixer.no") | 
 |  194   ]; | 
 |  195  | 
 |  196   getInfobarTexts = function() result; | 
 |  197   return getInfobarTexts(); | 
 |  198 } | 
| OLD | NEW |