Bug 689139 Highlight the domain name in the urlbar r=Ratty
authorNeil Rashbrook <neil@parkwaycc.co.uk>
Sun, 04 Mar 2012 15:25:12 +0000
changeset 10996 5cb1917f9106932c8fa2e41c98f9af150bd51383
parent 10995 6bc285618138a22c173dad4acaeee876f1eba76a
child 10997 4a91b37fbbfa73b81a294b718e129200320f5825
push id463
push userbugzilla@standard8.plus.com
push dateTue, 24 Apr 2012 17:34:51 +0000
treeherdercomm-beta@e53588e8f7b0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersRatty
bugs689139
Bug 689139 Highlight the domain name in the urlbar r=Ratty
suite/browser/browser-prefs.js
suite/browser/urlbarBindings.xml
--- a/suite/browser/browser-prefs.js
+++ b/suite/browser/browser-prefs.js
@@ -145,16 +145,17 @@ pref("browser.search.suggest.enabled", t
 
 // Smart Browsing prefs
 pref("keyword.enabled", true);
 // Override the default keyword.URL. Empty value means
 // "use the search service's default engine"
 pref("keyword.URL", "");
 
 pref("browser.urlbar.autocomplete.enabled", true);
+pref("browser.urlbar.formatting.enabled", true);
 pref("browser.urlbar.clickSelectsAll", true);
 // when clickSelectsAll=true, does it also apply when the click is past end of text?
 pref("browser.urlbar.clickAtEndSelects", true);
 
 pref("browser.urlbar.autoFill", false);
 pref("browser.urlbar.showPopup", true);
 pref("browser.urlbar.showSearch", true);
 // 0: Match anywhere (e.g., middle of words)
--- a/suite/browser/urlbarBindings.xml
+++ b/suite/browser/urlbarBindings.xml
@@ -43,16 +43,17 @@
 
     <implementation>
       <constructor><![CDATA[
         this.mPrefs.addObserver("browser.urlbar", this.mPrefObserver, false);
 
         this.updatePref("browser.urlbar.showPopup");
         this.updatePref("browser.urlbar.autoFill");
         this.updatePref("browser.urlbar.showSearch");
+        this.updatePref("browser.urlbar.formatting.enabled");
         this.inputField.controllers.insertControllerAt(0, this._editItemsController);
       ]]></constructor>
 
       <destructor><![CDATA[
         this.inputField.controllers.removeController(this._editItemsController);
         this.mPrefs.removeObserver("browser.urlbar", this.mPrefObserver);
       ]]></destructor>
 
@@ -72,26 +73,81 @@
           }
         });
       ]]></field>
 
       <method name="updatePref">
         <parameter name="aPref"/>
         <body><![CDATA[
           if (aPref == "browser.urlbar.showPopup") {
-            this.showPopup = this.mPrefs.getBoolPref("browser.urlbar.showPopup");
+            this.showPopup = this.mPrefs.getBoolPref(aPref);
           } else if (aPref == "browser.urlbar.autoFill") {
-            this.autoFill = this.mPrefs.getBoolPref("browser.urlbar.autoFill");
+            this.autoFill = this.mPrefs.getBoolPref(aPref);
           } else if (aPref == "browser.urlbar.showSearch") {
-            this.minResultsForPopup = this.mPrefs.getBoolPref("browser.urlbar.showSearch") ?
-                                      0 : 1;
+            this.minResultsForPopup = this.mPrefs.getBoolPref(aPref) ?  0 : 1;
+          } else if (aPref == "browser.urlbar.formatting.enabled") {
+            this._formattingEnabled = this.mPrefs.getBoolPref(aPref);
+            this._formatValue(this._formattingEnabled && !this.focused);
           }
         ]]></body>
       </method>
-      
+
+      <field name="_formattingEnabled">true</field>
+
+      <method name="_formatValue">
+        <parameter name="formattingEnabled"/>
+        <body><![CDATA[
+          var controller = this.editor.selectionController;
+          var selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
+          selection.removeAllRanges();
+          if (!formattingEnabled)
+            return;
+
+          var textNode = this.editor.rootElement.firstChild;
+          var value = textNode.textContent;
+
+          var protocol = value.match(/^[a-z\d.+\-]+:(?=[^\d])/);
+          if (protocol && !/^https?:|ftp:/.test(protocol[0]))
+            return;
+          var matchedURL = value.match(/^((?:[a-z]+:\/\/)?(?:[^\/]+@)?)(.+?)(?::\d+)?(?:\/|$)/);
+          if (!matchedURL)
+            return;
+
+          var [, preDomain, domain] = matchedURL;
+          var subDomain = "";
+          // getBaseDomainFromHost doesn't recognize IPv6 literals in brackets as IPs (bug 667159)
+          if (domain[0] != "[") {
+            try {
+              var baseDomain = Services.eTLD.getBaseDomainFromHost(domain);
+              if (baseDomain != domain) {
+                function dots(s) { return s.replace(/[^.]*/g, "").length; }
+                var subSegments = dots(domain) - dots(baseDomain);
+                subDomain = domain.match(new RegExp("(?:[^.]*\.){" + subSegments + "}"))[0];
+              }
+            } catch (e) {}
+          }
+
+          var startLength = preDomain.length + subDomain.length;
+          if (startLength) {
+            var startRange = document.createRange();
+            startRange.setStart(textNode, 0);
+            startRange.setEnd(textNode, startLength);
+            selection.addRange(startRange);
+          }
+
+          var endLength = preDomain.length + domain.length;
+          if (endLength < value.length) {
+            var endRange = document.createRange();
+            endRange.setStart(textNode, endLength);
+            endRange.setEnd(textNode, value.length);
+            selection.addRange(endRange);
+          }
+        ]]></body>
+      </method>
+
       <method name="autoFillInput">
         <parameter name="aSessionName"/>
         <parameter name="aResults"/>
         <parameter name="aUseFirstMatchIfNoDefault"/>
         <body><![CDATA[
           if (this.mInputElt.selectionEnd < this.currentSearchString.length ||
               this.mDefaultMatchFilled)
             return;
@@ -203,16 +259,32 @@
                 this._fireEvent("textentered", "pasting");
                 break;
             }
           }.bind(this),
           onEvent: function(aEventName) {}
         })
       ]]></field>
     </implementation>
+
+    <handlers>
+      <handler event="ValueChange"><![CDATA[
+        if (this._formattingEnabled && !this.focused)
+          this._formatValue(true);
+      ]]></handler>
+
+      <handler event="blur"><![CDATA[
+        if (this._formattingEnabled)
+          this._formatValue(true);
+      ]]></handler>
+
+      <handler event="focus"><![CDATA[
+        this._formatValue(false);
+      ]]></handler>
+    </handlers>
   </binding>
 
   <binding id="autocomplete-result-popup" extends="chrome://global/content/autocomplete.xml#autocomplete-result-popup">
     <content>
       <xul:tree anonid="tree" class="autocomplete-tree plain" flex="1">
         <xul:treecols anonid="treecols">
           <xul:treecol class="autocomplete-treecol" id="treecolAutoCompleteValue" flex="2"/>
           <xul:treecol class="autocomplete-treecol" id="treecolAutoCompleteComment" flex="1" hidden="true"/>