Bug 1391421 - Part 3 - Switch various places that can end up being user-visible to use Unicode domains. r?jwu,esawin draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Thu, 14 Sep 2017 18:55:09 +0200
changeset 666447 0ef4a646eba39aac9a021fd896ba0aba6960fd79
parent 666389 51acc3b646354e61b4f9ae4c988f336bcf90e843
child 666448 6ec808350092387f6bde13e208c1612885f60154
push id80411
push usermozilla@buttercookie.de
push dateMon, 18 Sep 2017 19:20:36 +0000
reviewersjwu, esawin
bugs1391421
milestone57.0a1
Bug 1391421 - Part 3 - Switch various places that can end up being user-visible to use Unicode domains. r?jwu,esawin Amongst others, this includes some prompts, as well as various progress messages sent to the Java UI. We also fix getTabWithURL to be able to find tabs regardless of whether the given URL to search is written in Punycode or with Unicode characters. MozReview-Commit-ID: K7xhgz2IK2h
mobile/android/chrome/content/browser.js
mobile/android/components/PromptService.js
mobile/android/components/TabSource.js
mobile/android/components/geckoview/GeckoViewPermission.js
mobile/android/components/geckoview/GeckoViewPrompt.js
mobile/android/modules/HelperApps.jsm
mobile/android/modules/geckoview/GeckoViewNavigation.jsm
mobile/android/modules/geckoview/GeckoViewProgress.jsm
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1347,17 +1347,17 @@ var BrowserApp = {
    * @return the tab with the given URL, or null if no such tab exists
    */
   getTabWithURL: function getTabWithURL(aURL, aOptions) {
     aOptions = aOptions || {};
     let uri = Services.io.newURI(aURL);
     for (let i = 0; i < this._tabs.length; ++i) {
       let tab = this._tabs[i];
       if (aOptions.startsWith) {
-        if (tab.currentURI.spec.startsWith(aURL)) {
+        if (tab.currentURI.spec.startsWith(uri.spec)) {
           return tab;
         }
       } else {
         if (tab.currentURI.equals(uri)) {
           return tab;
         }
       }
     }
@@ -2204,18 +2204,18 @@ var BrowserApp = {
       };
     }
 
     let browser = this.selectedBrowser;
     let hist = browser.sessionHistory;
     for (let i = toIndex; i >= fromIndex; i--) {
       let entry = hist.getEntryAtIndex(i, false);
       let item = {
-        title: entry.title || entry.URI.spec,
-        url: entry.URI.spec,
+        title: entry.title || entry.URI.displaySpec,
+        url: entry.URI.displaySpec,
         selected: (i == selIndex)
       };
       listitems.push(item);
     }
 
     return {
       "historyItems": listitems,
       "toIndex": toIndex
@@ -3577,17 +3577,17 @@ Tab.prototype = {
     }
 
     this.browser.stop();
 
     // Only set tab uri if uri is valid
     let uri = null;
     let title = aParams.title || aURL;
     try {
-      uri = Services.io.newURI(aURL).spec;
+      uri = Services.io.newURI(aURL).displaySpec;
     } catch (e) {}
 
     // When the tab is stubbed from Java, there's a window between the stub
     // creation and the tab creation in Gecko where the stub could be removed
     // or the selected tab can change (which is easiest to hit during startup).
     // To prevent these races, we need to differentiate between tab stubs from
     // Java and new tabs from Gecko.
     let stub = false;
@@ -4357,17 +4357,17 @@ Tab.prototype = {
       // true if the page loaded successfully (i.e., no 404s or other errors)
       let success = false;
       let uri = "";
       try {
         // Remember original URI for UA changes on redirected pages
         this.originalURI = aRequest.QueryInterface(Components.interfaces.nsIChannel).originalURI;
 
         if (this.originalURI != null)
-          uri = this.originalURI.spec;
+          uri = this.originalURI.displaySpec;
       } catch (e) { }
       try {
         success = aRequest.QueryInterface(Components.interfaces.nsIHttpChannel).requestSucceeded;
       } catch (e) {
         // If the request does not handle the nsIHttpChannel interface, use nsIRequest's success
         // status. Used for local files. See bug 948849.
         success = aRequest.status == 0;
       }
@@ -4437,20 +4437,20 @@ Tab.prototype = {
     // This mirrors the desktop logic in TabsProgressListener.
     if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
       this.browser.messageManager.sendAsyncMessage("Reader:PushState", {isArticle: this.browser.isArticle});
     }
 
     let baseDomain = "";
     // For recognized scheme, get base domain from host.
     let principalURI = contentWin.document.nodePrincipal.URI;
-    if (principalURI && ["http", "https", "ftp"].includes(principalURI.scheme) && principalURI.host) {
+    if (principalURI && ["http", "https", "ftp"].includes(principalURI.scheme) && principalURI.displayHost) {
       try {
-        baseDomain = Services.eTLD.getBaseDomainFromHost(principalURI.host);
-        if (!principalURI.host.endsWith(baseDomain)) {
+        baseDomain = Services.eTLD.getBaseDomainFromHost(principalURI.displayHost);
+        if (!principalURI.displayHost.endsWith(baseDomain)) {
           // getBaseDomainFromHost converts its resultant to ACE.
           let IDNService = Cc["@mozilla.org/network/idn-service;1"].getService(Ci.nsIIDNService);
           baseDomain = IDNService.convertACEtoUTF8(baseDomain);
         }
       } catch (e) {}
     }
 
     // If we are navigating to a new location with a different host,
@@ -4474,17 +4474,17 @@ Tab.prototype = {
     // Update the page actions URI for helper apps.
     if (BrowserApp.selectedTab == this) {
       ExternalApps.updatePageActionUri(fixedURI);
     }
 
     let message = {
       type: "Content:LocationChange",
       tabID: this.id,
-      uri: truncate(fixedURI.spec, MAX_URI_LENGTH),
+      uri: truncate(fixedURI.displaySpec, MAX_URI_LENGTH),
       userRequested: this.userRequested || "",
       baseDomain: baseDomain,
       contentType: (contentType ? contentType : ""),
       sameDocument: sameDocument,
 
       canGoBack: webNav.canGoBack,
       canGoForward: webNav.canGoForward,
     };
@@ -5971,17 +5971,17 @@ var SearchEngines = {
     let charset = aElement.ownerDocument.characterSet;
     let docURI = Services.io.newURI(aElement.ownerDocument.URL, charset);
     let formURL = Services.io.newURI(form.getAttribute("action"), charset, docURI).spec;
     let method = form.method.toUpperCase();
     let formData = this._getSortedFormData(aElement);
 
     // prompt user for name of search engine
     let promptTitle = Strings.browser.GetStringFromName("contextmenu.addSearchEngine3");
-    let title = { value: (aElement.ownerDocument.title || docURI.host) };
+    let title = { value: (aElement.ownerDocument.title || docURI.displayHost) };
     if (!Services.prompt.prompt(null, promptTitle, null, title, null, {})) {
       if (resultCallback) {
         resultCallback(false);
       };
       return;
     }
 
     Services.search.init(function addEngine_cb(rv) {
--- a/mobile/android/components/PromptService.js
+++ b/mobile/android/components/PromptService.js
@@ -785,17 +785,17 @@ var PromptUtils = {
     }
     aAuthInfo.password = password;
   },
 
   /**
    * Strip out things like userPass and path for display.
    */
   getFormattedHostname: function pu_getFormattedHostname(uri) {
-    return uri.scheme + "://" + uri.hostPort;
+    return uri.scheme + "://" + uri.displayHostPort;
   },
 
   fireDialogEvent: function(aDomWin, aEventName) {
     // accessing the document object can throw if this window no longer exists. See bug 789888.
     try {
       if (!aDomWin.document)
         return;
       let event = aDomWin.document.createEvent("Events");
--- a/mobile/android/components/TabSource.js
+++ b/mobile/android/components/TabSource.js
@@ -38,19 +38,19 @@ TabSource.prototype = {
     let prompt = new Prompt({
       title: title,
       window: null
     }).setSingleChoiceItems(tabs.map(function(tab) {
       let label;
       if (tab.browser.contentTitle)
         label = tab.browser.contentTitle;
       else if (tab.browser.contentURI)
-        label = tab.browser.contentURI.spec;
+        label = tab.browser.contentURI.displaySpec;
       else
-        label = tab.originalURI.spec;
+        label = tab.originalURI.displaySpec;
       return { label: label,
                icon: "thumbnail:" + tab.id }
     }));
 
     let result = null;
     prompt.show(function(data) {
       result = data.button;
     });
--- a/mobile/android/components/geckoview/GeckoViewPermission.js
+++ b/mobile/android/components/geckoview/GeckoViewPermission.js
@@ -102,17 +102,17 @@ GeckoViewPermission.prototype = {
       } else if (constraints.audio && !sources.some(source => source.type === "audio")) {
         throw "no audio source";
       }
 
       let dispatcher = this.getDispatcherForWindow(win);
       let uri = win.document.documentURIObject;
       return dispatcher.sendRequestForResult({
         type: "GeckoView:MediaPermission",
-        uri: uri.spec,
+        uri: uri.displaySpec,
         video: constraints.video ? sources.filter(source => source.type === "video") : null,
         audio: constraints.audio ? sources.filter(source => source.type === "audio") : null,
       }).then(response => {
         if (!response) {
           // Rejected.
           denyRequest();
           return;
         }
@@ -215,17 +215,17 @@ GeckoViewPermission.prototype = {
       return;
     }
 
     let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
     let dispatcher = this.getDispatcherForWindow(
         aRequest.window ? aRequest.window.top : aRequest.element.ownerGlobal.top);
     let promise = dispatcher.sendRequestForResult({
         type: "GeckoView:ContentPermission",
-        uri: aRequest.principal.URI.spec,
+        uri: aRequest.principal.URI.displaySpec,
         perm: perm.type,
         access: perm.access !== "unused" ? perm.access : null,
     }).then(granted => {
       if (!granted) {
         return false;
       }
       // Ask for app permission after asking for content permission.
       if (perm.type === "geolocation") {
--- a/mobile/android/components/geckoview/GeckoViewPrompt.js
+++ b/mobile/android/components/geckoview/GeckoViewPrompt.js
@@ -663,17 +663,17 @@ PromptDelegate.prototype = {
     } else {
       username = aAuthInfo.username;
     }
     return this._addText(/* title */ null, this._getAuthText(aChannel, aAuthInfo), {
       type: "auth",
       mode: aAuthInfo.flags & Ci.nsIAuthInformation.ONLY_PASSWORD ? "password" : "auth",
       options: {
         flags: aAuthInfo.flags,
-        uri: aChannel && aChannel.URI.spec,
+        uri: aChannel && aChannel.URI.displaySpec,
         level: aLevel,
         username: username,
         password: aAuthInfo.password,
       },
     });
   },
 
   _fillAuthInfo: function(aAuthInfo, aCheckState, aResult) {
@@ -796,17 +796,17 @@ PromptDelegate.prototype = {
       let hostname = "moz-proxy://" + idnService.convertUTF8toACE(info.host) + ":" + info.port;
       let realm = aAuthInfo.realm;
       if (!realm) {
         realm = hostname;
       }
       return [hostname, realm];
     }
 
-    let hostname = aChannel.URI.scheme + "://" + aChannel.URI.hostPort;
+    let hostname = aChannel.URI.scheme + "://" + aChannel.URI.displayHostPort;
     // If a HTTP WWW-Authenticate header specified a realm, that value
     // will be available here. If it wasn't set or wasn't HTTP, we'll use
     // the formatted hostname instead.
     let realm = aAuthInfo.realm;
     if (!realm) {
       realm = hostname;
     }
     return [hostname, realm];
--- a/mobile/android/modules/HelperApps.jsm
+++ b/mobile/android/modules/HelperApps.jsm
@@ -191,17 +191,17 @@ var HelperApps =  {
     if (uri && mimeType == undefined) {
       mimeType = ContentAreaUtils.getMIMETypeForURI(uri) || "";
     }
 
     return {
       type: type,
       mime: mimeType,
       action: options.action || "", // empty action string defaults to android.intent.action.VIEW
-      url: uri ? uri.spec : "",
+      url: uri ? uri.displaySpec : "",
       packageName: options.packageName || "",
       className: options.className || ""
     };
   },
 
   _launchApp: function launchApp(app, uri, callback) {
     if (callback) {
         let msg = this._getMessage("Intent:OpenForResult", uri, {
--- a/mobile/android/modules/geckoview/GeckoViewNavigation.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewNavigation.jsm
@@ -79,17 +79,17 @@ class GeckoViewNavigation extends GeckoV
           " aFlags=" + aFlags);
 
     if (!aUri) {
       return false;
     }
 
     let message = {
       type: "GeckoView:OnLoadUri",
-      uri: aUri.spec,
+      uri: aUri.displaySpec,
       where: aWhere,
       flags: aFlags
     };
 
     debug("dispatch " + JSON.stringify(message));
 
     let handled = undefined;
     this.eventDispatcher.sendRequestForResult(message).then(response => {
@@ -191,17 +191,17 @@ class GeckoViewNavigation extends GeckoV
     let fixedURI = aLocationURI;
 
     try {
       fixedURI = URIFixup.createExposableURI(aLocationURI);
     } catch (ex) { }
 
     let message = {
       type: "GeckoView:LocationChange",
-      uri: fixedURI.spec,
+      uri: fixedURI.displaySpec,
       canGoBack: this.browser.canGoBack,
       canGoForward: this.browser.canGoForward,
     };
 
     debug("dispatch " + JSON.stringify(message));
 
     this.eventDispatcher.sendRequest(message);
   }
--- a/mobile/android/modules/geckoview/GeckoViewProgress.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewProgress.jsm
@@ -266,17 +266,17 @@ class GeckoViewProgress extends GeckoVie
     if (!aWebProgress.isTopLevel) {
       return;
     }
 
     if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
       let uri = aRequest.QueryInterface(Ci.nsIChannel).URI;
       let message = {
         type: "GeckoView:PageStart",
-        uri: uri.spec,
+        uri: uri.displaySpec,
       };
 
       this.eventDispatcher.sendRequest(message);
     } else if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
                !aWebProgress.isLoadingDocument) {
       let message = {
         type: "GeckoView:PageStop",
         success: !aStatus