Backed out changeset c5798de806e2 (bug 1521280) for crashing when searching about:config for upcoming beta (bug 1551013)

--HG--
extra : rebase_source : 8f936159c23d09bf227ce4f5eb6f2d96d33bbff1
This commit is contained in:
Coroiu Cristina 2019-05-13 08:50:28 +03:00
Родитель 66831165d4
Коммит cc280c4be9
32 изменённых файлов: 194 добавлений и 303 удалений

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

@ -112,9 +112,9 @@
<textbox id="readonly_textbox" readonly="true"/> <textbox id="readonly_textbox" readonly="true"/>
<textbox id="disabled_textbox" disabled="true"/> <textbox id="disabled_textbox" disabled="true"/>
<textbox id="searchbox" flex="1" is="search-textbox" results="historyTree"/> <textbox id="searchbox" flex="1" type="search" results="historyTree"/>
<textbox id="searchfield" placeholder="Search all add-ons" <textbox id="searchfield" placeholder="Search all add-ons"
is="search-textbox" searchbutton="true"/> type="search" searchbutton="true"/>
</vbox> </vbox>
</hbox> </hbox>
</window> </window>

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

@ -42,6 +42,7 @@
accTree = accTree =
{ SECTION: [ { SECTION: [
{ ENTRY: [ { TEXT_LEAF: [] } ] }, { ENTRY: [ { TEXT_LEAF: [] } ] },
{ MENUPOPUP: [] }
] }; ] };
testAccessibleTree("txc_search", accTree); testAccessibleTree("txc_search", accTree);
@ -52,12 +53,14 @@
accTree = accTree =
{ SECTION: [ { SECTION: [
{ ENTRY: [ { TEXT_LEAF: [] } ] }, { ENTRY: [ { TEXT_LEAF: [] } ] },
{ MENUPOPUP: [] }
] }; ] };
} else { } else {
accTree = accTree =
{ SECTION: [ { SECTION: [
{ ENTRY: [ { TEXT_LEAF: [] } ] }, { ENTRY: [ { TEXT_LEAF: [] } ] },
{ PUSHBUTTON: [] }, { PUSHBUTTON: [] },
{ MENUPOPUP: [] }
] }; ] };
} }
@ -153,8 +156,8 @@
<vbox flex="1"> <vbox flex="1">
<textbox id="txc" value="hello"/> <textbox id="txc" value="hello"/>
<textbox id="txc_search" is="search-textbox" value="hello"/> <textbox id="txc_search" type="search" value="hello"/>
<textbox id="txc_search_searchbutton" searchbutton="true" is="search-textbox" value="hello"/> <textbox id="txc_search_searchbutton" searchbutton="true" type="search" value="hello"/>
<textbox id="txc_number" type="number" value="44"/> <textbox id="txc_number" type="number" value="44"/>
<textbox id="txc_password" type="password" value="hello"/> <textbox id="txc_password" type="password" value="hello"/>
<textbox id="txc_autocomplete" type="autocomplete" value="hello"/> <textbox id="txc_autocomplete" type="autocomplete" value="hello"/>

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

@ -640,7 +640,7 @@ async function performSelectSearchTests(win) {
let selectPopup = win.document.getElementById("ContentSelectDropdown").menupopup; let selectPopup = win.document.getElementById("ContentSelectDropdown").menupopup;
await openSelectPopup(selectPopup, false, "select", win); await openSelectPopup(selectPopup, false, "select", win);
let searchElement = selectPopup.querySelector(".contentSelectDropdown-searchbox"); let searchElement = selectPopup.querySelector("textbox");
searchElement.focus(); searchElement.focus();
EventUtils.synthesizeKey("O", {}, win); EventUtils.synthesizeKey("O", {}, win);

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

@ -28,9 +28,9 @@ add_task(async function test_focus_on_search_shouldnt_close_popup() {
await BrowserTestUtils.synthesizeMouseAtCenter("#one", { type: "mousedown" }, gBrowser.selectedBrowser); await BrowserTestUtils.synthesizeMouseAtCenter("#one", { type: "mousedown" }, gBrowser.selectedBrowser);
await popupShownPromise; await popupShownPromise;
let searchInput = selectPopup.querySelector(".contentSelectDropdown-searchbox"); let searchInput = selectPopup.querySelector("textbox[type='search']");
searchInput.scrollIntoView(); searchInput.scrollIntoView();
let searchFocused = BrowserTestUtils.waitForEvent(searchInput, "focus", true); let searchFocused = BrowserTestUtils.waitForEvent(searchInput, "focus");
await EventUtils.synthesizeMouseAtCenter(searchInput, {}, window); await EventUtils.synthesizeMouseAtCenter(searchInput, {}, window);
await searchFocused; await searchFocused;
@ -39,3 +39,4 @@ add_task(async function test_focus_on_search_shouldnt_close_popup() {
await hideSelectPopup(selectPopup, "escape"); await hideSelectPopup(selectPopup, "escape");
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
}); });

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

@ -37,7 +37,7 @@
#include bookmarksHistoryTooltip.inc.xul #include bookmarksHistoryTooltip.inc.xul
<hbox id="sidebar-search-container" align="center"> <hbox id="sidebar-search-container" align="center">
<textbox id="search-box" flex="1" is="search-textbox" <textbox id="search-box" flex="1" type="search"
placeholder="&bookmarksSearch.placeholder;" placeholder="&bookmarksSearch.placeholder;"
aria-controls="bookmarks-view" aria-controls="bookmarks-view"
oncommand="searchBookmarks(this.value);"/> oncommand="searchBookmarks(this.value);"/>

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

@ -45,7 +45,7 @@
#include bookmarksHistoryTooltip.inc.xul #include bookmarksHistoryTooltip.inc.xul
<hbox id="sidebar-search-container"> <hbox id="sidebar-search-container">
<textbox id="search-box" flex="1" is="search-textbox" <textbox id="search-box" flex="1" type="search"
placeholder="&historySearch.placeholder;" placeholder="&historySearch.placeholder;"
aria-controls="historyTree" aria-controls="historyTree"
oncommand="searchHistory(this.value);"/> oncommand="searchHistory(this.value);"/>

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

@ -333,7 +333,7 @@
<textbox id="searchFilter" <textbox id="searchFilter"
flex="1" flex="1"
is="search-textbox" type="search"
aria-controls="placeContent" aria-controls="placeContent"
oncommand="PlacesSearchBox.search(this.value);" oncommand="PlacesSearchBox.search(this.value);"
collection="bookmarks"> collection="bookmarks">

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

@ -383,7 +383,7 @@
<label><html:h2 data-l10n-id="applications-header"/></label> <label><html:h2 data-l10n-id="applications-header"/></label>
<description data-l10n-id="applications-description"/> <description data-l10n-id="applications-description"/>
<textbox id="filter" flex="1" <textbox id="filter" flex="1"
is="search-textbox" type="search"
data-l10n-id="applications-filter" data-l10n-id="applications-filter"
aria-controls="handlersView"/> aria-controls="handlersView"/>

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

@ -173,7 +173,7 @@
</hbox> </hbox>
</hbox> </hbox>
<textbox <textbox
is="search-textbox" id="searchInput" type="search" id="searchInput"
data-l10n-id="search-input-box" data-l10n-id="search-input-box"
data-l10n-attrs="style" data-l10n-attrs="style"
hidden="true" clickSelectsAll="true"/> hidden="true" clickSelectsAll="true"/>

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

@ -31,7 +31,7 @@
<separator class="thin"/> <separator class="thin"/>
<hbox id="searchBoxContainer"> <hbox id="searchBoxContainer">
<textbox id="searchBox" is="search-textbox" flex="1" <textbox id="searchBox" type="search" flex="1"
data-l10n-id="site-data-search-textbox"/> data-l10n-id="site-data-search-textbox"/>
</hbox> </hbox>
<separator class="thin"/> <separator class="thin"/>

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

@ -36,7 +36,7 @@
<separator class="thin"/> <separator class="thin"/>
<hbox align="start"> <hbox align="start">
<textbox id="searchBox" flex="1" data-l10n-id="permissions-searchbox" <textbox id="searchBox" flex="1" data-l10n-id="permissions-searchbox"
is="search-textbox" oncommand="gSitePermissionsManager.buildPermissionsList();"/> type="search" oncommand="gSitePermissionsManager.buildPermissionsList();"/>
</hbox> </hbox>
<separator class="thin"/> <separator class="thin"/>
<listheader> <listheader>
@ -66,7 +66,7 @@
<checkbox id="permissionsDisableCheckbox"/> <checkbox id="permissionsDisableCheckbox"/>
<description id="permissionsDisableDescription"/> <description id="permissionsDisableDescription"/>
<spacer flex="1"/> <spacer flex="1"/>
<hbox id="browserNotificationsPermissionExtensionContent" <hbox id="browserNotificationsPermissionExtensionContent"
class="extension-controlled" align="center" hidden="true"> class="extension-controlled" align="center" hidden="true">
<description control="disableNotificationsPermissionExtension" flex="1"/> <description control="disableNotificationsPermissionExtension" flex="1"/>
<button id="disableNotificationsPermissionExtension" <button id="disableNotificationsPermissionExtension"

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

@ -7,6 +7,6 @@
<script type="text/javascript" src="platform.js"/> <script type="text/javascript" src="platform.js"/>
<textbox is="search-textbox"/> <textbox type="search"/>
</window> </window>

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

@ -4,7 +4,7 @@
<window title="mirrored searchfield" <window title="mirrored searchfield"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<hbox> <hbox>
<textbox is="search-textbox" width="200" id="searchbox" style="-moz-transform: scaleX(-1);"/> <textbox type="search" width="200" id="searchbox" style="-moz-transform: scaleX(-1);"/>
<spacer flex="1"/> <spacer flex="1"/>
</hbox> </hbox>
</window> </window>

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

@ -4,7 +4,7 @@
<window title="RTL searchfield" <window title="RTL searchfield"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<hbox> <hbox>
<textbox is="search-textbox" width="200" id="searchbox" style="direction: rtl;"/> <textbox type="search" width="200" id="searchbox" style="direction: rtl;"/>
<spacer flex="1"/> <spacer flex="1"/>
</hbox> </hbox>
</window> </window>

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

@ -61,7 +61,7 @@
<vbox id="savedsignons" class="contentPane" flex="1"> <vbox id="savedsignons" class="contentPane" flex="1">
<!-- filter --> <!-- filter -->
<hbox align="center"> <hbox align="center">
<textbox id="filter" flex="1" is="search-textbox" <textbox id="filter" flex="1" type="search"
aria-controls="signonsTree" aria-controls="signonsTree"
oncommand="FilterPasswords();" oncommand="FilterPasswords();"
data-l10n-id="search-filter"/> data-l10n-id="search-filter"/>

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

@ -70,7 +70,7 @@
<vbox flex="1"> <vbox flex="1">
<hbox id="filterRow" align="center"> <hbox id="filterRow" align="center">
<label data-l10n-id="config-search-prefs" control="textbox"/> <label data-l10n-id="config-search-prefs" control="textbox"/>
<textbox id="textbox" flex="1" is="search-textbox" <textbox id="textbox" flex="1" type="search"
aria-controls="configTree" aria-controls="configTree"
oncommand="FilterPrefs();"/> oncommand="FilterPrefs();"/>
</hbox> </hbox>

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

@ -668,7 +668,6 @@ if (!isDummyDocument) {
for (let [tag, script] of [ for (let [tag, script] of [
["findbar", "chrome://global/content/elements/findbar.js"], ["findbar", "chrome://global/content/elements/findbar.js"],
["menulist", "chrome://global/content/elements/menulist.js"], ["menulist", "chrome://global/content/elements/menulist.js"],
["search-textbox", "chrome://global/content/elements/search-textbox.js"],
["stringbundle", "chrome://global/content/elements/stringbundle.js"], ["stringbundle", "chrome://global/content/elements/stringbundle.js"],
["printpreview-toolbar", "chrome://global/content/printPreviewToolbar.js"], ["printpreview-toolbar", "chrome://global/content/printPreviewToolbar.js"],
["editor", "chrome://global/content/elements/editor.js"], ["editor", "chrome://global/content/elements/editor.js"],

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

@ -60,13 +60,12 @@ window.addEventListener("DOMContentLoaded", () => {
// Support context menus on html textareas in the parent process: // Support context menus on html textareas in the parent process:
window.addEventListener("contextmenu", (e) => { window.addEventListener("contextmenu", (e) => {
const HTML_NS = "http://www.w3.org/1999/xhtml";
// Note that there's not a risk of e.target being XBL anonymous content for <textbox> (which manages // Note that there's not a risk of e.target being XBL anonymous content for <textbox> (which manages
// its own context menu), because e.target will be the XBL binding parent in that case. // its own context menu), because e.target will be the XBL binding parent in that case.
let needsContextMenu = e.target.ownerDocument == document && !e.defaultPrevented && ( let needsContextMenu = e.target.ownerDocument == document &&
(e.target.localName == "textarea" && e.target.namespaceURI == HTML_NS) !e.defaultPrevented &&
|| e.target.closest("textbox[is='search-textbox']") e.target.localName == "textarea" &&
); e.target.namespaceURI == "http://www.w3.org/1999/xhtml";
if (!needsContextMenu) { if (!needsContextMenu) {
return; return;

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

@ -98,7 +98,6 @@ toolkit.jar:
content/global/elements/marquee.js (widgets/marquee.js) content/global/elements/marquee.js (widgets/marquee.js)
content/global/elements/menulist.js (widgets/menulist.js) content/global/elements/menulist.js (widgets/menulist.js)
content/global/elements/popupnotification.js (widgets/popupnotification.js) content/global/elements/popupnotification.js (widgets/popupnotification.js)
content/global/elements/search-textbox.js (widgets/search-textbox.js)
content/global/elements/stringbundle.js (widgets/stringbundle.js) content/global/elements/stringbundle.js (widgets/stringbundle.js)
content/global/elements/tabbox.js (widgets/tabbox.js) content/global/elements/tabbox.js (widgets/tabbox.js)
content/global/elements/text.js (widgets/text.js) content/global/elements/text.js (widgets/text.js)

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

@ -25,6 +25,4 @@
<html:textarea /> <html:textarea />
<textbox is="search-textbox"/>
</window> </window>

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

@ -19,25 +19,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1513343
await new Promise(r => win.addEventListener("load", r, { once: true})); await new Promise(r => win.addEventListener("load", r, { once: true}));
await SimpleTest.promiseFocus(win); await SimpleTest.promiseFocus(win);
const elements = [ let textarea = win.document.querySelector("textarea");
win.document.querySelector("textarea"), ok(textarea, "textarea exists");
win.document.querySelector("textbox[is='search-textbox']"),
];
for (const element of elements) {
await testElement(element, win);
}
SimpleTest.finish();
}
async function testElement(element, win) {
ok(element, "element exists");
info("Synthesizing a key so 'Undo' will be enabled"); info("Synthesizing a key so 'Undo' will be enabled");
element.focus(); textarea.focus();
synthesizeKey("x", {}, win); synthesizeKey("x", {}, win);
is(element.value, "x", "initial value"); is(textarea.value, "x", "initial value");
element.select(); textarea.select();
synthesizeKey("c", { accelKey: true }, win); // copy to clipboard synthesizeKey("c", { accelKey: true }, win); // copy to clipboard
synthesizeKey("KEY_ArrowRight", {}, win); // drop selection to disable cut and copy context menu items synthesizeKey("KEY_ArrowRight", {}, win); // drop selection to disable cut and copy context menu items
@ -45,11 +35,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1513343
info("Calling prevent default on the first contextmenu event"); info("Calling prevent default on the first contextmenu event");
e.preventDefault(); e.preventDefault();
}, { once: true }); }, { once: true });
synthesizeMouseAtCenter(element, {type: "contextmenu"}, win); synthesizeMouseAtCenter(textarea, {type: "contextmenu"}, win);
ok(!win.document.getElementById("textbox-contextmenu"), "contextmenu with preventDefault() doesn't run"); ok(!win.document.getElementById("textbox-contextmenu"), "contextmenu with preventDefault() doesn't run");
let popupshown = new Promise(r => win.addEventListener("popupshown", r, { once: true })); let popupshown = new Promise(r => win.addEventListener("popupshown", r, { once: true }));
synthesizeMouseAtCenter(element, {type: "contextmenu"}, win); synthesizeMouseAtCenter(textarea, {type: "contextmenu"}, win);
let contextmenu = win.document.getElementById("textbox-contextmenu"); let contextmenu = win.document.getElementById("textbox-contextmenu");
ok(contextmenu, "context menu exists after right click"); ok(contextmenu, "context menu exists after right click");
await popupshown; await popupshown;
@ -62,14 +52,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1513343
ok(!contextmenu.querySelector("[command=cmd_selectAll]").hasAttribute("disabled"), "select all enabled"); ok(!contextmenu.querySelector("[command=cmd_selectAll]").hasAttribute("disabled"), "select all enabled");
contextmenu.querySelector("[command=cmd_undo]").click(); contextmenu.querySelector("[command=cmd_undo]").click();
is(element.value, "", "undo worked"); is(textarea.value, "", "undo worked");
// Close the context menu to avoid affecting next test SimpleTest.finish();
let popuphidden = new Promise(r => win.addEventListener("popuphidden", r, { once: true }));
contextmenu.hidePopup();
await popuphidden;
contextmenu.remove();
} }
</script> </script>
</head> </head>
<body onload="runTest()"> <body onload="runTest()">

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

@ -11,7 +11,7 @@
<hbox> <hbox>
<textbox id="searchbox" <textbox id="searchbox"
is="search-textbox" type="search"
oncommand="doSearch(this.value);" oncommand="doSearch(this.value);"
placeholder="random placeholder" placeholder="random placeholder"
timeout="1"/> timeout="1"/>
@ -30,9 +30,9 @@ var gLastTest;
function doTests() { function doTests() {
var textbox = $("searchbox"); var textbox = $("searchbox");
var icons = textbox.querySelector(".textbox-search-icons"); var icons = document.getAnonymousElementByAttribute(textbox, "anonid", "search-icons");
var searchIcon = icons.querySelector(".textbox-search-icon"); var searchIcon = document.getAnonymousElementByAttribute(textbox, "class", "textbox-search-icon");
var clearIcon = icons.querySelector(".textbox-search-clear"); var clearIcon = document.getAnonymousElementByAttribute(textbox, "class", "textbox-search-clear");
ok(icons, "icon deck found"); ok(icons, "icon deck found");
ok(searchIcon, "search icon found"); ok(searchIcon, "search icon found");

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

@ -1,225 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
const HTML_NS = "http://www.w3.org/1999/xhtml";
class MozSearchTextbox extends MozXULElement {
constructor() {
super();
this.inputField = document.createElementNS(HTML_NS, "input");
const METHODS = ["focus", "blur", "select", "setUserInput", "setSelectionRange"];
for (const method of METHODS) {
this[method] = (...args) => this.inputField[method](...args);
}
const READ_WRITE_PROPERTIES = ["defaultValue", "placeholder", "readOnly",
"size", "selectionStart", "selectionEnd"];
for (const property of READ_WRITE_PROPERTIES) {
Object.defineProperty(this, property, {
enumerable: true,
get() {
return this.inputField[property];
},
set(val) {
return this.inputField[property] = val;
},
});
}
this.addEventListener("input", (event) => {
if (this.searchButton) {
this._searchIcons.selectedIndex = 0;
return;
}
if (this._timer) {
clearTimeout(this._timer);
}
this._timer = this.timeout && setTimeout(this._fireCommand, this.timeout, this);
this._searchIcons.selectedIndex = this.value ? 1 : 0;
});
this.addEventListener("keypress", (event) => {
switch (event.keyCode) {
case KeyEvent.DOM_VK_ESCAPE:
if (this._clearSearch()) {
event.preventDefault();
event.stopPropagation();
}
break;
case KeyEvent.DOM_VK_RETURN:
this._enterSearch();
event.preventDefault();
event.stopPropagation();
break;
}
});
}
static get inheritedAttributes() {
return {
".textbox-input": "value,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,mozactionhint,spellcheck",
".textbox-search-icon": "src=image,label=searchbuttonlabel,searchbutton,disabled",
".textbox-search-clear": "disabled",
};
}
connectedCallback() {
if (this.delayConnectedCallback()) {
return;
}
this.textContent = "";
const textboxSign = document.createXULElement("image");
textboxSign.className = "textbox-search-sign";
const input = this.inputField;
input.className = "textbox-input";
input.setAttribute("mozactionhint", "search");
input.addEventListener("focus", () => this.setAttribute("focused", "true"));
input.addEventListener("blur", () => this.removeAttribute("focused"));
const searchBtn = this._searchButtonIcon = document.createXULElement("image");
searchBtn.className = "textbox-search-icon";
searchBtn.addEventListener("click", (e) => this._iconClick(e));
// TODO: Bug 1534799 - Convert string to Fluent and use manual DOM construction
let clearBtn = MozXULElement.parseXULToFragment(`
<image class="textbox-search-clear" label="&searchTextBox.clear.label;"/>
`, ["chrome://global/locale/textcontext.dtd"]);
clearBtn = this._searchClearIcon = clearBtn.querySelector(".textbox-search-clear");
clearBtn.addEventListener("click", () => this._clearSearch());
const deck = this._searchIcons = document.createXULElement("deck");
deck.className = "textbox-search-icons";
deck.append(searchBtn, clearBtn);
this.append(textboxSign, input, deck);
this._timer = null;
// Ensure the button state is up to date:
this.searchButton = this.searchButton;
// Set is attribute for styling
this.setAttribute("is", "search-textbox");
this.initializeAttributeInheritance();
}
set timeout(val) {
this.setAttribute("timeout", val);
return val;
}
get timeout() {
return parseInt(this.getAttribute("timeout")) || 500;
}
set searchButton(val) {
if (val) {
this.setAttribute("searchbutton", "true");
this.removeAttribute("aria-autocomplete");
// Hack for the button to get the right accessible:
this._searchButtonIcon.setAttribute("onclick", "true");
} else {
this.removeAttribute("searchbutton");
this._searchButtonIcon.removeAttribute("onclick");
this.setAttribute("aria-autocomplete", "list");
}
return val;
}
get searchButton() {
return this.getAttribute("searchbutton") == "true";
}
set value(val) {
this.inputField.value = val;
if (val) {
this._searchIcons.selectedIndex = this.searchButton ? 0 : 1;
} else {
this._searchIcons.selectedIndex = 0;
}
if (this._timer) {
clearTimeout(this._timer);
}
return val;
}
get value() {
return this.inputField.value;
}
get editor() {
return this.inputField.editor;
}
set disabled(val) {
this.inputField.disabled = val;
if (val) this.setAttribute("disabled", "true");
else this.removeAttribute("disabled");
return val;
}
get disabled() {
return this.inputField.disabled;
}
reset() {
this.value = this.defaultValue;
// XXX: Is this still needed ?
try {
this.editor.transactionManager.clear();
return true;
} catch (e) {}
return false;
}
_fireCommand(me) {
if (me._timer) {
clearTimeout(me._timer);
}
me._timer = null;
me.doCommand();
}
_iconClick() {
if (this.searchButton) {
this._enterSearch();
} else {
this.focus();
}
}
_enterSearch() {
if (this.disabled) {
return;
}
if (this.searchButton && this.value && !this.readOnly) {
this._searchIcons.selectedIndex = 1;
}
this._fireCommand(this);
}
_clearSearch() {
if (!this.disabled && !this.readOnly && this.value) {
this.value = "";
this._fireCommand(this);
this._searchIcons.selectedIndex = 0;
return true;
}
return false;
}
}
customElements.define("search-textbox", MozSearchTextbox, { extends: "textbox" });
}

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

@ -261,4 +261,138 @@
#endif #endif
</handlers> </handlers>
</binding> </binding>
<binding id="search-textbox" extends="chrome://global/content/bindings/textbox.xml#textbox">
<content>
<children/>
<xul:moz-input-box anonid="moz-input-box" flex="1" xbl:inherits="context,spellcheck" align="center">
<xul:image class="textbox-search-sign"/>
<html:input class="textbox-input" anonid="input" mozactionhint="search"
xbl:inherits="value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,mozactionhint,spellcheck"/>
<xul:deck class="textbox-search-icons" anonid="search-icons">
<xul:image class="textbox-search-icon" anonid="searchbutton-icon"
xbl:inherits="src=image,label=searchbuttonlabel,searchbutton,disabled"/>
<xul:image class="textbox-search-clear"
onclick="document.getBindingParent(this)._clearSearch();"
label="&searchTextBox.clear.label;"
xbl:inherits="disabled"/>
</xul:deck>
</xul:moz-input-box>
</content>
<implementation>
<field name="_timer">null</field>
<field name="_searchIcons">
document.getAnonymousElementByAttribute(this, "anonid", "search-icons");
</field>
<field name="_searchButtonIcon">
document.getAnonymousElementByAttribute(this, "anonid", "searchbutton-icon");
</field>
<property name="timeout"
onset="this.setAttribute('timeout', val); return val;"
onget="return parseInt(this.getAttribute('timeout')) || 500;"/>
<property name="searchButton"
onget="return this.getAttribute('searchbutton') == 'true';">
<setter><![CDATA[
if (val) {
this.setAttribute("searchbutton", "true");
this.removeAttribute("aria-autocomplete");
// Hack for the button to get the right accessible:
this._searchButtonIcon.setAttribute("onclick", "true");
} else {
this.removeAttribute("searchbutton");
this._searchButtonIcon.removeAttribute("onclick");
this.setAttribute("aria-autocomplete", "list");
}
return val;
]]></setter>
</property>
<property name="value"
onget="return this.inputField.value;">
<setter><![CDATA[
this.inputField.value = val;
if (val)
this._searchIcons.selectedIndex = this.searchButton ? 0 : 1;
else
this._searchIcons.selectedIndex = 0;
if (this._timer)
clearTimeout(this._timer);
return val;
]]></setter>
</property>
<constructor><![CDATA[
// Ensure the button state is up to date:
this.searchButton = this.searchButton;
this._searchButtonIcon.addEventListener("click", (e) => this._iconClick(e));
]]></constructor>
<method name="_fireCommand">
<parameter name="me"/>
<body><![CDATA[
if (me._timer)
clearTimeout(me._timer);
me._timer = null;
me.doCommand();
]]></body>
</method>
<method name="_iconClick">
<body><![CDATA[
if (this.searchButton)
this._enterSearch();
else
this.focus();
]]></body>
</method>
<method name="_enterSearch">
<body><![CDATA[
if (this.disabled)
return;
if (this.searchButton && this.value && !this.readOnly)
this._searchIcons.selectedIndex = 1;
this._fireCommand(this);
]]></body>
</method>
<method name="_clearSearch">
<body><![CDATA[
if (!this.disabled && !this.readOnly && this.value) {
this.value = "";
this._fireCommand(this);
this._searchIcons.selectedIndex = 0;
return true;
}
return false;
]]></body>
</method>
</implementation>
<handlers>
<handler event="input">
<![CDATA[
if (this.searchButton) {
this._searchIcons.selectedIndex = 0;
return;
}
if (this._timer)
clearTimeout(this._timer);
this._timer = this.timeout && setTimeout(this._fireCommand, this.timeout, this);
this._searchIcons.selectedIndex = this.value ? 1 : 0;
]]>
</handler>
<handler event="keypress" keycode="VK_ESCAPE">
<![CDATA[
if (this._clearSearch()) {
event.preventDefault();
event.stopPropagation();
}
]]>
</handler>
<handler event="keypress" keycode="VK_RETURN">
<![CDATA[
this._enterSearch();
event.preventDefault();
event.stopPropagation();
]]>
</handler>
</handlers>
</binding>
</bindings> </bindings>

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

@ -458,8 +458,8 @@ textbox {
text-shadow: none; text-shadow: none;
} }
textbox[is="search-textbox"] { textbox[type="search"] {
-moz-binding: none; -moz-binding: url("chrome://global/content/bindings/textbox.xml#search-textbox");
} }
/* Prefix with (xul|*):root to workaround HTML tests loading xul.css */ /* Prefix with (xul|*):root to workaround HTML tests loading xul.css */

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

@ -436,13 +436,11 @@ function populateChildren(menulist, options, uniqueOptionStyles, selectedIndex,
if (Services.prefs.getBoolPref("dom.forms.selectSearch") && addSearch if (Services.prefs.getBoolPref("dom.forms.selectSearch") && addSearch
&& element.childElementCount > SEARCH_MINIMUM_ELEMENTS) { && element.childElementCount > SEARCH_MINIMUM_ELEMENTS) {
// Add a search text field as the first element of the dropdown // Add a search text field as the first element of the dropdown
let searchbox = element.ownerDocument.createXULElement("textbox", { let searchbox = element.ownerDocument.createXULElement("textbox");
is: "search-textbox", searchbox.setAttribute("type", "search");
});
searchbox.className = "contentSelectDropdown-searchbox";
searchbox.addEventListener("input", onSearchInput); searchbox.addEventListener("input", onSearchInput);
searchbox.inputField.addEventListener("focus", onSearchFocus); searchbox.addEventListener("focus", onSearchFocus);
searchbox.inputField.addEventListener("blur", onSearchBlur); searchbox.addEventListener("blur", onSearchBlur);
searchbox.addEventListener("command", onSearchInput); searchbox.addEventListener("command", onSearchInput);
// Handle special keys for exiting search // Handle special keys for exiting search
@ -544,7 +542,7 @@ function onSearchInput() {
function onSearchFocus() { function onSearchFocus() {
let searchObj = this; let searchObj = this;
let menupopup = searchObj.closest("menupopup"); let menupopup = searchObj.parentElement;
menupopup.parentElement.activeChild = null; menupopup.parentElement.activeChild = null;
menupopup.setAttribute("ignorekeys", "true"); menupopup.setAttribute("ignorekeys", "true");
currentBrowser.messageManager.sendAsyncMessage("Forms:SearchFocused", {}); currentBrowser.messageManager.sendAsyncMessage("Forms:SearchFocused", {});
@ -552,6 +550,6 @@ function onSearchFocus() {
function onSearchBlur() { function onSearchBlur() {
let searchObj = this; let searchObj = this;
let menupopup = searchObj.closest("menupopup"); let menupopup = searchObj.parentElement;
menupopup.setAttribute("ignorekeys", "false"); menupopup.setAttribute("ignorekeys", "false");
} }

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

@ -226,7 +226,7 @@
class="warning" data-l10n-id="show-unsigned-extensions-button" class="warning" data-l10n-id="show-unsigned-extensions-button"
command="cmd_showUnsignedExtensions"/> command="cmd_showUnsignedExtensions"/>
<label id="search-label" control="header-search"/> <label id="search-label" control="header-search"/>
<textbox id="header-search" is="search-textbox" searchbutton="true" <textbox id="header-search" type="search" searchbutton="true"
data-l10n-id="search-header" data-l10n-id="search-header"
data-l10n-attrs="searchbuttonlabel" maxlength="100"/> data-l10n-attrs="searchbuttonlabel" maxlength="100"/>
</hbox> </hbox>

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

@ -10,9 +10,7 @@ var focusCount = 0;
async function test() { async function test() {
waitForExplicitFinish(); waitForExplicitFinish();
// The discovery pane does not display the about:addons searchbox, let aWindow = await open_manager(null);
// open the extensions pane instead.
let aWindow = await open_manager("addons://list/extension");
gManagerWindow = aWindow; gManagerWindow = aWindow;
var searchBox = gManagerWindow.document.getElementById("header-search"); var searchBox = gManagerWindow.document.getElementById("header-search");
@ -20,10 +18,10 @@ async function test() {
searchBox.blur(); searchBox.blur();
focusCount++; focusCount++;
} }
searchBox.inputField.addEventListener("focus", focusHandler); searchBox.addEventListener("focus", focusHandler);
f_key_test(); f_key_test();
slash_key_test(); slash_key_test();
searchBox.inputField.removeEventListener("focus", focusHandler); searchBox.removeEventListener("focus", focusHandler);
end_test(); end_test();
} }

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

@ -70,7 +70,7 @@ textbox.plain html|*.textbox-input {
/* ::::: search textbox ::::: */ /* ::::: search textbox ::::: */
textbox:not([searchbutton]) > .textbox-search-sign { textbox:not([searchbutton]) > moz-input-box > .textbox-search-sign {
list-style-image: url(chrome://global/skin/icons/search-textbox.svg); list-style-image: url(chrome://global/skin/icons/search-textbox.svg);
margin-inline-end: 5px; margin-inline-end: 5px;
} }

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

@ -68,13 +68,13 @@ xul|radio[focused="true"] > .radio-check {
-moz-outline-radius: 100%; -moz-outline-radius: 100%;
} }
textbox[is="search-textbox"] { textbox[type="search"] {
-moz-appearance: none; -moz-appearance: none;
padding-inline-start: 8px; padding-inline-start: 8px;
padding-inline-end: 8px; padding-inline-end: 8px;
} }
xul|textbox[is="search-textbox"] > .textbox-search-sign { xul|textbox[type="search"] > moz-input-box > .textbox-search-sign {
-moz-context-properties: fill, fill-opacity; -moz-context-properties: fill, fill-opacity;
fill: currentColor; fill: currentColor;
fill-opacity: 0.8; fill-opacity: 0.8;

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

@ -60,7 +60,7 @@ textbox.plain html|*.textbox-input {
/* ::::: search box ::::: */ /* ::::: search box ::::: */
textbox[is="search-textbox"] { textbox[type="search"] {
-moz-appearance: searchfield; -moz-appearance: searchfield;
padding: 1px; padding: 1px;
font-size: 12px; font-size: 12px;

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

@ -76,7 +76,7 @@ textbox.plain html|*.textbox-input {
/* ::::: search textbox ::::: */ /* ::::: search textbox ::::: */
textbox:not([searchbutton]) > .textbox-search-sign { textbox:not([searchbutton]) > moz-input-box > .textbox-search-sign {
list-style-image: url(chrome://global/skin/icons/search-textbox.svg); list-style-image: url(chrome://global/skin/icons/search-textbox.svg);
margin-inline-end: 5px; margin-inline-end: 5px;
} }