/* 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/. */ import { html, ifDefined } from "chrome://global/content/vendor/lit.all.mjs"; import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs", }); const SEARCH_DEBOUNCE_RATE_MS = 500; const SEARCH_DEBOUNCE_TIMEOUT_MS = 1000; /** * A search box that displays a search icon and is clearable. Updates to the * search query trigger a `fxview-search-textbox-query` event with the current * query value. * * There is no actual searching done here. That needs to be implemented by the * `fxview-search-textbox-query` event handler. `searchTabList()` from * `helpers.mjs` can be used as a starting point. * * @property {string} placeholder * The placeholder text for the search box. * @property {number} size * The width (number of characters) of the search box. * @property {string} pageName * The hash for the page name that the search input is located on. */ export default class FxviewSearchTextbox extends MozLitElement { static properties = { placeholder: { type: String }, size: { type: Number }, pageName: { type: String }, }; static queries = { clearButton: ".clear-icon", input: "input", }; #query = ""; constructor() { super(); this.searchTask = new lazy.DeferredTask( () => this.#dispatchQueryEvent(), SEARCH_DEBOUNCE_RATE_MS, SEARCH_DEBOUNCE_TIMEOUT_MS ); } disconnectedCallback() { super.disconnectedCallback(); if (!this.searchTask?.isFinalized) { this.searchTask?.finalize(); } } focus() { this.input.focus(); } blur() { this.input.blur(); } onInput(event) { this.#query = event.target.value.trim(); event.preventDefault(); this.onSearch(); } /** * Handler for query updates from keyboard input, and textbox clears from 'X' * button. */ onSearch() { this.searchTask?.arm(); this.requestUpdate(); } clear(event) { if ( event.type == "click" || (event.type == "keydown" && event.code == "Enter") || (event.type == "keydown" && event.code == "Space") ) { this.#query = ""; event.preventDefault(); this.onSearch(); } } #dispatchQueryEvent() { window.scrollTo(0, 0); this.dispatchEvent( new CustomEvent("fxview-search-textbox-query", { bubbles: true, composed: true, detail: { query: this.#query }, }) ); Services.telemetry.recordEvent( "firefoxview_next", "search_initiated", "search", null, { page: this.pageName, } ); } render() { return html`