Commit 38a88569 authored by Tom Lukaszewicz's avatar Tom Lukaszewicz Committed by Josip Sokcevic

WebUI: Added SearchField component to TabSearch

Added the SearchField component to the TabSearch WebUI.

The search field adheres to current UX style specifications for
Read Later and Tab Search features.

Dependent CL (update to Polymer bundle):
  https://crrev.com/c/2324810

Before:
  https://drive.google.com/file/d/1A_ikRVaaqhYH1k9RXSnH1aWWknAwajZF

After:
  https://drive.google.com/file/d/1rN_-548iNgbWDvlVH9l_CZQXgydRtgyc

Bug: 1099917
Change-Id: Id92c573aee7463e626773ff514a1b50d3ee18648
Reviewed-on: https://chrome-internal-review.googlesource.com/c/chrome/browser/resources/tab_search/+/3177409Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: default avatarRoman Arora <romanarora@chromium.org>
Reviewed-by: default avatarJohn Lee <johntlee@chromium.org>
Reviewed-by: default avatarYuheng Huang <yuhengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#819573}
parent 0c827c9f
......@@ -10,13 +10,19 @@ import("//ui/webui/webui_features.gni")
js_type_check("closure_compile") {
is_polymer3 = true
deps = [ ":app" ]
deps = [
":app",
":tab_search_api_proxy",
":tab_search_item",
":tab_search_search_field"
]
}
js_library("app") {
deps = [
":tab_search_api_proxy",
":tab_search_item",
":tab_search_search_field",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
]
}
......@@ -35,9 +41,18 @@ js_library("tab_search_item") {
]
}
js_library("tab_search_search_field") {
deps = [
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/cr_elements/cr_search_field:cr_search_field_behavior.m",
]
}
html_to_js("web_components") {
js_files = [
"app.js",
"shared_vars.js",
"tab_search_item.js",
"tab_search_search_field.js",
]
}
......@@ -17,12 +17,10 @@
overflow-y: auto;
}
</style>
<div id="searchBar">
<iron-icon id="searchIcon" icon="cr:search"></iron-icon>
<input id="searchInput" type="text" value="[[searchText_]]"
on-input="onSearchInput_" on-keydown="onKeyDown_" autofocus>
</div>
<tab-search-search-field id="searchField" on-search-changed="onSearchChanged_"
label="Search tabs" clear-label="Clear search" on-keydown="onKeyDown_"
autofocus>
</tab-search-search-field>
<div id="tabs">
<iron-selector id="selector" selected="{{selectedIndex_}}" selected-class="selected">
<template id="tabs-list" is="dom-repeat" items="[[filteredOpenTabs_]]">
......
......@@ -8,6 +8,7 @@ import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
import './tab_search_item.js';
import './tab_search_search_field.js'
import {assert} from 'chrome://resources/js/assert.m.js';
import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
......@@ -115,6 +116,14 @@ export class TabSearchAppElement extends PolymerElement {
return result;
}
/**
* @param {!CustomEvent<string>} e
* @private
*/
onSearchChanged_(e) {
this.searchText_ = e.detail;
}
/**
* @param {!Event} e
* @private
......@@ -136,6 +145,8 @@ export class TabSearchAppElement extends PolymerElement {
}
/**
* TODO(crbug.com/1111003): Check for the presence of modifiers before
* triggering a navigation.
* @param {!KeyboardEvent} e
* @private
*/
......@@ -165,14 +176,6 @@ export class TabSearchAppElement extends PolymerElement {
e.stopPropagation();
}
/**
* @param {!Event} e
* @private
*/
onSearchInput_(e) {
this.searchText_ = e.target.value;
}
/**
* @param {number} offset Distance from the desired item to select and the
* currently selected item.
......@@ -194,13 +197,6 @@ export class TabSearchAppElement extends PolymerElement {
this.getTabSearchItem_(scrollToIndex)
.scrollIntoView({behavior: 'smooth', block: 'nearest'});
}
/**
* @param {string} text
*/
setSearchText(text) {
this.searchText_ = text;
}
}
customElements.define(TabSearchAppElement.is, TabSearchAppElement);
<custom-style>
<style>
html {
--icon-size: 16px;
--primary-text-font-size: 13px;
}
</style>
</custom-style>
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
const $_documentContainer = document.createElement('template');
$_documentContainer.innerHTML = `{__html_template__}`;
document.head.appendChild($_documentContainer.content);
......@@ -2,7 +2,6 @@
/* TODO(crbug.com/1110109): Add dark mode support. */
:host {
--horizontal-margin: 16px;
--icon-size: 16px;
--vertical-margin: 12px;
align-items: center;
background-color: white;
......@@ -42,7 +41,7 @@
.primary-text {
color: var(--cr-primary-text-color);
font-size: 13px;
font-size: var(--primary-text-font-size);
margin-bottom: 3px;
}
......
......@@ -6,6 +6,7 @@ import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
import 'chrome://resources/cr_elements/cr_icons_css.m.js';
import 'chrome://resources/cr_elements/icons.m.js';
import 'chrome://resources/cr_elements/shared_vars_css.m.js';
import './shared_vars.js';
import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
......
......@@ -12,17 +12,14 @@
</outputs>
<release seq="1">
<includes>
<include name="IDR_TAB_SEARCH_API_PROXY_JS"
file="tab_search_api_proxy.js"
type="BINDATA" />
<include name="IDR_APP_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_search/app.js"
type="BINDATA"
use_base_dir="false" />
<include name="IDR_TAB_SEARCH_PAGE_HTML"
file="tab_search_page.html"
<include name="IDR_TAB_SEARCH_API_PROXY_JS"
file="tab_search_api_proxy.js"
type="BINDATA" />
<include name="IDR_TAB_SEARCH_ITEM"
<include name="IDR_TAB_SEARCH_ITEM_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_search/tab_search_item.js"
type="BINDATA"
use_base_dir="false"/>
......@@ -30,6 +27,17 @@
file="${root_gen_dir}/chrome/browser/ui/webui/tab_search/tab_search.mojom-lite.js"
type="BINDATA"
use_base_dir="false"/>
<include name="IDR_TAB_SEARCH_PAGE_HTML"
file="tab_search_page.html"
type="BINDATA" />
<include name="IDR_TAB_SEARCH_SEARCH_FIELD_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_search/tab_search_search_field.js"
type="BINDATA"
use_base_dir="false" />
<include name="IDR_TAB_SEARCH_SHARED_VARS_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_search/shared_vars.js"
type="BINDATA"
use_base_dir="false"/>
</includes>
</release>
</grit>
<style include="cr-icons">
:host {
align-items: center;
background-color: var(--google-grey-refresh-100);
border-radius: 32px;
display: flex;
height: 28px;
padding: 0 8px;
user-select: none;
}
#searchIcon {
height: var(--icon-size);
padding-inline-end: 4px;
width: var(--icon-size);
}
input {
align-self: stretch;
background-color: transparent;
border: none;
border-radius: 0;
color: var(--cr-primary-text-color);
flex: 1;
font-size: var(--primary-text-font-size);
outline: none;
text-overflow: ellipsis;
}
</style>
<iron-icon id="searchIcon" icon="cr:search"></iron-icon>
<input id="searchInput" on-search="onSearchTermSearch"
on-input="onSearchTermInput" aria-label$="[[label]]" type="search"
autofocus="[[autofocus]]" placeholder="[[label]]" autocomplete="off"
spellcheck="false" />
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'chrome://resources/cr_elements/icons.m.js';
import 'chrome://resources/cr_elements/shared_vars_css.m.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import './shared_vars.js';
import {CrSearchFieldBehavior} from 'chrome://resources/cr_elements/cr_search_field/cr_search_field_behavior.m.js';
import {html, PolymerElement, mixinBehaviors} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
class TabSearchSearchField extends mixinBehaviors(
[CrSearchFieldBehavior], PolymerElement) {
static get is() {
return 'tab-search-search-field';
}
static get template() {
return html`{__html_template__}`;
}
static get properties() {
return {
/**
* Controls autofocus for the search field.
*/
autofocus: {
type: Boolean,
value: false,
},
};
}
/** @return {!HTMLInputElement} */
getSearchInput() {
return /** @type {!HTMLInputElement} */ (this.$.searchInput);
}
}
customElements.define(TabSearchSearchField.is, TabSearchSearchField);
......@@ -116,7 +116,9 @@ suite('TabSearchAppTest', () => {
test('return filtered tabs', async () => {
await setupTest(sampleData());
tabSearchApp.setSearchText('bing');
const searchField = /** @type {!TabSearchSearchFieldElement} */
(tabSearchApp.shadowRoot.querySelector("#searchField"));
searchField.setValue('bing');
await flushTasks();
verifyTabIds(queryRows(), [2]);
});
......@@ -131,19 +133,19 @@ suite('TabSearchAppTest', () => {
test('Keyboard navigation on an empty list', async () => {
await setupTest({windows: [{active: true, tabs: []}]});
const searchInput = /** @type {!HTMLInputElement} */ (
tabSearchApp.shadowRoot.getElementById('searchInput'));
const searchField = /** @type {!TabSearchSearchFieldElement} */
(tabSearchApp.shadowRoot.querySelector("#searchField"));
keyDownOn(searchInput, 0, [], 'ArrowUp');
keyDownOn(searchField, 0, [], 'ArrowUp');
assertEquals(-1, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'ArrowDown');
keyDownOn(searchField, 0, [], 'ArrowDown');
assertEquals(-1, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'Home');
keyDownOn(searchField, 0, [], 'Home');
assertEquals(-1, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'End');
keyDownOn(searchField, 0, [], 'End');
assertEquals(-1, tabSearchApp.getSelectedIndex());
});
......@@ -152,25 +154,25 @@ suite('TabSearchAppTest', () => {
const numTabs =
sampleData().windows.reduce((total, w) => total + w.tabs.length, 0);
const searchInput = /** @type {!HTMLInputElement} */ (
tabSearchApp.shadowRoot.getElementById('searchInput'));
const searchField = /** @type {!TabSearchSearchFieldElement} */
(tabSearchApp.shadowRoot.querySelector("#searchField"));
keyDownOn(searchInput, 0, [], 'ArrowUp');
keyDownOn(searchField, 0, [], 'ArrowUp');
assertEquals(numTabs - 1, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'ArrowDown');
keyDownOn(searchField, 0, [], 'ArrowDown');
assertEquals(0, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'ArrowDown');
keyDownOn(searchField, 0, [], 'ArrowDown');
assertEquals(1, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'ArrowUp');
keyDownOn(searchField, 0, [], 'ArrowUp');
assertEquals(0, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'End');
keyDownOn(searchField, 0, [], 'End');
assertEquals(numTabs - 1, tabSearchApp.getSelectedIndex());
keyDownOn(searchInput, 0, [], 'Home');
keyDownOn(searchField, 0, [], 'Home');
assertEquals(0, tabSearchApp.getSelectedIndex());
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment