Commit e3dd922b authored by Kenton Lam's avatar Kenton Lam Committed by Chromium LUCI CQ

Implement skeleton of emoji_picker using Polymer.

Very basic skeleton of the interface with search box and list of
emoji. Currently draws emoji into groups from the emoji_ordering.json
file. There is also a row of icons (currently not rendering).

Some changes to BUILD.gn have been made to build the components
using Polymer. This allows us to write template in html and have them
imported into the js component code (see `__html_template__` placeholders)

Bug: 1152237
Change-Id: Ie7f803ba8c2f45d136e81ae2f6b0dd95d616fd27
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2591988
Commit-Queue: Kenton Lam <kentonlam@google.com>
Reviewed-by: default avatarKeith Lee <keithlee@chromium.org>
Reviewed-by: default avatarJohn Palmer <jopalmer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837808}
parent f0782b47
...@@ -4,20 +4,41 @@ ...@@ -4,20 +4,41 @@
import("//third_party/closure_compiler/compile_js.gni") import("//third_party/closure_compiler/compile_js.gni")
import("//tools/grit/grit_rule.gni") import("//tools/grit/grit_rule.gni")
import("//tools/polymer/html_to_js.gni")
import("//ui/webui/resources/tools/generate_grd.gni") import("//ui/webui/resources/tools/generate_grd.gni")
component_js_files = [
"emoji_picker.js",
"emoji_group.js",
]
polymer_deps =
[ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled" ]
resources_grd_file = "$target_gen_dir/resources.grd" resources_grd_file = "$target_gen_dir/resources.grd"
components_grdp_file = "$target_gen_dir/components.grdp"
generate_grd("build_grd") { generate_grd("build_grd") {
deps = [ ":build_grdp" ]
grd_prefix = "emoji_picker" grd_prefix = "emoji_picker"
out_grd = resources_grd_file out_grd = resources_grd_file
input_files = [ input_files = [
"emoji_picker.css", "index.html",
"emoji_picker.html", "types.js",
"emoji_picker.js", "emoji_ordering.json",
] ]
grdp_files = [ components_grdp_file ]
input_files_base_dir = rebase_path(".", "//") input_files_base_dir = rebase_path(".", "//")
} }
generate_grd("build_grdp") {
deps = [ ":web_components" ]
grd_prefix = "emoji_picker"
out_grd = components_grdp_file
input_files = component_js_files
input_files_base_dir = rebase_path(target_gen_dir, "//")
}
grit("resources") { grit("resources") {
# These arguments are needed since the grd is generated at build time. # These arguments are needed since the grd is generated at build time.
enable_input_discovery_for_gn_analyze = false enable_input_discovery_for_gn_analyze = false
...@@ -33,10 +54,30 @@ grit("resources") { ...@@ -33,10 +54,30 @@ grit("resources") {
} }
js_library("emoji_picker") { js_library("emoji_picker") {
deps = [ "//ui/webui/resources/js:load_time_data.m" ] deps = [
":types",
":emoji_group",
"//ui/webui/resources/js:load_time_data.m",
"//third_party/polymer/v3_0/components-chromium/iron-icon",
] + polymer_deps
}
js_library("emoji_group") {
deps = [ ":types" ] + polymer_deps
}
js_library("types") {
} }
js_type_check("closure_compile") { js_type_check("closure_compile") {
uses_js_modules = true is_polymer3 = true
deps = [ ":emoji_picker" ] deps = [
":emoji_group",
":emoji_picker",
":types",
]
}
html_to_js("web_components") {
js_files = component_js_files
} }
<style>
.emoji-group-emoji {
display: flex;
flex-wrap: wrap;
}
.emoji-button {
font-size: 17px;
height: 20px;
margin: 8px;
text-align: center;
width: 20px;
}
.emoji-button.variants {
background-color: red;
}
</style>
<div class="emoji-group">
<div class="emoji-group-heading">[[data.group]]</div>
<div class="emoji-group-emoji">
<template is="dom-repeat" items="[[data.emoji]]">
<div class$="[[_className(item.alternates)]]">
[[_renderEmoji(item.base)]]
</div>
</template>
</div>
</div>
\ 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 {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {EmojiGroup} from './types.js';
class EmojiGroupComponent extends PolymerElement {
static get is() {
return 'emoji-group';
}
static get template() {
return html`{__html_template__}`;
}
static get properties() {
return {
/** @type {EmojiGroup} */
data: {type: Object},
};
}
constructor() {
super();
}
_renderEmoji(codepoints) {
return String.fromCodePoint(...codepoints);
}
_className(alternates) {
return 'emoji-button ' + (alternates.length > 0 ? 'variants' : '');
}
}
customElements.define(EmojiGroupComponent.is, EmojiGroupComponent);
[
{
"group": "Group 1",
"emoji": [
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
}
]
},
{
"group": "Group 2",
"emoji": [
{
"base": [
128075
],
"alternates": [
[128075],
[128075, 127995]
]
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
},
{
"base": [
128512
],
"alternates": []
}
]
}
]
\ No newline at end of file
/* Copyright 2020 The Chromium Authors. All Rights Reserved.
* Use of this source code is governed by the Apache v2.0 license that can be
* found in the LICENSE file.
*/
p {
white-space: pre-wrap;
}
\ No newline at end of file
<!DOCTYPE HTML> <style>
<html> .w-100 {
<head> width: 100%;
<meta charset="utf-8"> }
<link rel="stylesheet" href="emoji_picker.css">
<script type="module" src="emoji_picker.js"></script> .emoji-picker {
</head> max-height: 343px;
<body> min-height: 343px;
<h1>Emoji picker</h1> width: calc(36px * 7);
<p id="welcome-message"></p> }
<div id="emoji-picker"></div> </style>
</body>
</html> <div class="emoji-picker">
\ No newline at end of file
<input
id="search" class="w-100"
type="text" value="{{search::input}}"
></input>
<div class="emoji-tabs">
<iron-icon icon="device:access-time"></iron-icon>
<iron-icon icon="image:tag-faces"></iron-icon>
<iron-icon icon="device:access-time"></iron-icon>
<iron-icon icon="device:access-time"></iron-icon>
<iron-icon icon="device:access-time"></iron-icon>
<iron-icon icon="device:access-time"></iron-icon>
<iron-icon icon="device:access-time"></iron-icon>
<iron-icon icon="device:access-time"></iron-icon>
<iron-icon icon="device:access-time"></iron-icon>
</div>
<div class="emoji-groups w-100">
<template is="dom-repeat" items="{{emojiData}}">
<emoji-group data="[[item]]"></emoji-group>
</template>
</div>
</div>
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All Rights Reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by the Apache v2.0 license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import './strings.m.js'; import './strings.m.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import './emoji_group.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {$} from 'chrome://resources/js/util.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
function initialize() { import {EmojiData} from './types.js';
for (const emoji of loadTimeData.getString('emoji').split(',')) {
const block = document.createElement('div'); const EMOJI_ORDERING_JSON = '/emoji_ordering.json';
block.innerText = emoji;
$('emoji-picker').appendChild(block); class EmojiPicker extends PolymerElement {
static get is() {
return 'emoji-picker';
} }
}
static get template() {
return html`{__html_template__}`;
}
static get properties() {
return {
emoji: {type: Array},
/** @type {?EmojiData} */
emojiData: {type: Object},
search: {type: String},
};
}
constructor() {
super();
const xhr = new XMLHttpRequest();
xhr.onloadend = () => this.onEmojiDataLoaded(xhr.responseText);
xhr.open('GET', EMOJI_ORDERING_JSON);
xhr.send();
this.emojiData = [];
this.emoji = loadTimeData.getString('emoji').split(',');
this.search = '';
}
_formatEmojiData(emojiData) {
return JSON.stringify(emojiData);
}
onEmojiDataLoaded(data) {
this.emojiData = /** @type {!EmojiData} */ (JSON.parse(data));
}
}
document.addEventListener('DOMContentLoaded', initialize); customElements.define(EmojiPicker.is, EmojiPicker);
\ No newline at end of file
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Emoji Picker</title>
<script type="module" src="emoji_picker.js"></script>
<style>
* {
font-family: sans-serif;
}
</style>
</head>
<body>
<emoji-picker></emoji-picker>
</body>
</html>
\ 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.
/**
* @typedef {{base: number, alternates: Array<Array<number>>}}
*/
export let Emoji;
/**
* @typedef {{group: string, emoji: Array<Emoji>}}
*/
export let EmojiGroup;
/**
* @typedef {Array<EmojiGroup>} EmojiData
*/
export let EmojiData;
\ No newline at end of file
...@@ -36,7 +36,7 @@ EmojiPicker::EmojiPicker(content::WebUI* web_ui) ...@@ -36,7 +36,7 @@ EmojiPicker::EmojiPicker(content::WebUI* web_ui)
webui::SetupWebUIDataSource( webui::SetupWebUIDataSource(
html_source.get(), html_source.get(),
base::make_span(kEmojiPickerResources, kEmojiPickerResourcesSize), base::make_span(kEmojiPickerResources, kEmojiPickerResourcesSize),
IDR_EMOJI_PICKER_EMOJI_PICKER_HTML); IDR_EMOJI_PICKER_INDEX_HTML);
content::BrowserContext* browser_context = content::BrowserContext* browser_context =
web_ui->GetWebContents()->GetBrowserContext(); web_ui->GetWebContents()->GetBrowserContext();
......
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