Bug 472426: listbox is rendered outside the fennec window, r=gavin
authorMark Finkle <mfinkle@mozilla.com>
Wed, 24 Jun 2009 12:42:53 -0400
changeset 596 70e9519cada3a736a08c69c74f93544f0f52fe48
parent 595 858b1bf0f8934b75dbd2f9680fe590c5c0c78749
child 597 87ef0915a1d63eb2c91ff847025a83a9f8ce7d1f
push id532
push usermfinkle@mozilla.com
push dateWed, 24 Jun 2009 16:44:17 +0000
reviewersgavin
bugs472426
Bug 472426: listbox is rendered outside the fennec window, r=gavin
chrome/content/bindings.xml
chrome/content/browser-ui.js
chrome/content/browser.css
chrome/content/browser.js
chrome/content/browser.xul
chrome/content/content.css
chrome/content/cursor.css
chrome/content/scrollbars.css
chrome/jar.mn
locales/en-US/chrome/browser.dtd
themes/hildon/browser.css
themes/hildon/images/check-default-30.png
themes/hildon/jar.mn
themes/wince/browser.css
themes/wince/images/check-default-30.png
themes/wince/jar.mn
--- a/chrome/content/bindings.xml
+++ b/chrome/content/bindings.xml
@@ -958,9 +958,184 @@
             // the placetree onselect handler. We don't need to explicitly fire
             // anything here.
           ]]>
         </body>
       </method>
     </implementation>
   </binding>
 
+  <binding id="chrome-select" extends="xul:menu">
+    <content orient="horizontal">
+      <xul:hbox class="select-label-box" flex="1">
+        <xul:label anonid="select-label" flex="1" value="" xbl:inherits="value=label"/>
+      </xul:hbox>
+      <xul:dropmarker class="select-dropmarker" type="menu"/>
+      <xul:vbox anonid="select-options" collapsed="true">
+        <children/>
+      </xul:vbox>
+    </content>
+
+    <implementation>
+      <constructor>
+        <![CDATA[
+          // XXX I wish this worked
+          // Bug 500206
+          let options = document.getAnonymousElementByAttribute(this, "anonid", "select-options");
+          let rect = options.getBoundingClientRect();
+          this._label.width = rect.width;
+
+          // Display any pre-selected option
+          this._updateLabel();
+        ]]>
+      </constructor>
+
+      <field name="_displayFormat">"&selectListDisplay.format;"</field>
+
+      <field name="_label">
+        document.getAnonymousElementByAttribute(this, "anonid", "select-label");
+      </field>
+
+      <field name="_originalIndex">
+        -1
+      </field>
+
+      <property name="selectElement" readonly="true">
+        <getter>
+          <![CDATA[
+            return this.QueryInterface(Components.interfaces.nsISelectElement);
+          ]]>
+        </getter>
+      </property>
+
+      <method name="_updateLabel">
+        <body>
+          <![CDATA[
+            let label = "";
+            if (this.multiple) {
+              let selected = 0;
+              let options = this.options;
+              for (let i = 0; i < options.length; i++) {
+                if (options[i].selected)
+                  selected++;
+              }
+
+              label = this._displayFormat.replace(/#1/, selected);
+            } else {
+              let index = this.selectedIndex;
+              if (index != -1)
+                label = this.options[index].text;
+            }
+            this._label.value = label;
+          ]]>
+        </body>
+      </method>
+
+      <method name="_fireChange">
+        <body>
+          <![CDATA[
+            let changeEvent = document.createEvent("Events");
+            changeEvent.initEvent("change", true, false);
+            this.dispatchEvent(changeEvent);
+
+            this._originalIndex = this.selectedIndex;
+          ]]>
+        </body>
+      </method>
+    </implementation>
+
+    <handlers>
+      <handler event="keypress" keycode="VK_UP">
+        <![CDATA[
+          let options = this.options;
+          if (options.length == 0)
+            return;
+
+          let index = this.selectedIndex;
+          if (index == -1) {
+            index = 0;
+          }
+          else {
+            index--;
+            if (index < 0)
+              index = options.length - 1;
+          }
+          this.selectedIndex = index;
+        ]]>
+      </handler>
+
+      <handler event="keypress" keycode="VK_DOWN">
+        <![CDATA[
+          let options = this.options;
+          if (options.length == 0)
+            return;
+
+          let index = this.selectedIndex;
+          if (index == -1) {
+            index = 0;
+          }
+          else {
+            index++;
+            if (index >= options.length)
+              index = 0;
+          }
+          this.selectedIndex = index;
+        ]]>
+      </handler>
+
+      <handler event="click" button="0">
+        <![CDATA[
+          let options = this.options;
+          if (options.length == 0)
+            return;
+
+          this.focus();
+
+          var showEvent = document.createEvent("Events");
+          showEvent.initEvent("UIShowSelect", true, false);
+          this.dispatchEvent(showEvent);
+        ]]>
+      </handler>
+
+      <handler event="focus">
+        <![CDATA[
+          this._originalIndex = this.selectedIndex;
+        ]]>
+      </handler>
+
+      <handler event="blur">
+        <![CDATA[
+          if (this._originalIndex != this.selectedIndex) {
+            this._updateLabel();
+            this._fireChange();
+          }
+        ]]>
+      </handler>
+
+    </handlers>
+  </binding>
+
+  <binding id="chrome-select-option">
+    <content orient="hortizontal" flex="1">
+      <xul:image anonid="check"/>
+      <xul:label anonid="label" xbl:inherits="value=label"/>
+    </content>
+
+    <implementation>
+      <property name="selected">
+        <getter>
+          <![CDATA[
+            return this.hasAttribute("selected");
+          ]]>
+        </getter>
+        <setter>
+          <![CDATA[
+            if (val)
+              this.setAttribute("selected", "true");
+            else
+              this.removeAttribute("selected");
+            return val;
+          ]]>
+        </setter>
+      </property>
+    </implementation>
+  </binding>
 </bindings>
--- a/chrome/content/browser-ui.js
+++ b/chrome/content/browser-ui.js
@@ -258,16 +258,17 @@ var BrowserUI = {
     this._favicon = document.getElementById("urlbar-favicon");
     this._favicon.addEventListener("error", this, false);
     this._autocompleteNavbuttons = document.getElementById("autocomplete_navbuttons");
 
     // XXX these really want to listen whatever is the current browser, not any browser
     let browsers = document.getElementById("browsers");
     browsers.addEventListener("DOMTitleChanged", this, true);
     browsers.addEventListener("DOMLinkAdded", this, true);
+    browsers.addEventListener("UIShowSelect", this, false, true);
 
     document.getElementById("tabs").addEventListener("TabSelect", this, true);
 
     ExtensionsView.init();
     DownloadsView.init();
   },
 
   uninit : function() {
@@ -485,16 +486,19 @@ var BrowserUI = {
     switch (aEvent.type) {
       // Browser events
       case "DOMTitleChanged":
         this._titleChanged(aEvent.target);
         break;
       case "DOMLinkAdded":
         this._linkAdded(aEvent);
         break;
+      case "UIShowSelect":
+        SelectHelper.show(aEvent.target);
+        break;
       case "TabSelect":
         this._tabSelect(aEvent);
         break;
       // URL textbox events
       case "click":
         this.doCommand("cmd_openLocation");
         break;
       case "keypress":
@@ -771,8 +775,134 @@ var FolderPicker = {
     if (folders.selectedItem.itemId != folderId) {
       PlacesUtils.bookmarks.moveItem(itemId, folders.selectedItem.itemId, PlacesUtils.bookmarks.DEFAULT_INDEX);
       if (this._control.removeItem)
         this._control.removeItem(this._control.activeItem);
     }
     this.close();
   }
 };
+
+var SelectHelper = {
+  _panel: null,
+  _list: null,
+  _control: null,
+  _selectedIndex: -1,
+
+  show: function(aControl) {
+    if (!aControl)
+      return;
+
+    this._control = aControl;
+    this._selectedIndex = this._control.selectedIndex;
+
+    this._list = document.getElementById("select-list");
+    this._list.setAttribute("multiple", this._control.multiple ? "true" : "false")
+
+    let optionIndex = 0;
+    let children = this._control.children;
+    for (let i=0; i<children.length; i++) {
+      let child = children[i];
+      if (child instanceof HTMLOptGroupElement) {
+        let group = document.createElement("option");
+        group.setAttribute("label", child.label)
+        this._list.appendChild(group);
+        group.className = "optgroup";
+
+        let subchildren = child.children;
+        for (let ii=0; ii<subchildren.length; ii++) {
+          let subchild = subchildren[ii];
+          let item = document.createElement("option");
+          item.setAttribute("label", subchild.text)
+          this._list.appendChild(item);
+          item.className = "in-optgroup";
+          item.optionIndex = optionIndex++;
+          if (subchild.selected)
+            item.setAttribute("selected", "true");
+        }
+      } else if (child instanceof HTMLOptionElement) {
+        let item = document.createElement("option");
+        item.setAttribute("label", child.textContent)
+        this._list.appendChild(item);
+        item.optionIndex = optionIndex++;
+        if (child.selected)
+          item.setAttribute("selected", "true");
+      }
+    }
+
+    this._panel = document.getElementById("select-container");
+
+    let toolbar = document.getElementById("toolbar-main");
+    let top = parseInt(toolbar.top) + toolbar.boxObject.height;
+    if (top < 0)
+      top = 0;
+
+    this._panel.top = top + 20;
+    this._panel.left = 20;
+    this._panel.width = window.innerWidth - 40;
+    this._panel.height = window.innerHeight - (top + 40);
+    this._panel.hidden = false;
+
+    this._list.focus();
+    this._list.addEventListener("click", this, false);
+  },
+
+  _forEachOption: function(aCallback) {
+      let children = this._list.children;
+      for (let i = 0; i < children.length; i++) {
+        let item = children[i];
+        if (!item.hasOwnProperty("optionIndex"))
+          continue;
+        aCallback(item);
+      }
+  },
+
+  _updateControl: function() {
+    // XXX For "multiple", we could check to see if the selected items were
+    // different than the original set of selected items
+    if (this._control.multiple || this._selectedIndex != this._control.selectedIndex)
+      this._control.wrappedJSObject._fireChange();
+  },
+
+  close: function() {
+    this._updateControl();
+
+    this._list.removeEventListener("click", this, false);
+    this._panel.hidden = true;
+
+    // Clear out the list for the next show
+    let empty = this._list.cloneNode(false);
+    this._list.parentNode.replaceChild(empty, this._list);
+    this._list = empty;
+
+    this._control.focus();
+  },
+
+  handleEvent: function(aEvent) {
+    switch (aEvent.type) {
+      case "click":
+        let item = aEvent.target;
+        let selectElement = this._control.wrappedJSObject.selectElement;
+        if (item && item.hasOwnProperty("optionIndex")) {
+          if (this._control.multiple) {
+            // Toggle the item state
+            item.selected = !item.selected;
+            selectElement.setOptionsSelectedByIndex(item.optionIndex, item.optionIndex, item.selected, false, false, true);
+            this._control.wrappedJSObject._updateLabel();
+          }
+          else {
+            // Unselect all options
+            this._forEachOption(
+              function(aItem) {
+                aItem.selected = false;
+              }
+            );
+
+            // Select the new one and update the control
+            item.selected = true;
+            selectElement.setOptionsSelectedByIndex(item.optionIndex, item.optionIndex, true, true, false, true);
+            this._control.wrappedJSObject._updateLabel();
+          }
+        }
+        break;
+    }
+  }
+};
--- a/chrome/content/browser.css
+++ b/chrome/content/browser.css
@@ -91,16 +91,20 @@ richlistitem[typeName="local"] {
 richlistitem[typeName="search"] {
   -moz-binding: url("chrome://browser/content/bindings/extensions.xml#extension-search");
 }
 
 richlistitem[typeName="message"] {
   -moz-binding: url("chrome://browser/content/bindings/extensions.xml#extension-message");
 }
 
+#select-list > option {
+  -moz-binding: url("chrome://browser/content/bindings.xml#chrome-select-option");
+}
+
 /* richlist defaults ------------------------------------------------------- */
 richlistitem {
   padding: 5px;
   border-bottom: 1px solid rgb(207,207,207);
 }
 
 richlistitem label.title,
 richlistitem description.title {
--- a/chrome/content/browser.js
+++ b/chrome/content/browser.js
@@ -78,17 +78,17 @@ var Browser = {
     this._canvasBrowser = new CanvasBrowser(document.getElementById("browser-canvas"));
 
     // initialize the WidgetStack
     let browserContainer = document.getElementById("browser-container");
     ws = new WidgetStack(browserContainer);
 
     // during startup a lot of viewportHandler calls happen due to content and window resizes
     ws.beginUpdateBatch();
-    
+
     function panHandler(vr, dx, dy) {
       if (dx) {
         let visibleNow = ws.isWidgetVisible("tabs-container") || ws.isWidgetVisible("browser-controls");
         let isToolbarFrozen = ws.isWidgetFrozen('toolbar-main');
         if (visibleNow && !isToolbarFrozen) {
           BrowserUI.showToolbar(URLBAR_FORCE);
         }
         else if (!visibleNow && isToolbarFrozen) {
@@ -111,17 +111,17 @@ var Browser = {
         return;
 
       let w = window.innerWidth;
       let maximize = (document.documentElement.getAttribute("sizemode") == "maximized");
       if (maximize && w > screen.width)
         return;
 
       let h = window.innerHeight;
-      
+
       // Tell the UI to resize the browser controls before calling  updateSize
       BrowserUI.sizeControls(w, h);
 
       // Resize our container...
       let containerStyle = browserContainer.style;
       containerStyle.width = containerStyle.maxWidth = w + "px";
       containerStyle.height = containerStyle.maxHeight = h + "px";
 
@@ -129,17 +129,17 @@ var Browser = {
       let browsers = Browser.browsers;
       if (browsers) {
         let scaledH = (kDefaultBrowserWidth * (h / w));
         for (let i=0; i<browsers.length; i++) {
           let browserStyle = browsers[i].style;
           browserStyle.height = scaledH + "px";
         }
       }
-      
+
       ws.updateSize(w, h);
     }
     window.addEventListener("resize", resizeHandler, false);
 
     function viewportHandler(bounds, boundsSizeChanged) {
       self._canvasBrowser.viewportHandler(bounds, boundsSizeChanged);
     }
     ws.setViewportHandler(viewportHandler);
@@ -155,22 +155,22 @@ var Browser = {
     var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
     var styleSheets = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
 
     // Should we hide the cursors
     var hideCursor = gPrefService.getBoolPref("browser.ui.cursor") == false;
     if (hideCursor) {
       window.QueryInterface(Ci.nsIDOMChromeWindow).setCursor("none");
 
-      var styleURI = ios.newURI("chrome://browser/content/content.css", null, null);
+      var styleURI = ios.newURI("chrome://browser/content/cursor.css", null, null);
       styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
     }
 
     // load styles for scrollbars
-    var styleURI = ios.newURI("chrome://browser/content/scrollbars.css", null, null);
+    var styleURI = ios.newURI("chrome://browser/content/content.css", null, null);
     styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
 
     var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
     os.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false);
     os.addObserver(gXPInstallObserver, "xpinstall-download-started", false);
     os.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
 
     // XXX hook up memory-pressure notification to clear out tab browsers
@@ -230,17 +230,17 @@ var Browser = {
           if (whereURI)
             whereURI = whereURI.spec;
         }
       } catch (e) {}
 
       if (whereURI)
         this.addTab(whereURI, true);
     }
-    
+
     // JavaScript Error Console
     if (gPrefService.getBoolPref("browser.console.showInPanel")){
       let tool_console = document.getElementById("tool-console");
       tool_console.hidden = false;
     }
 
     // Re-enable plugins if we had previously disabled them. We should get rid of
     // this code eventually...
@@ -1237,17 +1237,17 @@ ProgressController.prototype = {
 
     if (Browser.selectedBrowser == this.browser) {
       Browser.canvasBrowser.endLoading();
       BrowserUI.update(TOOLBARSTATE_LOADED);
       this.browser.docShell.isOffScreenBrowser = true;
       if (Browser._isStartup) {
         // force the urlbar into position
         ws.panTo(0, -BrowserUI.toolbarH);
-        
+
         // now we can set the viewport to a real size and draw the page
         ws.endUpdateBatch();
         Browser._isStartup = false;
       }
     }
 
     this._tab.updateThumbnail();
   },
@@ -1362,17 +1362,17 @@ Tab.prototype = {
 
     // Create the browser using the current width the dynamically size the height
     let scaledHeight = kDefaultBrowserWidth * (window.innerHeight / window.innerWidth);
     let browser = this._browser = document.createElement("browser");
     browser.setAttribute("style", "overflow: hidden; visibility: hidden; width: " + kDefaultBrowserWidth + "px; height: " + scaledHeight + "px;");
     browser.setAttribute("type", "content");
     browser.setAttribute("src", uri);
 
-    // Attach the popup contextmenu    
+    // Attach the popup contextmenu
     let canvas = document.getElementById("browser-canvas");
     browser.setAttribute("contextmenu", canvas.getAttribute("contextmenu"));
     let autocompletepopup = canvas.getAttribute("autocompletepopup");
     if (autocompletepopup)
       browser.setAttribute("autocompletepopup", autocompletepopup);
 
     // Append the browser to the document, which should start the page load
     document.getElementById("browsers").appendChild(browser);
--- a/chrome/content/browser.xul
+++ b/chrome/content/browser.xul
@@ -168,17 +168,17 @@
     <key id="key_findAgain" key="&findAgainCmd.commandkey;" command="cmd_findAgain" modifiers="accel"/>
     <key id="key_findPrevious" key="&findAgainCmd.commandkey;" command="cmd_findPrevious" modifiers="accel shift"/>
     <key keycode="&findAgainCmd.commandkey2;" command="cmd_findAgain"/>
     <key keycode="&findAgainCmd.commandkey2;"  command="cmd_findPrevious" modifiers="shift"/>
   </keyset>
 
   <popupset id="mainPopupSet">
   </popupset>
-  
+
   <!-- stupid stack needs to be in a box. not sure why -->
   <box>
   <stack id="browser-container" flex="1">
 
     <!-- begin: Browser View -->
     <hbox id="canvasbox"
           left="0" top="-480"
           vptargetx="0"
@@ -401,16 +401,23 @@
                       align="center"
                       flex="1"
                       orient="horizontal"
                       oncommand="BrowserUI.doButtonSearch(event.target);">
         <image class="tool-search"/>
       </arrowscrollbox>
     </vbox>
 
+    <vbox id="select-container" class="panel-dark" hidden="true" top="0" left="0">
+      <scrollbox id="select-list" flex="1" orient="vertical"/>
+      <hbox id="select-buttons">
+        <button label="&selectListDone.label;" oncommand="SelectHelper.close();"/>
+      </hbox>
+    </vbox>
+
     <vbox id="bookmarklist-container" class="panel-dark" hidden="true" top="0" left="0">
       <hbox id="bookmarklist-header">
         <description flex="1">&bookmarksHeader.label;</description>
         <toolbarbutton id="tool-bookmarks-manage" class="urlbar-button show-text button-dark" type="check" autocheck="true" label="&bookmarksManage.label;"
                        oncommand="BookmarkList.toggleManage();"/>
         <toolbarbutton id="tool-bookmarks-close" class="urlbar-button button-image" type="check" checked="true"
                        oncommand="BookmarkList.close();"/>
       </hbox>
--- a/chrome/content/content.css
+++ b/chrome/content/content.css
@@ -1,42 +1,90 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Mobile Browser.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Mark Finkle <mfinkle@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-@namespace html url(http://www.w3.org/1999/xhtml);
-
-html|* {
-  cursor: none !important;
-}
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Style the scrollbars */
+scrollbar {
+  -moz-appearance: none !important;
+  display: none !important;
+}
+
+scrollbarbutton {
+  -moz-appearance: none !important;
+  display: none !important;
+}
+
+thumb {
+  min-width: 10px !important;
+  -moz-appearance: none !important;
+  background-color: gray !important;
+  border: 1px solid gray !important;
+  -moz-border-radius: 4px !important;
+}
+
+select {
+  -moz-binding: url("chrome://browser/content/bindings.xml#chrome-select");
+  -moz-user-focus: normal;
+
+  margin: 2px 4px;
+  border: 2px solid;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+  -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+  -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
+  background-color: -moz-Field;
+  color: -moz-FieldText;
+}
+
+.select-label-box {
+  -moz-box-align: center;
+  -moz-box-pack: center;
+  margin: 1px;
+  border: 1px solid transparent;
+}
+
+select:focus > .select-label-box {
+  border: 1px dotted #F5DB95;
+  background-color: Highlight;
+  color: HighlightText;
+}
+
+select[disabled] > .select-label-box {
+  -moz-user-input: disabled;
+  -moz-user-focus: ignore;
+  color: GrayText;
+  background-color: ThreeDFace;
+  cursor: inherit;
+}
new file mode 100644
--- /dev/null
+++ b/chrome/content/cursor.css
@@ -0,0 +1,42 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+@namespace html url(http://www.w3.org/1999/xhtml);
+
+html|* {
+  cursor: none !important;
+}
deleted file mode 100644
--- a/chrome/content/scrollbars.css
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Mobile Browser.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Mark Finkle <mfinkle@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* Style the scrollbars */
-scrollbar {
-  -moz-appearance: none !important;
-  /*background-color: transparent !important;*/
-  display: none !important;
-}
-
-scrollbarbutton {
--moz-appearance: none !important;
-  display: none !important;
-}
-
-thumb {
-  min-width: 10px !important;
-  -moz-appearance: none !important;
-  background-color: gray !important;
-  border: 1px solid gray !important;
-  -moz-border-radius: 4px !important;
-}
--- a/chrome/jar.mn
+++ b/chrome/jar.mn
@@ -9,17 +9,17 @@ browser.jar:
   content/bindings.xml                 (content/bindings.xml)
   content/tabs.xml                     (content/tabs.xml)
   content/checkbox.xml                 (content/checkbox.xml)
   content/notification.xml             (content/notification.xml)
   content/bindings/extensions.xml      (content/bindings/extensions.xml)
   content/bindings/downloads.xml       (content/bindings/downloads.xml)
   content/bindings/console.xml         (content/bindings/console.xml)
   content/browser.css                  (content/browser.css)
-  content/scrollbars.css               (content/scrollbars.css)
+  content/cursor.css                   (content/cursor.css)
   content/content.css                  (content/content.css)
   content/checkerboard.png             (content/checkerboard.png)
 % content branding %content/branding/
   content/preferences/richpref.xml     (content/preferences/richpref.xml)
 * content/sanitize.xul                 (content/sanitize.xul)
 * content/sanitize.js                  (content/sanitize.js)
   content/WidgetStack.js               (content/WidgetStack.js)
   content/CanvasBrowser.js             (content/CanvasBrowser.js)
--- a/locales/en-US/chrome/browser.dtd
+++ b/locales/en-US/chrome/browser.dtd
@@ -96,8 +96,11 @@
 <!ENTITY consoleWarnings.label     "Warnings">
 <!ENTITY consoleMessages.label     "Messages">
 <!ENTITY consoleCodeEval.label     "Code:">
 <!ENTITY consoleClear.label        "Clear">
 <!ENTITY consoleEvaluate.label     "Evaluate">
 <!ENTITY consoleErrFile.label      "Source File:">
 <!ENTITY consoleErrLine.label      "Line:">
 <!ENTITY consoleErrColumn.label    "Column:">
+
+<!ENTITY selectListDone.label      "Done">
+<!ENTITY selectListDisplay.format  "#1 Items">
--- a/themes/hildon/browser.css
+++ b/themes/hildon/browser.css
@@ -603,8 +603,55 @@ richpref {
   padding: 2.2mm; /* core spacing */
   -moz-box-shadow: black 0.5mm 0.5mm 1mm;
 }
 
 #alerts-text {
   font-size: 85% !important;
   white-space: pre-wrap;
 }
+
+/* select popup ------------------------------------------------------------ */
+#select-container {
+  border: 1mm solid #36373b;
+  -moz-border-radius: 2mm;
+  padding-top: 2.2mm; /* core spacing */
+}
+
+#select-list > option {
+  color: #000;
+  background-color: #fff;
+  padding: 5px;
+  border-bottom: 1px solid rgb(207,207,207);
+  min-height: 14.4mm; /* row size */
+  -moz-box-align: center;
+}
+
+#select-list > option[selected="true"] {
+  color: #fff;
+  background-color: grey;
+}
+
+#select-list > option.optgroup {
+  font-weight: bold;
+  font-style: italic;
+}
+
+#select-list > option.optgroup > image {
+  display: none;
+}
+
+#select-list > option.in-optgroup {
+  -moz-padding-start: 4.4mm;
+}
+
+#select-buttons {
+  padding: 1.1mm 2.2mm; /* row size & core spacing */
+  -moz-box-pack: center;
+}
+
+#select-list > option > image {
+  min-width: 30px;
+}
+
+#select-list > option[selected="true"] > image {
+  list-style-image: url("chrome://browser/skin/images/check-default-30.png");
+}
new file mode 100644
index 0000000000000000000000000000000000000000..5eaef22bc78b6aa107e66af3bd0c517296c41f6d
GIT binary patch
literal 341
zc$@)M0jmCqP)<h;3K|Lk000e1NJLTq0015U0015c1^@s6J20-I0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy_en%SRCwC#*Gme+AP@l17`&8MC_P3u
zo+!8I#?p1qB^2v`f(d>`oxx3opoTCHe}fUuxot(+w?#$F1{j^OWg}*Xg%H|52I};^
z<VJmU^UHDfZRo?&93;VEjdPDLfEt$+=)-%GlY~W69IBmjdRaFQcBE`m-Gh?By(m?h
z?nbY$4j-A&W<yi>6hKP(Lg2$_gde#84SWiX@Y7oR%>^jn(`a?X1zcmkZK1_AuHYnS
zc30P?kP6M6<0?*tmJ$dWA4O}KtBKE`t&~~B)1A%%XYuRV=7LYSQtER}D5EguvUh}=
n1yt|Y|6l04N4)B%?I*whK?QMRTa+LJ00000NkvXXu0mjfPVJIW
--- a/themes/hildon/jar.mn
+++ b/themes/hildon/jar.mn
@@ -37,17 +37,17 @@ classic.jar:
   images/forward-disabled-64.png       (images/forward-disabled-64.png)
   images/downloads-default-64.png      (images/downloads-default-64.png)
   images/downloads-active-64.png       (images/downloads-active-64.png)
   images/settings-default-64.png       (images/settings-default-64.png)
   images/settings-active-64.png        (images/settings-active-64.png)
   images/preferences-default-64.png    (images/preferences-default-64.png)
   images/preferences-active-64.png     (images/preferences-active-64.png)
   images/console-default-64.png        (images/console-default-64.png)
-  images/console-active-64.png         (images/console-active-64.png)  
+  images/console-active-64.png         (images/console-active-64.png)
   images/newtab-default-64.png         (images/newtab-default-64.png)
   images/newtab-active-64.png          (images/newtab-active-64.png)
   images/leftcap-default-64.png        (images/leftcap-default-64.png)
   images/leftcap-active-64.png         (images/leftcap-active-64.png)
   images/leftcapEV-default-64.png      (images/leftcapEV-default-64.png)
   images/leftcapEV-active-64.png       (images/leftcapEV-active-64.png)
   images/leftcapSSL-default-64.png     (images/leftcapSSL-default-64.png)
   images/leftcapSSL-active-64.png      (images/leftcapSSL-active-64.png)
@@ -56,9 +56,10 @@ classic.jar:
   images/identity-64.png               (images/identity-64.png)
   images/identityEV-64.png             (images/identityEV-64.png)
   images/identitySSL-64.png            (images/identitySSL-64.png)
   images/lock-40.png                   (images/lock-40.png)
   images/unlock-40.png                 (images/unlock-40.png)
   images/tab-close.png                 (images/tab-close.png)
   images/tag-default-30.png            (images/tag-default-30.png)
   images/star-default-30.png           (images/star-default-30.png)
+  images/check-default-30.png          (images/check-default-30.png)
   images/geo-16.png                    (images/geo-16.png)
--- a/themes/wince/browser.css
+++ b/themes/wince/browser.css
@@ -603,8 +603,55 @@ richpref {
   padding: 2.2mm; /* core spacing */
   -moz-box-shadow: black 0.5mm 0.5mm 1mm;
 }
 
 #alerts-text {
   font-size: 85% !important;
   white-space: pre-wrap;
 }
+
+/* select popup ------------------------------------------------------------ */
+#select-container {
+  border: 1mm solid #36373b;
+  -moz-border-radius: 2mm;
+  padding-top: 2.2mm; /* core spacing */
+}
+
+#select-list > option {
+  color: #000;
+  background-color: #fff;
+  padding: 5px;
+  border-bottom: 1px solid rgb(207,207,207);
+  min-height: 14.4mm; /* row size */
+  -moz-box-align: center;
+}
+
+#select-list > option[selected="true"] {
+  color: #fff;
+  background-color: grey;
+}
+
+#select-list > option.optgroup {
+  font-weight: bold;
+  font-style: italic;
+}
+
+#select-list > option.optgroup > image {
+  display: none;
+}
+
+#select-list > option.in-optgroup {
+  -moz-padding-start: 4.4mm;
+}
+
+#select-buttons {
+  padding: 1.1mm 2.2mm; /* row size & core spacing */
+  -moz-box-pack: center;
+}
+
+#select-list > option > image {
+  min-width: 30px;
+}
+
+#select-list > option[selected="true"] > image {
+  list-style-image: url("chrome://browser/skin/images/check-default-30.png");
+}
new file mode 100644
index 0000000000000000000000000000000000000000..5eaef22bc78b6aa107e66af3bd0c517296c41f6d
GIT binary patch
literal 341
zc$@)M0jmCqP)<h;3K|Lk000e1NJLTq0015U0015c1^@s6J20-I0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy_en%SRCwC#*Gme+AP@l17`&8MC_P3u
zo+!8I#?p1qB^2v`f(d>`oxx3opoTCHe}fUuxot(+w?#$F1{j^OWg}*Xg%H|52I};^
z<VJmU^UHDfZRo?&93;VEjdPDLfEt$+=)-%GlY~W69IBmjdRaFQcBE`m-Gh?By(m?h
z?nbY$4j-A&W<yi>6hKP(Lg2$_gde#84SWiX@Y7oR%>^jn(`a?X1zcmkZK1_AuHYnS
zc30P?kP6M6<0?*tmJ$dWA4O}KtBKE`t&~~B)1A%%XYuRV=7LYSQtER}D5EguvUh}=
n1yt|Y|6l04N4)B%?I*whK?QMRTa+LJ00000NkvXXu0mjfPVJIW
--- a/themes/wince/jar.mn
+++ b/themes/wince/jar.mn
@@ -37,17 +37,17 @@ classic.jar:
   images/forward-disabled-64.png       (images/forward-disabled-64.png)
   images/downloads-default-64.png      (images/downloads-default-64.png)
   images/downloads-active-64.png       (images/downloads-active-64.png)
   images/settings-default-64.png       (images/settings-default-64.png)
   images/settings-active-64.png        (images/settings-active-64.png)
   images/preferences-default-64.png    (images/preferences-default-64.png)
   images/preferences-active-64.png     (images/preferences-active-64.png)
   images/console-default-64.png        (images/console-default-64.png)
-  images/console-active-64.png         (images/console-active-64.png)  
+  images/console-active-64.png         (images/console-active-64.png)
   images/newtab-default-64.png         (images/newtab-default-64.png)
   images/newtab-active-64.png          (images/newtab-active-64.png)
   images/leftcap-default-64.png        (images/leftcap-default-64.png)
   images/leftcap-active-64.png         (images/leftcap-active-64.png)
   images/leftcapEV-default-64.png      (images/leftcapEV-default-64.png)
   images/leftcapEV-active-64.png       (images/leftcapEV-active-64.png)
   images/leftcapSSL-default-64.png     (images/leftcapSSL-default-64.png)
   images/leftcapSSL-active-64.png      (images/leftcapSSL-active-64.png)
@@ -56,9 +56,10 @@ classic.jar:
   images/identity-64.png               (images/identity-64.png)
   images/identityEV-64.png             (images/identityEV-64.png)
   images/identitySSL-64.png            (images/identitySSL-64.png)
   images/lock-40.png                   (images/lock-40.png)
   images/unlock-40.png                 (images/unlock-40.png)
   images/tab-close.png                 (images/tab-close.png)
   images/tag-default-30.png            (images/tag-default-30.png)
   images/star-default-30.png           (images/star-default-30.png)
+  images/check-default-30.png          (images/check-default-30.png)
   images/geo-16.png                    (images/geo-16.png)