зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
66831165d4
Коммит
cc280c4be9
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче