Bug 935377 - Firefox should fix common scheme typos, r=dolske
authorChristian Legnitto <christian@legnitto.com>
Sun, 12 Jan 2014 12:02:27 -0800
changeset 163057 72fc7d58a274
parent 163056 1b3735a6c466
child 163058 d48dc641d5c3
push id25979
push usercbook@mozilla.com
push date2014-01-13 11:46 +0000
Treeherderresults
reviewersdolske
bugs935377
milestone29.0a1
Bug 935377 - Firefox should fix common scheme typos, r=dolske
browser/base/content/browser.js
browser/base/content/openLocation.js
browser/base/content/tabbrowser.xml
browser/base/content/urlbarBindings.xml
browser/base/content/utilityOverlay.js
browser/components/nsBrowserContentHandler.js
browser/metro/base/content/browser-ui.js
browser/metro/base/content/browser.js
caps/src/nsScriptSecurityManager.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsIDocShell.idl
docshell/base/nsIWebNavigation.idl
mobile/android/chrome/content/browser.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1834,18 +1834,20 @@ function BrowserTryToCloseWindow()
     window.close();     // WindowIsClosing does all the necessary checks
 }
 
 function loadURI(uri, referrer, postData, allowThirdPartyFixup) {
   if (postData === undefined)
     postData = null;
 
   var flags = nsIWebNavigation.LOAD_FLAGS_NONE;
-  if (allowThirdPartyFixup)
+  if (allowThirdPartyFixup) {
     flags |= nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+    flags |= nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
+  }
 
   try {
     gBrowser.loadURIWithFlags(uri, flags, referrer, null, postData);
   } catch (e) {}
 }
 
 function getShortcutOrURIAndPostData(aURL) {
   return Task.spawn(function() {
--- a/browser/base/content/openLocation.js
+++ b/browser/base/content/openLocation.js
@@ -77,17 +77,18 @@ function open()
     }
 
     try {
       // Whichever target we use for the load, we allow third-party services to
       // fixup the URI
       switch (dialog.openWhereList.value) {
         case "0":
           var webNav = Components.interfaces.nsIWebNavigation;
-          var flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+          var flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
+                      webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
           if (!mayInheritPrincipal)
             flags |= webNav.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
           browser.gBrowser.loadURIWithFlags(url, flags, null, null, postData);
           break;
         case "1":
           window.opener.delayedOpenWindow(getBrowserURL(), "all,dialog=no",
                                           url, postData, null, null, true);
           break;
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1596,18 +1596,20 @@
             // then let's just continue loading the page normally.
             if (!docShellsSwapped && !uriIsAboutBlank) {
               // pretend the user typed this so it'll be available till
               // the document successfully loads
               if (aURI && gInitialPages.indexOf(aURI) == -1)
                 b.userTypedValue = aURI;
 
               let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
-              if (aAllowThirdPartyFixup)
+              if (aAllowThirdPartyFixup) {
                 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+                flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
+              }
               if (aFromExternal)
                 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
               if (aDisableMCB)
                 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT;
               try {
                 b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData);
               } catch (ex) {
                 Cu.reportError(ex);
@@ -4475,17 +4477,20 @@
           if (!tab || dropEffect == "copy") {
             // We're adding a new tab.
             let newIndex = this._getDropIndex(event);
             let newTab = this.tabbrowser.loadOneTab(url, {inBackground: bgLoad, allowThirdPartyFixup: true});
             this.tabbrowser.moveTabTo(newTab, newIndex);
           } else {
             // Load in an existing tab.
             try {
-              this.tabbrowser.getBrowserForTab(tab).loadURIWithFlags(url, Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP);
+              let webNav = Ci.nsIWebNavigation;
+              let flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
+                          webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
+              this.tabbrowser.getBrowserForTab(tab).loadURIWithFlags(url, flags);
               if (!bgLoad)
                 this.selectedItem = tab;
             } catch(ex) {
               // Just ignore invalid urls
             }
           }
         }
 
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -288,17 +288,19 @@
               addToUrlbarHistory(url);
             } catch (ex) {
               // Things may go wrong when adding url to session history,
               // but don't let that interfere with the loading of the url.
               Cu.reportError(ex);
             }
 
             function loadCurrent() {
-              let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+              let webnav = Ci.nsIWebNavigation;
+              let flags = webnav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
+                          webnav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
               // Pass LOAD_FLAGS_DISALLOW_INHERIT_OWNER to prevent any loads from
               // inheriting the currently loaded document's principal, unless this
               // URL is marked as safe to inherit (e.g. came from a bookmark
               // keyword).
               if (!mayInheritPrincipal)
                 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
               gBrowser.loadURIWithFlags(url, flags, null, null, postData);
             }
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -295,18 +295,20 @@ function openLinkIn(url, where, params) 
 
   // Raise the target window before loading the URI, since loading it may
   // result in a new frontmost window (e.g. "javascript:window.open('');").
   w.focus();
 
   switch (where) {
   case "current":
     let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
-    if (aAllowThirdPartyFixup)
+    if (aAllowThirdPartyFixup) {
       flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+      flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
+    }
     if (aDisallowInheritPrincipal)
       flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
     w.gBrowser.loadURIWithFlags(url, flags, aReferrerURI, null, aPostData);
     break;
   case "tabshifted":
     loadInBackground = !loadInBackground;
     // fall through
   case "tab":
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -49,36 +49,36 @@ function shouldLoadURI(aURI) {
 
   dump("*** Preventing external load of chrome: URI into browser window\n");
   dump("    Use -chrome <uri> instead\n");
   return false;
 }
 
 function resolveURIInternal(aCmdLine, aArgument) {
   var uri = aCmdLine.resolveURI(aArgument);
+  var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
+                           .getService(nsIURIFixup);
 
   if (!(uri instanceof nsIFileURL)) {
-    return uri;
+    return urifixup.createFixupURI(aArgument,
+                                   urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS);
   }
 
   try {
     if (uri.file.exists())
       return uri;
   }
   catch (e) {
     Components.utils.reportError(e);
   }
 
   // We have interpreted the argument as a relative file URI, but the file
   // doesn't exist. Try URI fixup heuristics: see bug 290782.
  
   try {
-    var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
-                             .getService(nsIURIFixup);
-
     uri = urifixup.createFixupURI(aArgument, 0);
   }
   catch (e) {
     Components.utils.reportError(e);
   }
 
   return uri;
 }
--- a/browser/metro/base/content/browser-ui.js
+++ b/browser/metro/base/content/browser-ui.js
@@ -363,22 +363,26 @@ var BrowserUI = {
     // Make sure we're online before attempting to load
     Util.forceOnline();
 
     BrowserUI.showContent(aURI);
     Browser.selectedBrowser.focus();
 
     Task.spawn(function() {
       let postData = {};
+      let webNav = Ci.nsIWebNavigation;
+      let flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
+                  webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
       aURI = yield Browser.getShortcutOrURI(aURI, postData);
-      Browser.loadURI(aURI, { flags: Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP, postData: postData });
+      Browser.loadURI(aURI, { flags: flags, postData: postData });
 
       // Delay doing the fixup so the raw URI is passed to loadURIWithFlags
       // and the proper third-party fixup can be done
-      let fixupFlags = Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
+      let fixupFlags = Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP | 
+                       Ci.nsIURIFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS;
       let uri = gURIFixup.createFixupURI(aURI, fixupFlags);
       gHistSvc.markPageAsTyped(uri);
 
       BrowserUI._titleChanged(Browser.selectedBrowser);
     });
   },
 
   doOpenSearch: function doOpenSearch(aName) {
--- a/browser/metro/base/content/browser.js
+++ b/browser/metro/base/content/browser.js
@@ -167,17 +167,20 @@ var Browser = {
 
     Task.spawn(function() {
       // Activation URIs come from protocol activations, secondary tiles, and file activations
       let activationURI = yield this.getShortcutOrURI(Services.metro.activationURI);
 
       let self = this;
       function loadStartupURI() {
         if (activationURI) {
-          self.addTab(activationURI, true, null, { flags: Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP });
+          let webNav = Ci.nsIWebNavigation;
+          let flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
+                      webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
+          self.addTab(activationURI, true, null, { flags: flags });
         } else {
           let uri = commandURL || Browser.getHomePage();
           self.addTab(uri, true);
         }
       }
 
       // Should we restore the previous session (crash or some other event)
       let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1266,16 +1266,17 @@ nsScriptSecurityManager::CheckLoadURIStr
     // Note: This needs to stay in sync with the nsIURIFixup api.
     nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID);
     if (!fixup) {
         return rv;
     }
 
     uint32_t flags[] = {
         nsIURIFixup::FIXUP_FLAG_NONE,
+        nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS,
         nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP,
         nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
         nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP |
         nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI
     };
 
     for (uint32_t i = 0; i < ArrayLength(flags); ++i) {
         rv = fixup->CreateFixupURI(aTargetURIStr, flags[i], nullptr,
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1578,16 +1578,19 @@ nsDocShell::LoadURI(nsIURI * aURI,
         flags |= INTERNAL_LOAD_FLAGS_INHERIT_OWNER;
 
     if (!sendReferrer)
         flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
             
     if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP)
         flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
 
+    if (aLoadFlags & LOAD_FLAGS_FIXUP_SCHEME_TYPOS)
+        flags |= INTERNAL_LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
+
     if (aLoadFlags & LOAD_FLAGS_FIRST_LOAD)
         flags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD;
 
     if (aLoadFlags & LOAD_FLAGS_BYPASS_CLASSIFIER)
         flags |= INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER;
 
     if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES)
         flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
@@ -4267,16 +4270,19 @@ nsDocShell::LoadURI(const char16_t * aUR
         // Call the fixup object.  This will clobber the rv from NS_NewURI
         // above, but that's fine with us.  Note that we need to do this even
         // if NS_NewURI returned a URI, because fixup handles nested URIs, etc
         // (things like view-source:mozilla.org for example).
         uint32_t fixupFlags = 0;
         if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
           fixupFlags |= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
         }
+        if (aLoadFlags & LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
+          fixupFlags |= nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS;
+        }
         nsCOMPtr<nsIInputStream> fixupStream;
         rv = sURIFixup->CreateFixupURI(uriString, fixupFlags,
                                        getter_AddRefs(fixupStream),
                                        getter_AddRefs(uri));
         if (fixupStream) {
             // CreateFixupURI only returns a post data stream if it succeeded
             // and changed the URI, in which case we should override the
             // passed-in post data.
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -39,17 +39,17 @@ interface nsIDOMStorage;
 interface nsIPrincipal;
 interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 
 typedef unsigned long nsLoadFlags;
 
-[scriptable, builtinclass, uuid(55ca6545-7ce4-49ad-8117-8286ca9c61bb)]
+[scriptable, builtinclass, uuid(e3ea830d-2614-4aeb-9ec3-b8f744b03b80)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
@@ -106,16 +106,18 @@ interface nsIDocShell : nsIDocShellTreeI
   const long INTERNAL_LOAD_FLAGS_FIRST_LOAD              = 0x8;
 
   const long INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER       = 0x10;
   const long INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES     = 0x20;
 
   // Whether the load should be treated as srcdoc load, rather than a URI one.
   const long INTERNAL_LOAD_FLAGS_IS_SRCDOC               = 0x40;
 
+  const long INTERNAL_LOAD_FLAGS_FIXUP_SCHEME_TYPOS      = 0x80;
+
   /**
    * Loads the given URI.  This method is identical to loadURI(...) except
    * that its parameter list is broken out instead of being packaged inside
    * of an nsIDocShellLoadInfo object...
    *
    * @param aURI            - The URI to load.
    * @param aReferrer       - Referring URI
    * @param aOwner          - Owner (security principal) 
--- a/docshell/base/nsIWebNavigation.idl
+++ b/docshell/base/nsIWebNavigation.idl
@@ -11,17 +11,17 @@ interface nsISHistory;
 interface nsIURI;
 
 /**
  * The nsIWebNavigation interface defines an interface for navigating the web.
  * It provides methods and attributes to direct an object to navigate to a new
  * location, stop or restart an in process load, or determine where the object
  * has previously gone.
  */
-[scriptable, uuid(28404f7e-0f17-4dc3-a21a-2074d8659b02)]
+[scriptable, uuid(dbd6241d-c76e-42c0-9410-930589d803a2)]
 interface nsIWebNavigation : nsISupports
 {
   /**
    * Indicates if the object can go back.  If true this indicates that
    * there is back session history available for navigation.
    */
   readonly attribute boolean canGoBack;
 
@@ -186,16 +186,21 @@ interface nsIWebNavigation : nsISupports
 
   /**
    * This flag specifies that the URI may be submitted to a third-party
    * server for correction. This should only be applied to non-sensitive
    * URIs entered by users.  This flag must not be passed to Reload.
    */
   const unsigned long LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x100000;
 
+  /**
+   * This flag specifies that common scheme typos should be corrected.
+   */
+  const unsigned long LOAD_FLAGS_FIXUP_SCHEME_TYPOS = 0x200000;
+
   /* Note that flag 0x80000 is available. */
 
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URI dispatcher will go through its normal process of content
    * loading.
    *
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1422,17 +1422,18 @@ var BrowserApp = {
         break;
       }
 
       case "Tab:Load": {
         let data = JSON.parse(aData);
 
         // Pass LOAD_FLAGS_DISALLOW_INHERIT_OWNER to prevent any loads from
         // inheriting the currently loaded document's principal.
-        let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+        let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
+                    Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
         if (data.userEntered) {
           flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
         }
 
         let delayLoad = ("delayLoad" in data) ? data.delayLoad : false;
         let params = {
           selected: ("selected" in data) ? data.selected : !delayLoad,
           parentId: ("parentId" in data) ? data.parentId : -1,