Bug 472426: listbox is rendered outside the fennec window, r=gavin

This commit is contained in:
Mark Finkle 2009-06-24 12:42:53 -04:00
Родитель 13f19b9146
Коммит 715503655c
15 изменённых файлов: 559 добавлений и 110 удалений

Просмотреть файл

@ -963,4 +963,179 @@
</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>

Просмотреть файл

@ -263,6 +263,7 @@ var BrowserUI = {
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);
@ -490,6 +491,9 @@ var BrowserUI = {
case "DOMLinkAdded":
this._linkAdded(aEvent);
break;
case "UIShowSelect":
SelectHelper.show(aEvent.target);
break;
case "TabSelect":
this._tabSelect(aEvent);
break;
@ -776,3 +780,129 @@ var FolderPicker = {
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;
}
}
};

Просмотреть файл

@ -96,6 +96,10 @@ 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;

Просмотреть файл

@ -83,7 +83,7 @@ var Browser = {
// 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");
@ -116,7 +116,7 @@ var Browser = {
return;
let h = window.innerHeight;
// Tell the UI to resize the browser controls before calling updateSize
BrowserUI.sizeControls(w, h);
@ -134,7 +134,7 @@ var Browser = {
browserStyle.height = scaledH + "px";
}
}
ws.updateSize(w, h);
}
window.addEventListener("resize", resizeHandler, false);
@ -160,12 +160,12 @@ var Browser = {
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);
@ -235,7 +235,7 @@ var Browser = {
if (whereURI)
this.addTab(whereURI, true);
}
// JavaScript Error Console
if (gPrefService.getBoolPref("browser.console.showInPanel")){
let tool_console = document.getElementById("tool-console");
@ -1242,7 +1242,7 @@ ProgressController.prototype = {
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;
@ -1367,7 +1367,7 @@ Tab.prototype = {
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");

Просмотреть файл

@ -173,7 +173,7 @@
<popupset id="mainPopupSet">
</popupset>
<!-- stupid stack needs to be in a box. not sure why -->
<box>
<stack id="browser-container" flex="1">
@ -406,6 +406,13 @@
</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>

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -1,56 +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 ***** */
/* 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;
}
/* ***** 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;
}

Просмотреть файл

@ -14,7 +14,7 @@ browser.jar:
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/

Просмотреть файл

@ -101,3 +101,6 @@
<!ENTITY consoleErrFile.label "Source File:">
<!ENTITY consoleErrLine.label "Line:">
<!ENTITY consoleErrColumn.label "Column:">
<!ENTITY selectListDone.label "Done">
<!ENTITY selectListDisplay.format "#1 Items">

Просмотреть файл

@ -608,3 +608,50 @@ richpref {
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");
}

Двоичные данные
mobile/themes/hildon/images/check-default-30.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 341 B

Просмотреть файл

@ -42,7 +42,7 @@ classic.jar:
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)
@ -61,4 +61,5 @@ classic.jar:
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)

Просмотреть файл

@ -608,3 +608,50 @@ richpref {
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");
}

Двоичные данные
mobile/themes/wince/images/check-default-30.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 341 B

Просмотреть файл

@ -42,7 +42,7 @@ classic.jar:
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)
@ -61,4 +61,5 @@ classic.jar:
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)