Bug 1111145 - The URL bar and search box dropdowns shadow should match the Firefox menu's. r?dao draft
authorJared Wein <jwein@mozilla.com>
Wed, 28 Sep 2016 15:28:51 -0400
changeset 418613 0a2b5bc23879aef01de8d913b0a73eeb59294e74
parent 415096 6fef7e47113c21ad3447db194f921bf2b6f97421
child 532388 c1efd015bedfe134c00d1b62ee23b9cfabbaee0d
push id30725
push userbmo:jaws@mozilla.com
push dateWed, 28 Sep 2016 19:29:09 +0000
reviewersdao
bugs1111145
milestone51.0a1
Bug 1111145 - The URL bar and search box dropdowns shadow should match the Firefox menu's. r?dao MozReview-Commit-ID: F2hEXvg2ARG
browser/base/content/browser.css
browser/base/content/urlbarBindings.xml
browser/components/search/content/search.xml
browser/themes/shared/urlbarSearchSuggestionsNotification.inc.css
browser/themes/windows/searchbar.css
toolkit/content/widgets/autocomplete.xml
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -456,23 +456,23 @@ toolbar:not(#TabsToolbar) > #personal-bo
    text. */
 .ac-url[actiontype],
 .ac-action:not([actiontype]) {
   display: none;
 }
 
 /* For action items in a noactions popup, show the URL text and hide the action
    text and type icon. */
-#PopupAutoCompleteRichResult[noactions] > richlistbox > richlistitem.overridable-action > .ac-url {
+#PopupAutoCompleteRichResult[noactions] > vbox[anonid="urlbar-rich-result-popup-container"] > richlistbox > richlistitem.overridable-action > .ac-url {
   display: -moz-box;
 }
-#PopupAutoCompleteRichResult[noactions] > richlistbox > richlistitem.overridable-action > .ac-action {
+#PopupAutoCompleteRichResult[noactions] > vbox[anonid="urlbar-rich-result-popup-container"] > richlistbox > richlistitem.overridable-action > .ac-action {
   display: none;
 }
-#PopupAutoCompleteRichResult[noactions] > richlistbox > richlistitem.overridable-action > .ac-type-icon {
+#PopupAutoCompleteRichResult[noactions] > vbox[anonid="urlbar-rich-result-popup-container"] > richlistbox > richlistitem.overridable-action > .ac-type-icon {
   list-style-image: none;
 }
 
 #urlbar:not([actiontype="switchtab"]) > #urlbar-display-box {
   display: none;
 }
 
 #PopupAutoComplete {
@@ -493,30 +493,30 @@ toolbar:not(#TabsToolbar) > #personal-bo
 #PopupAutoCompleteRichResult {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
 }
 
 #PopupAutoCompleteRichResult.showSearchSuggestionsNotification {
   transition: height 100ms;
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] {
   visibility: collapse;
   transition: margin-top 100ms;
 }
 
-#PopupAutoCompleteRichResult.showSearchSuggestionsNotification > hbox[anonid="search-suggestions-notification"] {
+#PopupAutoCompleteRichResult.showSearchSuggestionsNotification > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] {
   visibility: visible;
 }
 
 #PopupAutoCompleteRichResult > richlistbox {
   transition: height 100ms;
 }
 
-#PopupAutoCompleteRichResult.showSearchSuggestionsNotification > richlistbox {
+#PopupAutoCompleteRichResult.showSearchSuggestionsNotification > vbox[anonid="urlbar-rich-result-popup-container"] > richlistbox {
   transition: none;
 }
 
 #urlbar[pageproxystate="invalid"] > #urlbar-icons > .urlbar-icon,
 #urlbar[pageproxystate="invalid"][focused="true"] > #urlbar-go-button ~ toolbarbutton,
 #urlbar[pageproxystate="valid"] > #urlbar-go-button,
 #urlbar:not([focused="true"]) > #urlbar-go-button {
   visibility: collapse;
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1268,55 +1268,57 @@ file, You can obtain one at http://mozil
 
     <resources>
       <stylesheet src="chrome://browser/content/search/searchbarBindings.css"/>
       <stylesheet src="chrome://browser/skin/searchbar.css"/>
     </resources>
 
     <content ignorekeys="true" level="top" consumeoutsideclicks="never"
              aria-owns="richlistbox">
-      <xul:hbox anonid="search-suggestions-notification"
-                align="center"
-                role="alert"
-                aria-describedby="search-suggestions-notification-text">
-        <xul:description flex="1">
-          &urlbar.searchSuggestionsNotification.question;
-          <!-- Several things here are to make the label accessibile via an
-               accesskey so that a11y doesn't suck: the accesskey, using an
-               onclick handler instead of an href attribute, the control
-               attribute, and having the control attribute refer to a valid ID
-               that is the label itself. -->
-          <xul:label id="search-suggestions-notification-learn-more"
-                     class="text-link"
-                     role="link"
-                     value="&urlbar.searchSuggestionsNotification.learnMore;"
-                     accesskey="&urlbar.searchSuggestionsNotification.learnMore.accesskey;"
-                     onclick="document.getBindingParent(this).openSearchSuggestionsNotificationLearnMoreURL();"
-                     control="search-suggestions-notification-learn-more"/>
-        </xul:description>
-        <xul:button anonid="search-suggestions-notification-disable"
-                    label="&urlbar.searchSuggestionsNotification.disable;"
-                    accesskey="&urlbar.searchSuggestionsNotification.disable.accesskey;"
-                    onclick="document.getBindingParent(this).dismissSearchSuggestionsNotification(false);"/>
-        <xul:button anonid="search-suggestions-notification-enable"
-                    label="&urlbar.searchSuggestionsNotification.enable;"
-                    accesskey="&urlbar.searchSuggestionsNotification.enable.accesskey;"
-                    onclick="document.getBindingParent(this).dismissSearchSuggestionsNotification(true);"/>
-      </xul:hbox>
-      <xul:richlistbox anonid="richlistbox" class="autocomplete-richlistbox"
-                       flex="1"/>
-      <xul:hbox anonid="footer">
-        <children/>
-        <xul:vbox anonid="one-off-search-buttons"
-                  class="search-one-offs"
-                  compact="true"
-                  includecurrentengine="true"
-                  disabletab="true"
-                  flex="1"/>
-      </xul:hbox>
+      <xul:vbox anonid="urlbar-rich-result-popup-container">
+        <xul:hbox anonid="search-suggestions-notification"
+                  align="center"
+                  role="alert"
+                  aria-describedby="search-suggestions-notification-text">
+          <xul:description flex="1">
+            &urlbar.searchSuggestionsNotification.question;
+            <!-- Several things here are to make the label accessibile via an
+                 accesskey so that a11y doesn't suck: the accesskey, using an
+                 onclick handler instead of an href attribute, the control
+                 attribute, and having the control attribute refer to a valid ID
+                 that is the label itself. -->
+            <xul:label id="search-suggestions-notification-learn-more"
+                       class="text-link"
+                       role="link"
+                       value="&urlbar.searchSuggestionsNotification.learnMore;"
+                       accesskey="&urlbar.searchSuggestionsNotification.learnMore.accesskey;"
+                       onclick="document.getBindingParent(this).openSearchSuggestionsNotificationLearnMoreURL();"
+                       control="search-suggestions-notification-learn-more"/>
+          </xul:description>
+          <xul:button anonid="search-suggestions-notification-disable"
+                      label="&urlbar.searchSuggestionsNotification.disable;"
+                      accesskey="&urlbar.searchSuggestionsNotification.disable.accesskey;"
+                      onclick="document.getBindingParent(this).dismissSearchSuggestionsNotification(false);"/>
+          <xul:button anonid="search-suggestions-notification-enable"
+                      label="&urlbar.searchSuggestionsNotification.enable;"
+                      accesskey="&urlbar.searchSuggestionsNotification.enable.accesskey;"
+                      onclick="document.getBindingParent(this).dismissSearchSuggestionsNotification(true);"/>
+        </xul:hbox>
+        <xul:richlistbox anonid="richlistbox" class="autocomplete-richlistbox"
+                         flex="1"/>
+        <xul:hbox anonid="footer">
+          <children/>
+          <xul:vbox anonid="one-off-search-buttons"
+                    class="search-one-offs"
+                    compact="true"
+                    includecurrentengine="true"
+                    disabletab="true"
+                    flex="1"/>
+        </xul:hbox>
+      </xul:vbox>
     </content>
 
     <implementation>
       <field name="_maxResults">0</field>
 
       <field name="_bundle" readonly="true">
         Cc["@mozilla.org/intl/stringbundle;1"].
           getService(Ci.nsIStringBundleService).
@@ -1501,32 +1503,37 @@ file, You can obtain one at http://mozil
             return;
           }
 
           this.mInput = aInput;
           this.selectedIndex = this._isFirstResultHeuristic ? 0 : -1;
           this.view = aInput.controller.QueryInterface(Components.interfaces.nsITreeView);
           this._invalidate();
 
+          // We need to compensate for the negative margin on Windows, which doesn't
+          // show up in getComputedStyle until the popup has been shown.
+          // This is duplicated from urlbarSearchSuggestionsNotification.inc.css.
+          const popupMargin = AppConstants.platform == "win" ? 4 : 0;
+
           var rect = window.document.documentElement.getBoundingClientRect();
-          var width = rect.right - rect.left;
+          var width = rect.right - rect.left + 2 * popupMargin;
           this.setAttribute("width", width);
 
           // Adjust the direction of the autocomplete popup list based on the textbox direction, bug 649840
           var popupDirection = aElement.ownerDocument.defaultView.getComputedStyle(aElement).direction;
           this.style.direction = popupDirection;
 
           // Make the popup's starting margin negative so that the leading edge
           // of the popup aligns with the window border.
           let elementRect = aElement.getBoundingClientRect();
           if (popupDirection == "rtl") {
-            let offset = elementRect.right - rect.right
+            let offset = elementRect.right - rect.right - popupMargin;
             this.style.marginRight = offset + "px";
           } else {
-            let offset = rect.left - elementRect.left;
+            let offset = rect.left - elementRect.left - popupMargin;
             this.style.marginLeft = offset + "px";
           }
 
           // Keep the popup items' site icons aligned with the urlbar's identity
           // icon if it's not too far from the edge of the window.  If there are
           // at most two toolbar buttons between the window edge and the urlbar,
           // then consider that as "not too far."  The forward button's
           // visibility may have changed since the last time the popup was
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -701,19 +701,24 @@
             popup.showImageColumn = this.showImageColumn;
 
             document.popupNode = null;
 
             const isRTL = getComputedStyle(this, "").direction == "rtl";
 
             var outerRect = this.getBoundingClientRect();
             var innerRect = this.inputField.getBoundingClientRect();
+            // We need to compensate for the negative margin on Windows,
+            // which doesn't show up in getComputedStyle because the
+            // styles are not applied until the popup has been shown.
+            // Duplicated from /browser/themes/windows/searchbar.css.
+            const marginOffset = AppConstants.platfrom == "win" ? 4 : 0;
             let width = isRTL ?
-                        innerRect.right - outerRect.left :
-                        outerRect.right - innerRect.left;
+                        innerRect.right - outerRect.left + marginOffset :
+                        outerRect.right - innerRect.left + marginOffset;
             popup.setAttribute("width", width > 100 ? width : 100);
 
             var yOffset = outerRect.bottom - innerRect.bottom;
             popup.openPopup(this.inputField, "after_start", 0, yOffset, false, false);
           }
         ]]></body>
       </method>
 
@@ -879,31 +884,33 @@
   </binding>
 
   <binding id="browser-search-autocomplete-result-popup" extends="chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup">
     <resources>
       <stylesheet src="chrome://browser/content/search/searchbarBindings.css"/>
       <stylesheet src="chrome://browser/skin/searchbar.css"/>
     </resources>
     <content ignorekeys="true" level="top" consumeoutsideclicks="never">
-      <xul:hbox anonid="searchbar-engine" xbl:inherits="showonlysettings"
-                class="search-panel-header search-panel-current-engine">
-        <xul:image class="searchbar-engine-image" xbl:inherits="src"/>
-        <xul:label anonid="searchbar-engine-name" flex="1" crop="end"
-                   role="presentation"/>
-      </xul:hbox>
-      <xul:tree anonid="tree" flex="1"
-                class="autocomplete-tree plain search-panel-tree"
-                hidecolumnpicker="true" seltype="single">
-        <xul:treecols anonid="treecols">
-          <xul:treecol id="treecolAutoCompleteValue" class="autocomplete-treecol" flex="1" overflow="true"/>
-        </xul:treecols>
-        <xul:treechildren class="autocomplete-treebody"/>
-      </xul:tree>
-      <xul:vbox anonid="search-one-off-buttons" class="search-one-offs"/>
+      <xul:vbox class="autocomplete-popup-container">
+        <xul:hbox anonid="searchbar-engine" xbl:inherits="showonlysettings"
+                  class="search-panel-header search-panel-current-engine">
+          <xul:image class="searchbar-engine-image" xbl:inherits="src"/>
+          <xul:label anonid="searchbar-engine-name" flex="1" crop="end"
+                     role="presentation"/>
+        </xul:hbox>
+        <xul:tree anonid="tree" flex="1"
+                  class="autocomplete-tree plain search-panel-tree"
+                  hidecolumnpicker="true" seltype="single">
+          <xul:treecols anonid="treecols">
+            <xul:treecol id="treecolAutoCompleteValue" class="autocomplete-treecol" flex="1" overflow="true"/>
+          </xul:treecols>
+          <xul:treechildren class="autocomplete-treebody"/>
+        </xul:tree>
+        <xul:vbox anonid="search-one-off-buttons" class="search-one-offs"/>
+      </xul:vbox>
     </content>
     <implementation>
       <!-- Popup rollup is triggered by native events before the mousedown event
            reaches the DOM. The will be set to true by the popuphiding event and
            false after the mousedown event has been triggered to detect what
            caused rollup. -->
       <field name="_isHiding">false</field>
       <field name="_bundle">null</field>
@@ -1421,17 +1428,23 @@
           let header = document.getAnonymousElementByAttribute(this, "anonid",
                                                                "search-panel-one-offs-header")
           // header is a xul:deck so collapsed doesn't work on it, see bug 589569.
           header.hidden = list.collapsed = !engines.length;
 
           if (!engines.length)
             return;
 
-          let panelWidth = parseInt(this.popup.clientWidth);
+          let panelWidth = parseInt(this.popup.clientWidth, 10);
+          let container = this.popup.boxObject.firstChild;
+          if (container) {
+            let containerCS = getComputedStyle(container);
+            panelWidth -= parseInt(containerCS.marginLeft, 10);
+            panelWidth -= parseInt(containerCS.marginRight, 10);
+          }
           // The + 1 is because the last button doesn't have a right border.
           let enginesPerRow = Math.floor((panelWidth + 1) / this.buttonWidth);
           let buttonWidth = Math.floor(panelWidth / enginesPerRow);
           // There will be an emtpy area of:
           //   panelWidth - enginesPerRow * buttonWidth  px
           // at the end of each row.
 
           // If the <description> tag with the list of search engines doesn't have
--- a/browser/themes/shared/urlbarSearchSuggestionsNotification.inc.css
+++ b/browser/themes/shared/urlbarSearchSuggestionsNotification.inc.css
@@ -1,54 +1,77 @@
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] {
+
+%ifdef XP_WIN
+#PopupAutoCompleteRichResult {
+  /* Don't move the margin up the full 4px because we want to make sure
+     the bottom border of the navigation toolbar is visible. */
+  margin-top: -3px;
+  /* This value is duplicated in urlbarBindings.xml */
+  margin-inline-start: -4px;
+  margin-inline-end: -4px;
+  background: transparent;
+  -moz-appearance: none;
+  border: none;
+}
+
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] {
+  background-color: -moz-Field;
+  background-clip: padding-box;
+  border: 1px solid var(--arrowpanel-border-color);
+  box-shadow: 0 0 4px hsla(0,0%,0%,.2);
+  margin: 4px;
+}
+%endif
+
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] {
   border-bottom: 1px solid var(--panel-separator-color);
   background-color: hsla(210, 4%, 10%, 0.07);
   padding: 6px 0;
   padding-inline-start: 44px;
   padding-inline-end: 6px;
   background-image: url("chrome://browser/skin/info.svg");
   background-clip: padding-box;
   background-position: 20px center;
   background-repeat: no-repeat;
   background-size: 16px 16px;
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"]:-moz-locale-dir(rtl) {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"]:-moz-locale-dir(rtl) {
   background-position: right 20px center;
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > description {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] > description {
   margin: 0;
   padding: 0;
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > description > label.text-link {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] > description > label.text-link {
   margin-inline-start: 0;
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] > button {
   -moz-appearance: none;
   min-width: 80px;
   border-radius: 3px;
   padding: 4px 16px;
   margin: 0;
   margin-inline-start: 10px;
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-disable"] {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-disable"] {
   color: hsl(210, 0%, 38%);
   background-color: hsl(210, 0%, 88%);
   border: 1px solid hsl(210, 0%, 82%);
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-disable"]:hover {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-disable"]:hover {
   background-color: hsl(210, 0%, 84%);
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-enable"] {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-enable"] {
   color: white;
   background-color: hsl(93, 82%, 44%);
   border: 1px solid hsl(93, 82%, 44%);
 }
 
-#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-enable"]:hover {
+#PopupAutoCompleteRichResult > vbox[anonid="urlbar-rich-result-popup-container"] > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-enable"]:hover {
   background-color: hsl(93, 82%, 40%);
 }
--- a/browser/themes/windows/searchbar.css
+++ b/browser/themes/windows/searchbar.css
@@ -2,20 +2,34 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #PopupSearchAutoComplete {
   /* JS code forces the panel to have the width of the searchbar rather than
    * the width of the textfield. Alignment of the panel with the searchbar is
    * obtained with negative margins here: margin-inline-start when the text
    * field is in the same direction as the rest of the UI, margin-inline-end
-   * when the textfield's direction has been reversed.
-   * (eg. using ctrl+shift+X) */
-  margin-inline-start: -25px;
-  margin-inline-end: -18px;
+   * when the textfield's direction has been reversed (eg. using ctrl+shift+X).
+   * 4 of the pixels in both directions come from the negative margin necessary
+   * to compensate for the box-shadow of the inner container. This value is
+   * duplicated in search.xml */
+  margin-inline-start: -29px;
+  margin-inline-end: -24px;
+  margin-top: -4px;
+  background: transparent;
+  -moz-appearance: none;
+  border: none;
+}
+
+#PopupSearchAutoComplete > .autocomplete-popup-container {
+  background-color: -moz-Field;
+  background-clip: padding-box;
+  border: 1px solid var(--arrowpanel-border-color);
+  box-shadow: 0 0 4px hsla(0,0%,0%,.2);
+  margin: 4px;
 }
 
 .autocomplete-textbox-container {
   -moz-box-align: stretch;
 }
 
 .textbox-input-box {
   margin: 0;
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -1494,17 +1494,20 @@ extends="chrome://global/content/binding
             let parts = [
               this.getAttribute("title"),
               this.getAttribute("displayurl"),
             ];
             let label = parts.filter(str => str).join(" ")
 
             // allow consumers that have extended popups to override
             // the label values for the richlistitems
-            let panel = this.parentNode.parentNode;
+            let panel = this;
+            while (panel && panel.localName != "panel") {
+              panel = panel.parentNode;
+            }
             if (panel.createResultLabel) {
               return panel.createResultLabel(this, label);
             }
 
             return label;
           ]]>
         </getter>
       </property>
@@ -1866,17 +1869,20 @@ extends="chrome://global/content/binding
           return this._textToSubURI.unEscapeURIForUI("UTF-8", url);
           ]]>
         </body>
       </method>
 
       <method name="_adjustAcItem">
         <body>
           <![CDATA[
-          let popup = this.parentNode.parentNode;
+          let popup = this;
+          while (popup && popup.localName != "panel") {
+            popup = popup.parentNode;
+          }
           if (!popup.popupOpen) {
             // Removing the max-width and resetting it later when overflow is
             // handled is jarring when the item is visible, so skip this when
             // the popup is open.
             this._removeMaxWidths();
           }
 
           let title = this.getAttribute("title");
@@ -2259,17 +2265,21 @@ extends="chrome://global/content/binding
         let item = event.originalTarget;
         while (item && item.localName != "richlistitem") {
           item = item.parentNode;
         }
 
         if (!item)
           return;
 
-        this.parentNode.onPopupClick(event);
+        let popup = this;
+        while (popup && popup.localName != "panel") {
+          popup = popup.parentNode;
+        }
+        popup.onPopupClick(event);
       ]]>
       </handler>
 
       <handler event="mousemove">
         <![CDATA[
         if (Date.now() - this.mLastMoveTime > 30) {
          let item = event.target;
          while (item && item.localName != "richlistitem") {
@@ -2292,17 +2302,23 @@ extends="chrome://global/content/binding
   </binding>
 
   <binding id="autocomplete-treebody">
     <implementation>
       <field name="mLastMoveTime">Date.now()</field>
     </implementation>
 
     <handlers>
-      <handler event="mouseup" action="this.parentNode.parentNode.onPopupClick(event);"/>
+      <handler event="mouseup"><![CDATA[
+        let popup = this;
+        while (popup && popup.localName != "panel") {
+          popup = popup.parentNode;
+        }
+        popup.onPopupClick(event);
+      ]]></handler>
 
       <handler event="mousedown"><![CDATA[
          var rc = this.parentNode.treeBoxObject.getRowAt(event.clientX, event.clientY);
          if (rc != this.parentNode.currentIndex)
             this.parentNode.view.selection.select(rc);
       ]]></handler>
 
       <handler event="mousemove"><![CDATA[