0

[Emoji Picker] Render <seal-app /> under flag

- Sync seal resources from CIPD.
- Render <seal-snackbar /> and <seal-app /> when related flag is enabled.


Bug: b:311086550
Change-Id: I7b64fc44327c165b849d07c5c7d07c1815ecfca1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5242520
Commit-Queue: Grey Wang <greywang@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1254265}
This commit is contained in:
Grey Wang
2024-01-31 00:07:25 +00:00
committed by Chromium LUCI CQ
parent f856d9728d
commit 5542cf0118
15 changed files with 205 additions and 29 deletions

1
.gitignore vendored

@ -123,6 +123,7 @@ vs-chromium-project.txt
/chrome/browser/performance_monitor/performance_monitor.xml
/chrome/browser/protector/internal
/chrome/browser/resources/chromeos/mako/resources/
/chrome/browser/resources/chromeos/seal/resources/
/chrome/browser/resources/pdf/html_office
/chrome/browser/resources/media_router/extension/src/
/chrome/browser/resources/preinstalled_web_apps/internal/

11
DEPS

@ -3868,6 +3868,17 @@ deps = {
'dep_type': 'cipd',
},
'src/chrome/browser/resources/chromeos/seal/resources': {
'packages' : [
{
'package': 'chromeos_internal/inputs/seal',
'version': '11AdGL1RBEo2LflLT5Vc8Q3vBfjsHQAuH5jAhUBxL9QC'
}
],
'condition': 'checkout_chromeos and checkout_src_internal',
'dep_type': 'cipd',
},
# Installer bits used only by Mac, but mapped for all OSes to ease source
# grepping.
'src/chrome/installer/mac/internal': {

@ -44,6 +44,7 @@ group("resources") {
"parent_access:resources",
"password_change:resources",
"remote_maintenance_curtain:resources",
"seal:resources",
"sensor_info:resources",
"set_time_dialog:resources",
"supervision:resources",

@ -334,6 +334,7 @@
on-scroll="onSearchScroll"
category-metadata="[[getCategoryMetadata(gifSupport, category)]]"
gif-support$="[[gifSupport]]"
seal-support$="[[sealSupport]]"
close-gif-nudge-overlay="[[closeGifNudgeOverlay]]"
use-grouped-preference="[[shouldUseGroupedPreference(false)]]"
global-tone="[[globalTone]]"

@ -171,6 +171,12 @@
#search-results {
width: var(--search-content-width);
}
seal-app {
width: var(--search-content-width);
margin-top: 8px;
margin-bottom: 8px;
}
</style>
<div id="searchShadow">
@ -196,7 +202,20 @@
<div class="sr-only" role="heading" aria-level="1">
Emoji Search Results
</div>
<template is="dom-if" if="[[sealMode]]">
<seal-app
query="[[getSearchQuery()]]"
on-seal-app-query-change="onSealQueryChange"
on-seal-app-image-click="onSealImageClick"
>
</seal-app>
</template>
<!-- Do not show regular search results in seal mode -->
<template is="dom-if" if="[[!sealMode]]">
<div id="search-results">
<template is="dom-repeat" items="[[searchResults]]">
<emoji-group data="[[item.emoji]]" category$="[[item.category]]"
gif-support$="[[gifSupport]]" global-tone="[[globalTone]]"
@ -205,6 +224,10 @@
</emoji-group>
</template>
</div>
</template>
<!-- No results / error for seal mode is rendered by <seal-app /> -->
<template is="dom-if" if="[[!sealMode]]">
<div class="no-result">
<template is="dom-if" if="[[noResults(status, searchResults)]]">
<svg id="no-emoji-image" xmlns="http://www.w3.org/2000/svg" width="224" height="168" viewBox="0 0 224 168" fill="none">
@ -218,6 +241,7 @@
</svg>
No result found
</template>
<template is="dom-if" if="[[isGifInErrorState(status, searchResults)]]">
<emoji-error
status="[[status]]"
@ -225,5 +249,11 @@
</emoji-error>
</template>
</div>
</template>
</div>
</template>
<template is="dom-if" if="[[sealSupport]]">
<seal-snackbar on-seal-snackbar-confirm="onSealToastConfirmed">
</seal-snackbar>
</template>

@ -9,15 +9,28 @@ import './emoji_group.js';
import {CrSearchFieldElement} from 'chrome://resources/ash/common/cr_elements/cr_search_field/cr_search_field.js';
import {PolymerSpliceChange} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js';
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {Size} from 'chrome://resources/mojo/ui/gfx/geometry/mojom/geometry.mojom-webui.js';
import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js';
import {NO_INTERNET_SEARCH_ERROR_MSG} from './constants.js';
import {Status} from './emoji_picker.mojom-webui.js';
import {EmojiPickerApiProxyImpl} from './emoji_picker_api_proxy.js';
import {getTemplate} from './emoji_search.html.js';
import {GIF_ERROR_TRY_AGAIN} from './events.js';
import {createCustomEvent, EMOJI_IMG_BUTTON_CLICK, GIF_ERROR_TRY_AGAIN} from './events.js';
import Fuse from './fuse.js';
import {CategoryData, CategoryEnum, EmojiGroupData, EmojiVariants, Gender, Tone} from './types.js';
declare global {
interface HTMLElementTagNameMap {
'seal-snackbar': { show(): void } & HTMLElement;
}
}
interface Image {
url: Url;
size: Size;
}
export interface EmojiSearch {
$: {
search: CrSearchFieldElement,
@ -25,6 +38,7 @@ export interface EmojiSearch {
};
}
const SEAL_DEFAULT_STYLE_NAME = 'seal';
export class EmojiSearch extends PolymerElement {
static get is() {
@ -43,6 +57,7 @@ export class EmojiSearch extends PolymerElement {
searchResults: {type: Array},
needIndexing: {type: Boolean, value: false},
gifSupport: {type: Boolean, value: false},
sealSupport: {type: Boolean, value: false},
status: {type: Status, value: null},
searchQuery: {type: String, value: ''},
nextGifPos: {type: String, value: ''},
@ -51,6 +66,7 @@ export class EmojiSearch extends PolymerElement {
useGroupedPreference: {type: Boolean, value: false},
globalTone: {type: Number, value: null, readonly: true},
globalGender: {type: Number, value: null, readonly: true},
sealMode: {type: Boolean, value: false},
};
}
categoriesData: EmojiGroupData;
@ -59,11 +75,13 @@ export class EmojiSearch extends PolymerElement {
private searchResults: EmojiGroupData;
private needIndexing: boolean;
private gifSupport: boolean;
private sealSupport: boolean;
private status: Status|null;
private closeGifNudgeOverlay: () => void;
private useGroupedPreference: boolean;
private globalTone: Tone|null = null;
private globalGender: Gender|null = null;
private sealMode: boolean;
// TODO(b/235419647): Update the config to use extended search.
private fuseConfig: Fuse.IFuseOptions<EmojiVariants> = {
@ -98,6 +116,11 @@ export class EmojiSearch extends PolymerElement {
}
private onSearch(newSearch: string): void {
this.sealMode = this.isSealMode(newSearch);
if (this.sealMode) {
return;
}
const localSearchResults = this.computeLocalSearchResults(newSearch);
if (!this.gifSupport) {
this.set('searchResults', localSearchResults);
@ -333,6 +356,11 @@ export class EmojiSearch extends PolymerElement {
.then((searchResults) => {
this.push(['searchResults', gifIndex, 'emoji'], ...searchResults);
});
// As part of loading more GIFs process, we also show seal snackbar.
if (!this.sealMode && this.sealSupport) {
this.shadowRoot?.querySelector('seal-snackbar')?.show();
}
}
}
@ -433,6 +461,41 @@ export class EmojiSearch extends PolymerElement {
this.onSearch(this.$.search.getValue());
}
getSearchQuery(): string {
return this.$.search.getValue();
}
isSealMode(query: string): boolean {
return query.includes(':');
}
onSealToastConfirmed() {
if (!this.sealMode && this.sealSupport) {
this.setSearchQuery(`${SEAL_DEFAULT_STYLE_NAME}: ${this.getSearchQuery()}`);
}
}
onSealQueryChange(e: CustomEvent<string>) {
this.setSearchQuery(e.detail);
}
onSealImageClick(e: CustomEvent<Image>) {
this.dispatchEvent(createCustomEvent(
EMOJI_IMG_BUTTON_CLICK, {
name: 'image',
category: CategoryEnum.GIF,
visualContent: {
id: 'seal',
url: {
full: e.detail.url,
preview: e.detail.url,
},
previewSize: e.detail.size,
},
},
));
}
/**
* Sets the search query
*/
@ -453,5 +516,4 @@ declare global {
}
}
customElements.define(EmojiSearch.is, EmojiSearch);

@ -6,6 +6,7 @@
<link rel="stylesheet" href="chrome://theme/typography.css">
<meta charset="utf-8">
<title>Emoji Picker</title>
<script type="module" src="seal.js"></script>
<script type="module" src="emoji_picker.js"></script>
<style>
html,

@ -0,0 +1,18 @@
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//tools/grit/grit_rule.gni")
grit("resources") {
source = "resources.grd"
outputs = [
"grit/seal_resources.h",
"grit/seal_resources_map.h",
"grit/seal_resources_map.cc",
"seal_resources.pak",
]
output_dir = "$root_gen_dir/chrome"
use_brotli = true
}

@ -0,0 +1,2 @@
greywang@google.com
jopalmer@chromium.org

@ -0,0 +1 @@
Private resources for Seal

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
<outputs>
<output filename="grit/seal_resources.h" type="rc_header">
<emit emit_type='prepend'></emit>
</output>
<output filename="seal_resources.pak" type="data_package" />
<output filename="grit/seal_resources_map.cc"
type="resource_file_map_source" />
<output filename="grit/seal_resources_map.h"
type="resource_map_header" />
</outputs>
<release seq="1">
<includes>
<if expr="_google_chrome">
<then>
<include name="IDR_SEAL_JS" file="resources/seal/seal_js.js" resource_path="seal.js" type="BINDATA" />
</then>
<else>
<include name="IDR_SEAL_JS" file="seal_fake.js" resource_path="seal.js" type="BINDATA" />
</else>
</if>
</includes>
</release>
</grit>

@ -0,0 +1 @@
// fake resource for seal.js

@ -20,6 +20,8 @@
#include "chrome/grit/emoji_picker_resources.h"
#include "chrome/grit/emoji_picker_resources_map.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/seal_resources.h"
#include "chrome/grit/seal_resources_map.h"
#include "chromeos/ash/components/emoji/grit/emoji_map.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_ui.h"
@ -71,6 +73,21 @@ EmojiUI::EmojiUI(content::WebUI* web_ui)
IDR_EMOJI_PICKER_INDEX_HTML);
source->AddResourcePaths(base::make_span(kEmoji, kEmojiSize));
// Add seal extra resources.
if (SealUtils::ShouldEnable()) {
source->AddResourcePaths(
base::make_span(kSealResources, kSealResourcesSize));
}
// Some web components defined in seal extra resources are based on lit; so
// we override content security policy here to make them work.
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::TrustedTypes,
"trusted-types goog#html parse-html-subset sanitize-inner-html "
"static-types lit-html lottie-worker-script-loader webui-test-script "
"webui-test-html print-preview-plugin-loader polymer-html-literal "
"polymer-template-event-attribute-policy;");
Profile* profile = Profile::FromWebUI(web_ui);
content::URLDataSource::Add(profile,
std::make_unique<SanitizedImageSource>(profile));

@ -287,6 +287,7 @@ template("chrome_extra_paks") {
"$root_gen_dir/chrome/parent_access_resources.pak",
"$root_gen_dir/chrome/password_change_resources.pak",
"$root_gen_dir/chrome/remote_maintenance_curtain_resources.pak",
"$root_gen_dir/chrome/seal_resources.pak",
"$root_gen_dir/chrome/sensor_info_resources.pak",
"$root_gen_dir/chrome/set_time_dialog_resources.pak",
"$root_gen_dir/chrome/supervision_resources.pak",

@ -182,6 +182,10 @@
"META": {"sizes": {"includes": [50]}},
"includes": [2640],
},
"chrome/browser/resources/chromeos/seal/resources.grd": {
"META": {"sizes": {"includes": [50]}},
"includes": [2650],
},
"<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/chromeos/parent_access/resources.grd": {
"META": {"sizes": {"includes": [50],}},
"includes": [2660],