Bug 466717: reimplement nsIAutocompletePopup to avoid using a <panel> for the autocomplete popup, r=mfinkle

This commit is contained in:
Gavin Sharp 2008-12-09 10:38:31 -08:00
parent c0f8699815
commit 9f179d6ad0
6 changed files with 231 additions and 61 deletions

View File

@ -273,15 +273,11 @@ var BrowserUI = {
if (window != aEvent.target) {
return
}
var rect = document.getElementById("browser-container").getBoundingClientRect();
var containerW = rect.right - rect.left;
var containerH = rect.bottom - rect.top;
var toolbar = document.getElementById("toolbar-main");
var toolbarH = toolbar.boxObject.height;
var toolbarH = document.getElementById("toolbar-main").boxObject.height;
var popup = document.getElementById("popup_autocomplete");
popup.height = containerH - toolbarH;
popup.height = window.innerHeight - toolbarH;
popup.width = window.innerWidth;
// XXX need to handle make some of these work again
/*
@ -303,7 +299,6 @@ var BrowserUI = {
this._edit = document.getElementById("urlbar-edit");
this._edit.addEventListener("blur", this, false);
this._edit.addEventListener("keypress", this, true);
this._edit.addEventListener("input", this, false);
this._throbber = document.getElementById("urlbar-throbber");
this._favicon = document.getElementById("urlbar-favicon");
this._favicon.addEventListener("error", this, false);
@ -425,10 +420,9 @@ var BrowserUI = {
this.show(UIMODE_URLVIEW);
},
updateAutoComplete : function(showDefault) {
showAutoComplete : function(showDefault) {
this.updateSearchEngines();
if (showDefault || this._edit.getAttribute("nomatch"))
this._edit.showHistoryPopup();
this._edit.showHistoryPopup();
},
doButtonSearch : function(button) {
@ -629,9 +623,6 @@ var BrowserUI = {
case "click":
this.doCommand("cmd_openLocation");
break;
case "input":
this.updateAutoComplete(false);
break;
case "keypress":
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
this._edit.reallyClosePopup();
@ -705,7 +696,7 @@ var BrowserUI = {
break;
case "cmd_openLocation":
this.show(UIMODE_URLEDIT);
setTimeout(function () {BrowserUI.updateAutoComplete(true)}, 0);
setTimeout(function () { BrowserUI.showAutoComplete(); }, 0);
break;
case "cmd_star":
{

View File

@ -34,3 +34,7 @@ notification {
notification button {
-moz-binding: url("chrome://browser/content/notification.xml#notification-button");
}
#popup_autocomplete {
-moz-binding: url("chrome://browser/content/urlbar.xml#popup_autocomplete");
}

View File

@ -1270,7 +1270,9 @@ Tab.prototype = {
browser.className = "deckbrowser-browser";
browser.setAttribute("style", "overflow: hidden; visibility: hidden; width: 1024px; height: 800px;");
browser.setAttribute("contextmenu", document.getElementById("canvas").getAttribute("contextmenu"));
browser.setAttribute("autocompletepopup", document.getElementById("canvas").getAttribute("autocompletepopup"));
let autocompletepopup = document.getElementById("canvas").getAttribute("autocompletepopup");
if (autocompletepopup)
browser.setAttribute("autocompletepopup", autocompletepopup);
browser.setAttribute("type", "content");
document.getElementById("browsers").appendChild(browser);

View File

@ -162,14 +162,6 @@
</keyset>
<popupset id="mainPopupSet">
<panel type="autocomplete-richlistbox" id="popup_autocomplete"
noautofocus="true" onpopupshowing="BrowserUI.sizeAutocompletePopup()">
<hbox id="autocomplete_navbuttons" align="center" flex="1"
oncommand="BrowserUI.doButtonSearch(event.target);">
<image class="tool-search"/>
</hbox>
</panel>
<!-- popup for site identity information -->
<panel id="identity-popup" position="after_start" hidden="true" noautofocus="true"
norestorefocus="true">
@ -266,15 +258,13 @@
<textbox id="urlbar-edit"
type="autocomplete"
autocompletesearch="history"
autocompletepopup="popup_autocomplete"
enablehistory="false"
maxrows="6"
completeselectedindex="true"
minresultsforpopup="0"
flex="1"
hidden="true"
autocompletepopup="popup_autocomplete"
ontextentered="BrowserUI.goToURI();"
onsearchcomplete="BrowserUI.updateAutoComplete(false);"
clickSelectsAll="true"/>
</hbox>
<hbox id="urlbar-icons">
@ -355,6 +345,13 @@
</hbox>
</vbox>
<vbox id="popup_autocomplete" style="-moz-stack-sizing: ignore;" top="60" left="0" constraint="ignore-x,vp-relative">
<hbox id="autocomplete_navbuttons" align="center" flex="1"
oncommand="BrowserUI.doButtonSearch(event.target);">
<image class="tool-search"/>
</hbox>
</vbox>
<vbox id="bookmark-container" hidden="true" style="-moz-stack-sizing: ignore;" top="60" left="0">
<vbox id="bookmark-form">
<hbox align="start">

View File

@ -26,5 +26,201 @@
</method>
</implementation>
</binding>
<binding id="popup_autocomplete">
<content hidden="true">
<xul:vbox class="autocomplete-box" flex="1">
<xul:vbox class="autocomplete-items" anonid="autocomplete-items" flex="1000">
<xul:label/>
<xul:label/>
<xul:label/>
<xul:label/>
<xul:label/>
<xul:label/>
<xul:label/>
</xul:vbox>
<children/>
</xul:vbox>
</content>
<implementation implements="nsIAutoCompletePopup, nsIDOMEventListener">
<constructor><![CDATA[
window.addEventListener("click", this, true);
window.addEventListener("blur", this, true);
]]></constructor>
<!-- nsIAutocompleteInput -->
<property name="overrideValue"
readonly="true"
onget="return null;"/>
<field name="_input"/>
<property name="input"
readonly="true"
onget="return this._input;"/>
<field name="_selectedIndex">-1</field>
<field name="_selectedItem"/>
<property name="selectedIndex"
onget="return this._selectedIndex;">
<setter><![CDATA[
// Ignore invalid indices
if (val < -1 ||
val > this._matchCount - 1)
return val;
if (this._selectedItem)
this._styleItem(this._selectedItem, false);
// highlight the selected item
let item = this._items.childNodes.item(val);
if (item) {
this._selectedItem = item;
this._styleItem(this._selectedItem, true);
}
return this._selectedIndex = val;
]]></setter>
</property>
<field name="_popupOpen">false</field>
<property name="popupOpen"
readonly="true"
onget="return this._popupOpen;"/>
<method name="openAutocompletePopup">
<parameter name="aInput"/>
<parameter name="aElement"/>
<body><![CDATA[
if (this._popupOpen)
return;
this._input = aInput;
this.hidden = false;
this._popupOpen = true;
this.invalidate();
]]></body>
</method>
<method name="closePopup">
<body><![CDATA[
if (!this._popupOpen)
return;
this.selectedIndex = -1;
this.input.controller.stopSearch();
this.hidden = true;
this._popupOpen = false;
]]></body>
</method>
<method name="invalidate">
<body><![CDATA[
// Don't bother doing work if we're not even open
if (!this.popupOpen)
return;
let controller = this.input.controller;
let searchString = controller.searchString;
let matchCount = this._matchCount;
let children = this._items.childNodes.length;
for (let i = 0; i < children; ++i) {
let label = this._items.childNodes[i];
label._index = i;
// Check whether there's an entry to fill
if (i > matchCount - 1) {
// Just clear out the old item
label.setAttribute("class", "");
label.setAttribute("value", "");
continue;
}
let url = controller.getValueAt(i);
let title = controller.getCommentAt(i);
let type = controller.getStyleAt(i);
let image = controller.getImageAt(i);
let typeClass = "ac-result-type-" + type;
label.setAttribute("class", "autocomplete-item " + typeClass);
label.setAttribute("value", title || url);
}
]]></body>
</method>
<method name="selectBy">
<parameter name="aReverse"/>
<parameter name="aPage"/>
<body><![CDATA[
let newIndex;
let lastIndex = this._matchCount - 1;
if (this._selectedIndex == -1)
newIndex = aReverse ? lastIndex : 0;
else
newIndex = this._selectedIndex + (aReverse ? -1 : 1);
// Deal with rollover
if (newIndex > lastIndex)
newIndex = 0;
else if (newIndex < 0)
newIndex = lastIndex;
this.selectedIndex = newIndex;
]]></body>
</method>
<!-- Helpers -->
<field name="_items">
document.getAnonymousElementByAttribute(this,
"anonid", "autocomplete-items");
</field>
<property name="_matchCount"
readonly="true">
<getter><![CDATA[
return Math.min(this.input.controller.matchCount, this._items.childNodes.length);
]]></getter>
</property>
<!-- Handles click/blur events on the window while the popup is open. -->
<method name="handleEvent">
<parameter name="aEvent"/>
<body><![CDATA[
this.closePopup();
]]></body>
</method>
<method name="_styleItem">
<parameter name="aItem"/>
<parameter name="aAddStyle"/>
<body><![CDATA[
if (aAddStyle)
aItem.className = "autocomplete-item-selected";
else
aItem.className = "autocomplete-item";
]]></body>
</method>
</implementation>
<handlers>
<handler event="click">
<![CDATA[
let originalTarget = event.originalTarget;
if (event.button == 0 &&
originalTarget.localName == "label") {
this._selectedIndex = originalTarget._index;
this.input.controller.handleEnter(true);
} else
this.closePopup();
]]>
</handler>
</handlers>
</binding>
</bindings>

View File

@ -382,7 +382,10 @@ toolbarbutton.panel-button {
#popup_autocomplete {
background: url(images/navigation_background.png) repeat-x;
-moz-appearance: none;
padding-top: 8px !important;
}
.autocomplete-box {
padding: 5px;
}
.tool-search {
@ -415,32 +418,26 @@ toolbarbutton.panel-button {
#autocomplete_navbuttons {
-moz-border-image: url(images/navigation_search_caps.png) 0 23 0 23;
border-width: 0 23px;
margin-top: 12px;
margin-top: 10px;
min-height: 50px;
}
#PopupAutoCompleteRichResult {
direction: ltr !important;
}
#popup_autocomplete scrollbox {
background: rgb(46,45,45);
}
.autocomplete-richlistbox {
-moz-appearance: none !important;
.autocomplete-items {
overflow: hidden;
-moz-border-image: url(images/navigation_url_caps.png) 25 24 25 24 stretch stretch;
border-width: 26px 25px;
}
.autocomplete-richlistitem {
border-bottom: 0; /* override toolkit style */
padding: 16px;
padding-top: 0px;
padding-left: 0px;
.autocomplete-item,
.autocomplete-item-selected {
padding: 5px 2px;
color: white;
}
.autocomplete-item-selected {
background-color: grey;
}
.ac-result-type-bookmark {
list-style-image: url("chrome://browser/skin/images/page-starred.png");
width: 16px;
@ -453,23 +450,6 @@ toolbarbutton.panel-button {
height: 16px;
}
.ac-comment {
font-size: 16pt !important;
}
.ac-extra > .ac-comment {
font-size: inherit !important;
}
.ac-comment[selected="true"] {
color: inherit !important;
}
/* Hide URL box */
.ac-url-box {
display: none;
}
/* Left sidebar (tabs) ---------------------------------------------------- */
#tabs-container {
background: url("images/left_sidebar_middle.png") rgb(87,87,87) top right repeat-y;