Files
Mozilla/mozilla/browser/components/search/content/search.xml
joe%retrovirus.com 3ce0f497ff Add grey text to search box (when not focused) that identifies the current
search engine.

bug=2358968
r=gavin.sharp@gmail.com
sr=ben@mozilla.org


git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_BRANCH@195872 18797224-902f-48f8-a5cc-f745e15eee43
2006-05-03 01:23:40 +00:00

508 lines
18 KiB
XML

<?xml version="1.0"?>
# -*- Mode: HTML -*-
# ***** 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.org browser.
#
# The Initial Developer of the Original Code is
# Joe Hewitt.
# Portions created by the Initial Developer are Copyright (C) 2003
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Pierre Chanial (v2) <p_ch@verizon.net>
# Gavin Sharp (v3) <gavin@gavinsharp.com>
# Ben Goodger <beng@google.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 *****
<!DOCTYPE bindings SYSTEM "chrome://browser/locale/searchbar.dtd">
<bindings id="SearchBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="searchbar-base">
<resources>
<stylesheet src="chrome://browser/content/search/searchbarBindings.css"/>
<stylesheet src="chrome://browser/skin/searchbar.css"/>
</resources>
</binding>
<binding id="searchbar"
extends="chrome://browser/content/search/search.xml#searchbar-base">
<content>
<xul:stringbundle src="chrome://browser/locale/search.properties"/>
<xul:textbox class="searchbar-textbox"
type="autocomplete"
flex="1"
autocompletepopup="PopupAutoComplete"
autocompletesearch="form-history"
autocompletesearchparam="searchbar-history"
completeselectedindex="true"
tabscrolling="true"
xbl:inherits="disableautocomplete,searchengine,src">
<xul:button class="searchbar-dropmarker"
type="menu"
anonid="searchbar-dropmarker"
popup="_child"
xbl:inherits="src">
<xul:menupopup anonid="searchbar-popup"
class="searchbar-popup"
position="after_start"
oncommand="this.parentNode.parentNode.parentNode
.onEnginePopupCommand(event);">
<xul:menuseparator/>
<xul:menuitem label="&cmd_engineManager.label;"
accesskey="&cmd_engineManager.accesskey;"
oncommand="this.parentNode.parentNode.parentNode
.parentNode.openManager(event);"/>
</xul:menupopup>
</xul:button>
</xul:textbox>
</content>
<implementation implements="nsIObserver">
<constructor><![CDATA[
setTimeout(function (a) { a.init(); }, 0, this);
]]></constructor>
<method name="init">
<body><![CDATA[
this._popup = document.getAnonymousElementByAttribute(this, "anonid",
"searchbar-popup");
// Refresh the display (updating icon, etc)
this.rebuildPopup();
this.updateDisplay();
this._textbox._displayCurrentEngine();
var os =
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.addObserver(this, "browser-search-engine-modified", false);
]]></body>
</method>
<destructor><![CDATA[
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.removeObserver(this, "browser-search-engine-modified");
]]></destructor>
<field name="_stringBundle">document.getAnonymousNodes(this)[0];</field>
<field name="_textbox">document.getAnonymousNodes(this)[1];</field>
<field name="_popup">null</field>
<field name="_ss">null</field>
<field name="_engines">null</field>
<property name="currentEngine"
onset="this.searchService.currentEngine = val;">
<getter><![CDATA[
var currentEngine = this.searchService.currentEngine;
// Return a dummy engine if there is no currentEngine
return currentEngine || {name:"", uri:null};
]]></getter>
</property>
<property name="searchService" readonly="true">
<getter><![CDATA[
if (!this._ss) {
const nsIBSS = Components.interfaces.nsIBrowserSearchService;
this._ss =
Components.classes["@mozilla.org/browser/search-service;1"]
.getService(nsIBSS);
}
return this._ss;
]]></getter>
</property>
<property name="value"
onget="return this._textbox.value;"
onset="this._textbox.value = val; return val;"/>
<method name="focus">
<body><![CDATA[
this._textbox.focus();
]]></body>
</method>
<method name="select">
<body><![CDATA[
this._textbox.select();
]]></body>
</method>
<method name="observe">
<parameter name="aEngine"/>
<parameter name="aTopic"/>
<parameter name="aVerb"/>
<body><![CDATA[
if (aTopic == "browser-search-engine-modified") {
switch (aVerb) {
case "engine-removed":
case "engine-added":
case "engine-changed":
// An engine was removed (or hidden), added, or an icon was
// changed
this.rebuildPopup();
// Fall through
case "engine-current":
// The current engine was changed
this.updateDisplay();
}
}
]]></body>
</method>
<method name="updateDisplay">
<body><![CDATA[
var uri = this.currentEngine.iconURI;
if (uri)
this.setAttribute("src", uri.spec);
else
this.setAttribute("src", "");
var name = this.currentEngine.name;
var text = this._stringBundle.getFormattedString("searchtip", [name]);
this.setAttribute("tooltiptext", text);
]]></body>
</method>
<method name="rebuildPopup">
<body><![CDATA[
var popup = this._popup;
// Clear the popup
while (popup.firstChild && popup.firstChild.localName != "menuseparator")
popup.removeChild(popup.firstChild);
this._engines = this.searchService.getVisibleEngines({ });
const kXULNS =
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
for (var i = this._engines.length - 1; i >= 0; --i) {
var menuitem = document.createElementNS(kXULNS, "menuitem");
menuitem.setAttribute("label", this._engines[i].name);
menuitem.setAttribute("id", this._engines[i].name);
menuitem.setAttribute("class", "menuitem-iconic");
if (this._engines[i].iconURI)
menuitem.setAttribute("src", this._engines[i].iconURI.spec);
popup.insertBefore(menuitem, popup.firstChild);
menuitem.engine = this._engines[i];
}
]]></body>
</method>
<method name="openManager">
<parameter name="aEvent"/>
<body><![CDATA[
var wm =
Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var window = wm.getMostRecentWindow("Browser:SearchManager");
if (window)
window.focus()
else {
setTimeout(function () {
openDialog("chrome://browser/content/search/engineManager.xul",
"_blank", "chrome,dialog,modal,centerscreen");
}, 0);
}
]]></body>
</method>
<method name="onEnginePopupCommand">
<parameter name="aEvent"/>
<body><![CDATA[
if (aEvent.target.engine) {
this.currentEngine = aEvent.target.engine;
this.focus();
this.select();
}
]]></body>
</method>
<method name="selectEngine">
<parameter name="aEvent"/>
<parameter name="isNextEngine"/>
<body><![CDATA[
// Find the new index
var newIndex = this._engines.indexOf(this.currentEngine);
newIndex += (isNextEngine) ? 1 : -1;
if (newIndex >= 0 && newIndex < this._engines.length)
this.currentEngine = this._engines[newIndex];
aEvent.preventDefault();
aEvent.stopPropagation();
]]></body>
</method>
<method name="doSearch">
<parameter name="aData"/>
<parameter name="aInNewTab"/>
<body><![CDATA[
var postData = { value: null };
var submission = this.currentEngine.getSubmission(aData);
if (submission) {
var url = submission.uri.spec;
postData.value = submission.postData;
}
if (aInNewTab) {
content.focus();
getBrowser().loadOneTab(url, null, null, postData.value, false, false);
if (gURLBar)
gURLBar.value = url;
} else
loadURI(url, null, postData.value, false);
content.focus();
]]></body>
</method>
</implementation>
</binding>
<binding id="searchbar-textbox"
extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
<implementation>
<constructor><![CDATA[
if (this.parentNode.parentNode.parentNode.localName ==
"toolbarpaletteitem")
return;
setTimeout(function(a) { a.initialize(); }, 0, this);
]]></constructor>
<destructor><![CDATA[
// Because XBL and the customize toolbar code interacts poorly,
// there may not be anything to remove here
try {
this.controllers.removeController(this.searchbarController);
} catch (ex) { }
]]></destructor>
<field name="_stringBundle">this.parentNode._stringBundle</field>
<field name="_formHistSvc"/>
<field name="_prefBranch"/>
<method name="initialize">
<body><![CDATA[
this._formHistSvc =
Components.classes["@mozilla.org/satchel/form-history;1"]
.getService(Components.interfaces.nsIFormHistory2);
this._prefBranch =
Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
if (this._prefBranch.getBoolPref("browser.urlbar.clickSelectsAll"))
this.setAttribute("clickSelectsAll", true);
var textBox = document.getAnonymousElementByAttribute(this,
"anonid", "textbox-input-box");
var cxmenu = document.getAnonymousElementByAttribute(textBox,
"anonid", "input-box-contextmenu");
var element = document.createElementNS(XUL_NS, "menuseparator");
cxmenu.appendChild(element);
element = document.createElementNS(XUL_NS, "menuitem");
const label = this._stringBundle.getString("cmd_clearHistory");
const akey = this._stringBundle.getString("cmd_clearHistory_accesskey");
element.setAttribute("label", label);
element.setAttribute("accesskey", akey);
element.setAttribute("cmd", "cmd_clearhistory");
cxmenu.appendChild(element);
this.controllers.appendController(this.searchbarController);
]]></body>
</method>
<method name="openSearch">
<body>
<![CDATA[
// Don't open search popup if history popup is open
if (!this.popupOpen) {
document.getAnonymousElementByAttribute(this.parentNode,
"anonid", "searchbar-dropmarker").click();
return false;
}
return true;
]]>
</body>
</method>
<!-- Returns the main searchbox element. This is abstracted in
case the structure of this control gets more complicated.
-->
<method name="_getParentSearchbar">
<body><![CDATA[
return this.parentNode;
]]></body>
</method>
<!-- Displays a grayed-out hint string containing the name of the
current search engine in the search text box. (It makes it gray
by setting an empty="true" attribute on the searchbox element.)
-->
<method name="_displayCurrentEngine">
<body><![CDATA[
var searchbar = this._getParentSearchbar();
var newValue = searchbar._stringBundle.getFormattedString(
"searchbox_hint", [searchbar.currentEngine.name]);
// This section is a wee bit hacky; without the timeout, the CSS
// style corresponding to the "empty" attribute doesn't kick in
// until the text has changed, leading to an unpleasant moment
// where the engine name flashes black before turning gray.
searchbar.setAttribute("empty", "true");
var searchTextbox = this;
setTimeout(function() {
if (searchbar.getAttribute("empty") == "true")
searchTextbox.value = newValue;
}, 0);
]]></body>
</method>
<!-- overload |onTextEntered| in autocomplete.xml -->
<method name="onTextEntered">
<parameter name="aEvent"/>
<body><![CDATA[
// Save the current value in the form history
if (this.value && !this.hasAttribute("disableautocomplete"))
this._formHistSvc.addEntry(this.getAttribute(
"autocompletesearchparam"), this.value);
var evt = aEvent || this.mEnterEvent;
var newTab = this._prefBranch.getBoolPref("browser.search.openintab");
this.parentNode.doSearch(this.value, ((evt && evt.altKey) ^ newTab));
]]></body>
</method>
<!-- nsIController -->
<field name="searchbarController" readonly="true"><![CDATA[({
_self: this,
supportsCommand: function(aCommand) {
return aCommand == "cmd_clearhistory";
},
isCommandEnabled: function(aCommand) {
return this._self._formHistSvc.nameExists(
this._self.getAttribute("autocompletesearchparam"));
},
doCommand: function (aCommand) {
this._self._formHistSvc.removeEntriesForName(
this._self.getAttribute("autocompletesearchparam"));
this._self.value = "";
}
})]]></field>
<!-- DND Observer -->
<field name="searchbarDNDObserver" readonly="true"><![CDATA[({
mOuter: this,
onDrop: function (aEvent, aXferData, aDragSession) {
var data = transferUtils.retrieveURLFromData(aXferData.data,
aXferData.flavour.contentType);
if (data) {
this.mOuter.value = data;
this.mOuter.onTextEntered(aEvent);
}
},
getSupportedFlavours: function () {
var flavourSet = new FlavourSet();
flavourSet.appendFlavour("text/unicode");
flavourSet.appendFlavour("text/x-moz-url");
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
return flavourSet;
}
})]]></field>
</implementation>
<handlers>
<handler event="keypress" keycode="vk_up" modifiers="accel"
phase="capturing"
action="this.parentNode.selectEngine(event, false);"/>
<handler event="keypress" keycode="vk_down" modifiers="accel"
phase="capturing"
action="this.parentNode.selectEngine(event, true);"/>
<handler event="keypress" keycode="vk_down" modifiers="alt"
phase="capturing"
action="return this.openSearch();"/>
<handler event="keypress" keycode="vk_up" modifiers="alt"
phase="capturing"
action="return this.openSearch();"/>
#ifndef XP_MACOSX
<handler event="keypress" keycode="vk_f4"
phase="capturing"
action="return this.openSearch();"/>
#endif
<handler event="dragdrop" phase="capturing">
nsDragAndDrop.drop(event, this.searchbarDNDObserver);
</handler>
<handler event="focus" phase="capturing"><![CDATA[
var searchbar = this._getParentSearchbar();
if (searchbar.getAttribute("empty") == "true") {
searchbar.removeAttribute("empty");
this.value = "";
}
]]></handler>
<handler event="blur" phase="capturing"><![CDATA[
var searchbar = this._getParentSearchbar();
if (this.value == "")
this._displayCurrentEngine();
]]></handler>
</handlers>
</binding>
<binding id="searchbar-dropmarker"
extends="chrome://browser/content/search/search.xml#searchbar-base">
<content>
<xul:stack flex="1">
<xul:hbox align="center" class="searchbar-engine-image-container">
<xul:image class="searchbar-engine-image" xbl:inherits="src"/>
</xul:hbox>
<xul:image class="searchbar-dropmarker-image"/>
</xul:stack>
<children/>
</content>
</binding>
</bindings>