WebUI: Add syntax highlighting to docs/webui/ code snippets.
Bug: None Change-Id: Ib88ad238b6a2e756e9050876b37a984dd88d6c04 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6388416 Auto-Submit: Demetrios Papadopoulos <dpapad@chromium.org> Commit-Queue: Demetrios Papadopoulos <dpapad@chromium.org> Reviewed-by: Teresa Mao <temao@chromium.org> Cr-Commit-Position: refs/heads/main@{#1437215}
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
In order to build with a fast configuration, try setting these options in your
|
||||
GN args:
|
||||
|
||||
```
|
||||
```python
|
||||
optimize_webui = true
|
||||
is_debug = false
|
||||
```
|
||||
|
@ -71,11 +71,10 @@ class FooBarBrowserTest : public WebUIMochaBrowserTest {
|
||||
// Necessary if you have features (or the UI itself) behind a feature flag.
|
||||
base::test::ScopedFeatureList scoped_feature_list_{foo_bar::kSomeNewFeature};
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
Note: If testing a `chrome-untrusted://` UI, also call:
|
||||
```
|
||||
```c++
|
||||
set_test_loader_scheme(content::kChromeUIUntrustedScheme);
|
||||
```
|
||||
in the constructor.
|
||||
@ -89,7 +88,6 @@ IN_PROC_BROWSER_TEST_F(FooBarAppTest, All) {
|
||||
// Run all Mocha test suites found in app_test
|
||||
RunTest("foo_bar/app_test.js", "mocha.run();");
|
||||
}
|
||||
|
||||
```
|
||||
Should you write a large number of tests in a single file (e.g., for
|
||||
one particular custom element), it may be necessary to run different suites or
|
||||
@ -205,7 +203,7 @@ suite('SearchEmpty', function() {
|
||||
To build your tests as part of the `browser_tests` target, add a BUILD.gn file
|
||||
in your folder:
|
||||
|
||||
```
|
||||
```python
|
||||
# chrome/test/data/webui/foo_bar/BUILD.gn
|
||||
|
||||
import("../build_webui_tests.gni")
|
||||
@ -239,7 +237,7 @@ importing shared test files from `chrome-untrusted://webui-test/` paths.
|
||||
You then need to hook up the targets generated by this file, and list your
|
||||
browsertest.cc source file, in `chrome/test/data/webui/BUILD.gn`:
|
||||
|
||||
```
|
||||
```python
|
||||
# chrome/test/data/webui/BUILD.gn
|
||||
|
||||
source_set("browser_tests") {
|
||||
@ -282,8 +280,8 @@ generate_grd("build_grd") {
|
||||
|
||||
# Conditionally added (e.g. platform-specific) grdps and deps go here
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Unusual Test Setups
|
||||
Some UIs may need to rely on loading a particular URL, such that using the
|
||||
default `chrome://foo-bar/test_loader.html` URL that is used to dynamically
|
||||
|
@ -25,7 +25,7 @@ in the WebUI renderer such as memory corruption bugs.
|
||||
should have an if statement to check the Trusted Types support before using
|
||||
methods/properties under `window.trustedTypes` :**
|
||||
|
||||
```
|
||||
```ts
|
||||
if (window.trustedTypes) {
|
||||
// Trusted Types is supported, let's use Trusted Types 😎
|
||||
elem.innerHTML = trustedTypes.emptyHTML;
|
||||
@ -39,7 +39,7 @@ if (window.trustedTypes) {
|
||||
|
||||
Example code:
|
||||
|
||||
```
|
||||
```ts
|
||||
document.body.innerHTML = '';
|
||||
```
|
||||
|
||||
@ -47,7 +47,7 @@ This will be a Trusted Types violation because the value we are assigning to
|
||||
a dangerous sink is not a Trusted Type.
|
||||
This can be converted to:
|
||||
|
||||
```
|
||||
```ts
|
||||
document.body.innerHTML = trustedTypes.emptyHTML;
|
||||
```
|
||||
|
||||
@ -57,13 +57,13 @@ There is also `trustedTypes.emptyScript` to clear script contents.
|
||||
|
||||
Example code:
|
||||
|
||||
```
|
||||
```ts
|
||||
document.body.innerHTML = 'Hello Guest!';
|
||||
```
|
||||
|
||||
Because this is just a text assignment, this can be converted to:
|
||||
|
||||
```
|
||||
```ts
|
||||
document.body.textContent = 'Hello Guest!';
|
||||
```
|
||||
|
||||
@ -73,14 +73,14 @@ document.body.textContent = 'Hello Guest!';
|
||||
|
||||
Example code:
|
||||
|
||||
```
|
||||
```ts
|
||||
document.body.innerHTML = '<div><p>' + loadTimeData.getString('foo') + '</p>
|
||||
</div>';
|
||||
```
|
||||
|
||||
This can be converted by adding _template_ element to HTML file:
|
||||
|
||||
```
|
||||
```html
|
||||
<template id="foo-template">
|
||||
<div>
|
||||
<p></p>
|
||||
@ -90,7 +90,7 @@ This can be converted by adding _template_ element to HTML file:
|
||||
|
||||
And then adding following JS code to JS file:
|
||||
|
||||
```
|
||||
```ts
|
||||
// body might already have some contents, so let's clear those first 😊
|
||||
document.body.innerHTML = trustedTypes.emptyHTML;
|
||||
|
||||
@ -105,13 +105,13 @@ In cases where you don't have control over the HTML file (e.g. converting common
|
||||
JS libraries), you can use DOM APIs.
|
||||
Example code:
|
||||
|
||||
```
|
||||
```ts
|
||||
document.body.innerHTML += '<p>' + loadTimeData.getString('foo') + '</p>';
|
||||
```
|
||||
|
||||
And then adding following JS code to JS file:
|
||||
|
||||
```
|
||||
```ts
|
||||
const p = document.createElement('p');
|
||||
p.textContent = loadTimeData.getString('foo');
|
||||
document.body.appendChild(p);
|
||||
@ -124,7 +124,7 @@ readability, you can [use `trustedTypes.createPolicy`]
|
||||
(https://web.dev/trusted-types/#create-a-trusted-type-policy).
|
||||
Example code:
|
||||
|
||||
```
|
||||
```ts
|
||||
document.body.innerHTML = '<div class="tree-row">' +
|
||||
'<span class="expand-icon"></span>' +
|
||||
'<span class="tree-label-icon"></span>' +
|
||||
@ -135,7 +135,7 @@ document.body.innerHTML = '<div class="tree-row">' +
|
||||
|
||||
This can be converted to:
|
||||
|
||||
```
|
||||
```ts
|
||||
const htmlString = '<div class="tree-row">' +
|
||||
'<span class="expand-icon"></span>' +
|
||||
'<span class="tree-label-icon"></span>' +
|
||||
@ -155,7 +155,7 @@ This case also requires changes in C++, as we need to allow the `foo-static`
|
||||
Trusted Type policy (created above in `trustedTypes.createPolicy`) in the CSP
|
||||
header.
|
||||
|
||||
```
|
||||
```c++
|
||||
source->OverrideContentSecurityPolicy(
|
||||
network::mojom::CSPDirectiveName::TrustedTypes,
|
||||
"trusted-types foo-static;");
|
||||
@ -165,7 +165,7 @@ source->OverrideContentSecurityPolicy(
|
||||
|
||||
Example code:
|
||||
|
||||
```
|
||||
```ts
|
||||
const script = document.createElement('script');
|
||||
script.src = 'chrome://resources/foo.js';
|
||||
document.body.appendChild(script);
|
||||
@ -173,7 +173,7 @@ document.body.appendChild(script);
|
||||
|
||||
This can be converted to:
|
||||
|
||||
```
|
||||
```ts
|
||||
const staticUrlPolicy = trustedTypes.createPolicy(
|
||||
'foo-js-static',
|
||||
{createScriptURL: () => 'chrome://resources/foo.js'});
|
||||
@ -189,7 +189,7 @@ This case also requires changes in C++, as we need to allow the `foo-js-static`
|
||||
Trusted Type policy (created above in `trustedTypes.createPolicy`) in the CSP
|
||||
header.
|
||||
|
||||
```
|
||||
```c++
|
||||
source->OverrideContentSecurityPolicy(
|
||||
network::mojom::CSPDirectiveName::TrustedTypes,
|
||||
"trusted-types foo-js-static;");
|
||||
@ -200,7 +200,7 @@ source->OverrideContentSecurityPolicy(
|
||||
In case there is no way to support Trusted Types in a WebUI page, you can
|
||||
disable Trusted Types with following code:
|
||||
|
||||
```
|
||||
```c++
|
||||
source->DisableTrustedTypesCSP();
|
||||
```
|
||||
|
||||
|
@ -72,7 +72,7 @@ scheme: One of ['chrome', 'relative']. Defaults to 'relative'. Specifies whether
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//tools/polymer/html_to_wrapper.gni")
|
||||
import("//tools/polymer/css_to_wrapper.gni")
|
||||
|
||||
@ -115,7 +115,7 @@ defines: Optional parameter. Specifies additional variables that can be used in
|
||||
conditional expressions.
|
||||
```
|
||||
#### **Example:**
|
||||
```
|
||||
```python
|
||||
import("//tools/grit/preprocess_if_expr.gni")
|
||||
|
||||
# Preprocesses "my_web_component.html.ts" and my_style_module.css.ts in
|
||||
@ -223,7 +223,7 @@ enable_source_maps: Defaults to the value of the enable_webui_inline_sourcemaps
|
||||
|
||||
#### **Example**
|
||||
|
||||
```
|
||||
```python
|
||||
import("//tools/typescript/ts_library.gni")
|
||||
|
||||
# Compiles and outputs my_webui.js, my_web_component.js and
|
||||
@ -362,7 +362,7 @@ out_folder: The location where bundled files will be placed in. Defaults to
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//ui/webui/resources/tools/bundle_js.gni")
|
||||
import ("//chrome/common/features.gni")
|
||||
|
||||
@ -406,7 +406,7 @@ deps: Targets generating any files being minified.
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//ui/webui/resources/tools/minify_js.gni")
|
||||
import ("//chrome/common/features.gni")
|
||||
|
||||
@ -444,7 +444,7 @@ deps: Targets generating any files being minified.
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//ui/webui/resources/tools/generate_code_cache.gni")
|
||||
import ("//chrome/common/features.gni")
|
||||
|
||||
@ -497,7 +497,7 @@ resource_path_rewrites: Paths to rewrite. In general, the path in input_files,
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//ui/webui/resources/tools/generate_grd.gni")
|
||||
|
||||
generate_grd("build_grd") {
|
||||
@ -539,7 +539,7 @@ deps: Names of any targets generating the grd file, and names of any targets
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
|
||||
grit("resources") {
|
||||
@ -715,7 +715,7 @@ enable_type_aware_eslint_checks: Defaults to "true". Turns on additional
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//ui/webui/resources/tools/build_webui.gni")
|
||||
|
||||
build_webui("build") {
|
||||
@ -821,7 +821,7 @@ enable_type_aware_eslint_checks: Defaults to "true". Turns on additional
|
||||
```
|
||||
|
||||
#### **Example**
|
||||
```
|
||||
```python
|
||||
import("//chrome/test/data/webui/settings/tools/build_webui_tests.gni")
|
||||
|
||||
build_webui_tests("build") {
|
||||
@ -862,7 +862,7 @@ use any `<if expr>`.
|
||||
```
|
||||
|
||||
#### **BUILD.gn file**
|
||||
```
|
||||
```python
|
||||
import("//chrome/common/features.gni")
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
import("//tools/typescript/ts_library.gni")
|
||||
@ -915,7 +915,7 @@ for the top level index. None of these files use any `<if expr>`.
|
||||
```
|
||||
|
||||
#### **BUILD.gn file**
|
||||
```
|
||||
```python
|
||||
import("//chrome/common/features.gni")
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
import("//tools/typescript/ts_library.gni")
|
||||
|
@ -124,7 +124,7 @@ Third, **add dependencies and corresponding path mappings** in the build
|
||||
targets that depend on the new shared library. This is best demonstrated with
|
||||
an example:
|
||||
|
||||
```
|
||||
```python
|
||||
build_webui("build_my_webui") {
|
||||
grd_prefix = "my_webui"
|
||||
# Other params here
|
||||
|
@ -512,7 +512,7 @@ mojom() is the build rule used to generate mojo bindings. It can be set up as
|
||||
follows:
|
||||
|
||||
**chrome/browser/ui/webui/donuts/BUILD.gn**
|
||||
```
|
||||
```python
|
||||
import("//mojo/public/tools/bindings/mojom.gni")
|
||||
|
||||
mojom("mojo_bindings") {
|
||||
@ -673,7 +673,7 @@ added to the build and served from the root (e.g.
|
||||
`build_webui()`:
|
||||
|
||||
**chrome/browser/resources/donuts/BUILD.gn**
|
||||
```
|
||||
```python
|
||||
import("//ui/webui/resources/tools/build_webui.gni")
|
||||
|
||||
build_webui("build") {
|
||||
@ -743,7 +743,7 @@ calling the method returns a promise. The promise will be resolved with the
|
||||
response from the browser.
|
||||
|
||||
**chrome/browser/resources/donuts/donuts.ts**
|
||||
```js
|
||||
```ts
|
||||
import {BrowserProxyImpl} from './browser_proxy.js';
|
||||
|
||||
let numDonutsBaked: number = 0;
|
||||
@ -864,7 +864,7 @@ void OvenHandler::OnPilotLightExtinguished() {
|
||||
This works by crafting a string to be evaluated in the renderer. Any arguments
|
||||
to the call are serialized to JSON and the parameter list is wrapped with
|
||||
|
||||
```
|
||||
```c++
|
||||
// See WebUI::GetJavascriptCall() for specifics:
|
||||
"functionCallName(" + argumentsAsJson + ")"
|
||||
```
|
||||
|
@ -73,7 +73,7 @@ body {
|
||||
```
|
||||
|
||||
`chrome/browser/resources/hello_world/app.html.ts`
|
||||
```js
|
||||
```ts
|
||||
// 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.
|
||||
@ -89,7 +89,7 @@ export function getHtml(this: HelloWorldAppElement) {
|
||||
```
|
||||
|
||||
`chrome/browser/resources/hello_world/app.ts`
|
||||
```js
|
||||
```ts
|
||||
import './strings.m.js';
|
||||
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
@ -517,7 +517,7 @@ HelloWorldUI::HelloWorldUI(content::WebUI* web_ui) {
|
||||
It is suggested to turn off any optimizations during WebUI development by adding
|
||||
the following in the args.gn file:
|
||||
|
||||
```
|
||||
```py
|
||||
optimize_webui = false
|
||||
```
|
||||
|
||||
@ -541,7 +541,7 @@ iterate faster by **not having to do the above steps**. In order to use this
|
||||
flow, follow the steps below:
|
||||
|
||||
**Step 1:** Add the following in your args.gn file and build the `chrome` target.
|
||||
```
|
||||
```py
|
||||
optimize_webui = false # explained in previous section
|
||||
load_webui_from_disk = true
|
||||
```
|
||||
|
@ -84,7 +84,7 @@ will be necessary to check for changes to the property in `changedProperties`.
|
||||
This is also demonstrated in the example below.
|
||||
|
||||
Suppose the Lit child has a property with `notify: true` as follows:
|
||||
```
|
||||
```ts
|
||||
static override get properties() {
|
||||
return {
|
||||
foo: {
|
||||
@ -97,14 +97,14 @@ static override get properties() {
|
||||
|
||||
This property is also bound to a parent element that listens for the
|
||||
`-changed` event as follows:
|
||||
```
|
||||
```html
|
||||
<foo-child ?foo="${this.foo_}" on-foo-changed="${this.onFooChanged_}">
|
||||
</foo-child>
|
||||
<demo-child id="demo"></demo-child>
|
||||
```
|
||||
|
||||
The parent TypeScript code could look like this:
|
||||
```
|
||||
```ts
|
||||
static override get properties() {
|
||||
return {
|
||||
foo_: {type: Boolean},
|
||||
@ -148,7 +148,7 @@ empty at startup. The following example would reproduce this bug and
|
||||
have an empty `<select>` displayed at startup.
|
||||
|
||||
`.html.ts` file with `<select>` bug:
|
||||
```
|
||||
```html
|
||||
<select .value="${this.mySelectValue}" @change="${this.onSelectChange_}">
|
||||
<option value="${MyEnum.FIRST}">Option 1</option>
|
||||
<option value="${MyEnum.SECOND}">Option 2</option>
|
||||
@ -157,7 +157,7 @@ have an empty `<select>` displayed at startup.
|
||||
|
||||
Corresponding `.ts`. Note that the bug manifests even though `mySelectValue`
|
||||
is being initialized to a valid option.
|
||||
```
|
||||
```ts
|
||||
static get properties() {
|
||||
return {
|
||||
mySelectValue: {type: String},
|
||||
@ -175,7 +175,7 @@ The current recommended workaround is to instead bind to the `selected`
|
||||
attribute on each `<option>`, i.e.:
|
||||
|
||||
`.html.ts` file:
|
||||
```
|
||||
```html
|
||||
<select @change="${this.onSelectChange_}">
|
||||
<option value="${MyEnum.FIRST}"
|
||||
?selected="${this.isSelected_(MyEnum.FIRST)}">
|
||||
@ -189,7 +189,7 @@ attribute on each `<option>`, i.e.:
|
||||
```
|
||||
|
||||
Corresponding `.ts` file:
|
||||
```
|
||||
```ts
|
||||
static get properties() {
|
||||
return {
|
||||
mySelectValue: {type: String},
|
||||
@ -313,7 +313,7 @@ template and its styling, and a `.ts` file containing the element definition.
|
||||
***
|
||||
|
||||
Example `.ts` file:
|
||||
```
|
||||
```ts
|
||||
// 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.
|
||||
@ -371,7 +371,7 @@ customElements.define(MyExampleElement.is, MyExampleElement);
|
||||
```
|
||||
|
||||
Example CSS file:
|
||||
```
|
||||
```css
|
||||
/* 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. */
|
||||
@ -406,7 +406,7 @@ generate the wrapper `.css.ts` file.
|
||||
***
|
||||
|
||||
Example `.html.ts `file:
|
||||
```
|
||||
```ts
|
||||
// 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.
|
||||
@ -425,7 +425,7 @@ export function getHtml(this: MyExampleElement) {
|
||||
```
|
||||
|
||||
`BUILD.gn` file configuration:
|
||||
```
|
||||
```python
|
||||
build_webui("build") {
|
||||
…
|
||||
# Use non_web_component_files since the .html.ts file is checked in.
|
||||
@ -493,12 +493,12 @@ in these cases the computation method can be used directly in the template
|
||||
without specifying parameters. An example of this follows.
|
||||
|
||||
Polymer HTML template snippet:
|
||||
```
|
||||
```html
|
||||
<cr-button hidden="[[hideButton_]]">Click Me</cr-button>
|
||||
```
|
||||
|
||||
In the Polymer element definition:
|
||||
```
|
||||
```ts
|
||||
static get properties() {
|
||||
return {
|
||||
loading: Boolean,
|
||||
@ -519,12 +519,12 @@ private computeHideButton_(): boolean {
|
||||
This could be rewritten in Lit, omitting the `hideButton_` property entirely.
|
||||
|
||||
Equivalent Lit HTML template snippet:
|
||||
```
|
||||
```html
|
||||
<cr-button ?hidden="${this.computeHideButton_()}">Click Me</cr-button>
|
||||
```
|
||||
|
||||
Equivalent Lit element definition:
|
||||
```
|
||||
```ts
|
||||
static get properties() {
|
||||
return {
|
||||
loading: {type: Boolean},
|
||||
@ -543,7 +543,7 @@ In other cases, where computed properties are bound to other elements, used as
|
||||
attributes, or are needed for other internal logic, they can be computed in the
|
||||
`willUpdate()` lifecycle callback when the properties that they depend on change
|
||||
as in the following example:
|
||||
```
|
||||
```ts
|
||||
override willUpdate(changedProperties: PropertyValues<this>) {
|
||||
super.willUpdate(changedProperties);
|
||||
|
||||
@ -567,7 +567,7 @@ internal logic or requires accessing the element’s DOM:
|
||||
than triggering a second round of updates.
|
||||
|
||||
Consider the following Polymer code, with a complex observer:
|
||||
```
|
||||
```ts
|
||||
static get properties() {
|
||||
return {
|
||||
max: Number,
|
||||
@ -591,7 +591,7 @@ private onValueSet_() {
|
||||
|
||||
The Lit migrated code would look as follows, with the observer code split
|
||||
into `willUpdate()` and `updated()` based on whether it accesses the DOM:
|
||||
```
|
||||
```ts
|
||||
static override get properties() {
|
||||
return {
|
||||
max: {type: Number},
|
||||
@ -630,7 +630,7 @@ statements in the `.html.ts` file of the form
|
||||
`cr-toolbar`:
|
||||
|
||||
Polymer `cr_toolbar.html`:
|
||||
```
|
||||
```html
|
||||
<div id="content">
|
||||
<template is="dom-if" if="[[showMenu]]" restamp>
|
||||
<cr-icon-button id="menuButton" class="no-overlap"
|
||||
@ -642,7 +642,7 @@ Polymer `cr_toolbar.html`:
|
||||
```
|
||||
|
||||
Lit `cr_toolbar.html.ts`:
|
||||
```
|
||||
```html
|
||||
<div id="content">
|
||||
${this.showMenu ? html`
|
||||
<cr-icon-button id="menuButton" class="no-overlap"
|
||||
@ -677,7 +677,7 @@ One possibility is to set the index or item as data attributes on elements that
|
||||
fire events, as seen in the example that follows.
|
||||
|
||||
From the Polymer element template:
|
||||
```
|
||||
```html
|
||||
<template is="dom-repeat" items="[[listItems]]">
|
||||
<div class="item-container [[getSelectedClass_(item, selectedItem)]]">
|
||||
<cr-button id="[[getItemId_(index)]]" on-click="onItemClick_">
|
||||
@ -688,7 +688,7 @@ From the Polymer element template:
|
||||
```
|
||||
|
||||
From the Polymer element definition:
|
||||
```
|
||||
```ts
|
||||
private getItemId_(index: number): string {
|
||||
return 'listItemId' + index;
|
||||
}
|
||||
@ -709,7 +709,7 @@ private onItemClick_(e: DomRepeatEvent<ListItemType>) {
|
||||
```
|
||||
|
||||
Lit template:
|
||||
```
|
||||
```ts
|
||||
${this.listItems.map((item, index) => html`
|
||||
<div class="item-container ${this.getSelectedClass_(item)}">
|
||||
<cr-button id="${this.getItemId_(index)}"
|
||||
@ -725,7 +725,7 @@ Note the `data-index` setting the `data` attribute on the
|
||||
***
|
||||
|
||||
From the Lit element definition file:
|
||||
```
|
||||
```ts
|
||||
protected getItemId_(index: number): string {
|
||||
return 'listItemId' + index;
|
||||
}
|
||||
@ -763,7 +763,7 @@ An example based on a simplified form of `cr-url-list-item`, which uses
|
||||
composition, follows.
|
||||
|
||||
From the Polymer `.html` template:
|
||||
```
|
||||
```html
|
||||
<div class="folder-and-count">
|
||||
<template is="dom-if" if="[[shouldShowFolderImages_(size)]]" restamp>
|
||||
<template is="dom-repeat" items="[[imageUrls]]"
|
||||
@ -778,7 +778,7 @@ From the Polymer `.html` template:
|
||||
```
|
||||
|
||||
From the Polymer element definition:
|
||||
```
|
||||
```ts
|
||||
private shouldShowImageUrl_(_url: string, index: number) {
|
||||
return index <= 1;
|
||||
}
|
||||
@ -798,7 +798,7 @@ private getDisplayedCount_() {
|
||||
```
|
||||
|
||||
From the Lit `.html.ts` template file:
|
||||
```
|
||||
```ts
|
||||
import {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
import type {CrUrlListItemElement} from './cr_url_list_item.js';
|
||||
@ -842,7 +842,7 @@ export function getHtml(this: CrUrlListItemElement) {
|
||||
```
|
||||
|
||||
From the Lit element definition:
|
||||
```
|
||||
```ts
|
||||
protected getDisplayedCount_(): string {
|
||||
if (this.count && this.count > 999) {
|
||||
// The square to display the count only fits 3 characters.
|
||||
@ -891,7 +891,7 @@ their `updated()` lifecycle callback whenever any property that may impact
|
||||
their height has changed. See example below:
|
||||
|
||||
From the `list_parent.html` template (`iron-list` client so must be Polymer)
|
||||
```
|
||||
```html
|
||||
<iron-list id="list" items="[[listItems_]]" as="item">
|
||||
<template>
|
||||
<custom-item description="[[item.description]]" name="[[item.name]]"
|
||||
@ -902,7 +902,7 @@ From the `list_parent.html` template (`iron-list` client so must be Polymer)
|
||||
```
|
||||
|
||||
From the child `custom_item.html.ts` template:
|
||||
```
|
||||
```html
|
||||
<div class="name">${this.name}</div>
|
||||
<div class="description" ?hidden="${!this.description}">
|
||||
${this.description}
|
||||
@ -916,7 +916,7 @@ display gaps or overlap in the list. To prevent this, the child item should
|
||||
fire `iron-resize` in `updated()` if its `description` property changes.
|
||||
|
||||
From `custom_item.ts`:
|
||||
```
|
||||
```ts
|
||||
override updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has('description')) {
|
||||
@ -929,7 +929,7 @@ override updated(changedProperties: PropertyValues<this>) {
|
||||
### Testing
|
||||
|
||||
A large number of unit tests do something like the following:
|
||||
```
|
||||
```ts
|
||||
// Validate that the input is disabled when invalid is set.
|
||||
myTestElement.invalid = true;
|
||||
assertTrue(myTestElement.$.input.disabled);
|
||||
@ -948,7 +948,7 @@ to do this:
|
||||
render cycle).
|
||||
|
||||
Updated example:
|
||||
```
|
||||
```ts
|
||||
// Validate that the input is disabled when invalid is set.
|
||||
myTestElement.invalid = true;
|
||||
await microtasksFinished();
|
||||
|
Reference in New Issue
Block a user