Bug 507391: noscript addon causes select box rendering to fail in fennec [r=mark.finkle]
authorVivien Nicolas <21@vingtetun.org>
Sat, 28 Nov 2009 00:37:01 -0500
changeset 65855 2c922f0e9629136c7262ca6c451fbe1042e2d393
parent 65854 bff84b65b812ab696dc9a935bcc695fd031f7b29
child 65856 fbc12019553b11824ebefe7b309d93ba8f2c552e
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmark.finkle
bugs507391
Bug 507391: noscript addon causes select box rendering to fail in fennec [r=mark.finkle]
mobile/chrome/content/bindings.xml
mobile/chrome/content/browser-ui.js
mobile/chrome/content/browser.js
mobile/chrome/content/content.css
--- a/mobile/chrome/content/bindings.xml
+++ b/mobile/chrome/content/bindings.xml
@@ -893,64 +893,16 @@
       
           this.focus();
           SelectHelper.show(this);
         ]]>
       </handler>
     </handlers>
   </binding>
 
-  <binding id="chrome-input">
-    <content>
-      <children />
-    </content>
-    <handlers>
-      <handler event="click" button="0">
-        <![CDATA[
-          var showEvent = document.createEvent("Events");
-          showEvent.initEvent("UIShowForm", true, false);
-          this.dispatchEvent(showEvent);
-        ]]>
-      </handler>
-    </handlers>
-  </binding>
-
-  <binding id="chrome-select">
-    <content>
-      <children />
-    </content>
-
-    <implementation>
-      <property name="selectElement"
-                onget="return this.QueryInterface(Components.interfaces.nsISelectElement);"
-                readonly="true"/>
-    </implementation>
-
-    <handlers>
-      <handler event="mousedown" button="0" phase="capturing">
-        <![CDATA[
-          event.stopPropagation();
-          event.preventDefault();
-        ]]>
-      </handler>
-
-      <handler event="click" button="0">
-        <![CDATA[
-          let options = this.options;
-          if (options.length == 0)
-            return;
-      
-          var showEvent = document.createEvent("Events");
-          showEvent.initEvent("UIShowForm", true, false);
-          this.dispatchEvent(showEvent);
-        ]]>
-      </handler>
-    </handlers>
-  </binding>
-
   <binding id="chrome-select-option">
     <content orient="horizontal" flex="1">
       <xul:image anonid="check"/>
       <xul:label anonid="label" xbl:inherits="value=label"/>
     </content>
 
     <implementation>
       <property name="selected">
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -388,17 +388,16 @@ var BrowserUI = {
     document.getElementById("toolbar-main").ignoreDrag = true;
 
     let tabs = document.getElementById("tabs");
     tabs.addEventListener("TabSelect", this, true);
     tabs.addEventListener("TabOpen", this, true);
 
     let browsers = document.getElementById("browsers");
     browsers.addEventListener("DOMWindowClose", this, true);
-    browsers.addEventListener("UIShowForm", this, false, true);
 
     // XXX these really want to listen to only the current browser
     browsers.addEventListener("DOMTitleChanged", this, true);
     browsers.addEventListener("DOMLinkAdded", this, true);
     browsers.addEventListener("DOMWillOpenModalDialog", this, true);
     
     // listening mousedown for automatically dismiss some popups (e.g. larry)
     window.addEventListener("mousedown", this, true);
@@ -635,19 +634,16 @@ var BrowserUI = {
         this._titleChanged(aEvent.target);
         break;
       case "DOMLinkAdded":
         this._linkAdded(aEvent);
         break;
       case "DOMWindowClose":
         this._domWindowClose(aEvent);
         break;
-      case "UIShowForm":
-        FormHelper.open(aEvent.target);
-        break;
       case "TabSelect":
         this._tabSelect(aEvent);
         break;
       case "TabOpen":
         if (!this.isTabsVisible() && 
             Browser.selectedTab.chromeTab != aEvent.target)
           NewTabPopup.show(aEvent.target);
         break;
@@ -1277,16 +1273,21 @@ var FormHelper = {
   zoom: function formHelperZoom(aElement) {
     let zoomLevel = Browser._getZoomLevelForElement(aElement);
     zoomLevel = Math.min(Math.max(kBrowserFormZoomLevelMin, zoomLevel), kBrowserFormZoomLevelMax);
 
     let elRect = this._getRectForElement(aElement);
     let zoomRect = Browser._getZoomRectForPoint(elRect.center().x, elRect.y, zoomLevel);
 
     Browser.setVisibleRect(zoomRect);
+  },
+
+  canShowUIFor: function(aElement) {
+    return (this._isValidElement(aElement) && 
+            !(aElement instanceof HTMLInputElement && aElement.type == "submit"));
   }
 };
 
 function SelectWrapper(aControl) {
   this._control = aControl;
 }
 
 SelectWrapper.prototype = {
@@ -1294,22 +1295,22 @@ SelectWrapper.prototype = {
   get multiple() { return this._control.multiple; },
   get options() { return this._control.options; },
   get children() { return this._control.children; },
   
   getText: function(aChild) { return aChild.text; },
   isOption: function(aChild) { return aChild instanceof HTMLOptionElement; },
   isGroup: function(aChild) { return aChild instanceof HTMLOptGroupElement; },
   select: function(aIndex, aSelected, aClearAll) {
-    let selectElement = this._control.wrappedJSObject.selectElement;
+    let selectElement = this._control.QueryInterface(Ci.nsISelectElement);
     selectElement.setOptionsSelectedByIndex(aIndex, aIndex, aSelected, aClearAll, false, true);
   },
   focus: function() { this._control.focus(); },
   fireOnChange: function() {
-    let control = this._control.wrappedJSObject;
+    let control = this._control;
     let evt = document.createEvent("Events");
     evt.initEvent("change", true, true, window, 0,
                   false, false,
                   false, false, null);
     control.dispatchEvent(evt); 
   }
 };
 
@@ -1471,24 +1472,23 @@ var SelectHelper = {
       }
     }
 
     if (!isIdentical) 
       this._control.fireOnChange();
   },
 
   reset: function() {
+    this._updateControl();
     let empty = this._list.cloneNode(false);
     this._list.parentNode.replaceChild(empty, this._list);
     this._list = empty;
   },
 
   close: function() {
-    this._updateControl();
-
     this._list.removeEventListener("click", this, false);
     this._panel.hidden = true;
     
     this.reset();
   },
 
   handleEvent: function(aEvent) {
     switch (aEvent.type) {
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -1570,23 +1570,31 @@ ContentCustomClicker.prototype = {
 
     mouseDown: function mouseDown(cX, cY) {
     },
 
     mouseUp: function mouseUp(cX, cY) {
     },
 
     singleClick: function singleClick(cX, cY, modifiers) {
+      let [elementX, elementY] = Browser.transformClientToBrowser(cX, cY);
+      let element = Browser.elementFromPoint(elementX, elementY);
       if (modifiers == 0) {
+        if (element instanceof HTMLOptionElement)
+          element = element.parentNode;
+
+        if (FormHelper.canShowUIFor(element)) {
+          FormHelper.open(element);
+          return;
+        }
+
         this._dispatchMouseEvent("mousedown", cX, cY);
         this._dispatchMouseEvent("mouseup", cX, cY);
       }
       else if (modifiers == Ci.nsIDOMNSEvent.CONTROL_MASK) {
-        let [elementX, elementY] = Browser.transformClientToBrowser(cX, cY);
-        let element = Browser.elementFromPoint(elementX, elementY);
         let uri = Util.getHrefForElement(element);
         if (uri)
           Browser.addTab(uri, false);
       }
     },
 
     doubleClick: function doubleClick(cX1, cY1, cX2, cY2) {
       const kDoubleClickRadius = 32;
--- a/mobile/chrome/content/content.css
+++ b/mobile/chrome/content/content.css
@@ -49,29 +49,16 @@ scrollbarbutton {
 thumb {
   min-width: 10px !important;
   -moz-appearance: none !important;
   background-color: gray !important;
   border: 1px solid gray !important;
   -moz-border-radius: 4px !important;
 }
 
-textarea,
-input:not(type),
-input[type=""],
-input[type="file"],
-input[type="password"],
-input[type="text"] {
-  -moz-binding: url("chrome://browser/content/bindings.xml#chrome-input");
-}
-
-select {
-  -moz-binding: url("chrome://browser/content/bindings.xml#chrome-select");
-}
-
 select:not([size]) > scrollbar,
 select[size="1"] > scrollbar,
 select:not([size]) scrollbarbutton,
 select[size="1"] scrollbarbutton {
   display:block !important;
 }
 
 /* Override inverse OS themes */