WebUI: Update documentation
Update docs to reflect new guidance of Lit recommended for new WebUI. Also updating webui_in_chrome as follows: - Remove section on custom tsconfig_base since the vast majority of UIs should be able to use the build_webui() default configuration files (which are automatically selected for Polymer/Lit use as needed). - Updating guidance on sharing resources across WebUI to link to the newer WebUI code sharing doc and better reflect current best practice. - Updating WebUIConfig guidance to reference DefaultWebUIConfig, which is recommended for cases like the example where there are no parameters passed to the controller class. Bug: 40943652 Change-Id: I1d2d77d36fe13bcc830c5d32fb956cdf1e7b78f8 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5564524 Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org> Commit-Queue: Rebekah Potter <rbpotter@chromium.org> Cr-Commit-Position: refs/heads/main@{#1305177}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
758047eaa6
commit
5d410acfd4
@ -44,10 +44,36 @@ body {
|
||||
}
|
||||
```
|
||||
|
||||
`chrome/browser/resources/hello_world/app.html`
|
||||
```html
|
||||
`chrome/browser/resources/hello_world/app.css`
|
||||
```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. */
|
||||
|
||||
/* #css_wrapper_metadata_start
|
||||
* #type=style-lit
|
||||
* #scheme=relative
|
||||
* #css_wrapper_metadata_end */
|
||||
|
||||
#example-div {
|
||||
color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
`chrome/browser/resources/hello_world/app.html.ts`
|
||||
```js
|
||||
// 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 {html} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
import type {HelloWorldAppElement} from './app.js';
|
||||
|
||||
export function getHtml(this: HelloWorldAppElement) {
|
||||
return html`
|
||||
<h1>Hello World</h1>
|
||||
<div id="example-div">[[message_]]</div>
|
||||
<div id="example-div">${this.message_}</div>`;
|
||||
}
|
||||
```
|
||||
|
||||
`chrome/browser/resources/hello_world/app.ts`
|
||||
@ -55,26 +81,31 @@ body {
|
||||
import './strings.m.js';
|
||||
|
||||
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
|
||||
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
|
||||
import {getTemplate} from './app.html.js';
|
||||
import {CrLitElement} from '//resources/lit/v3_0/lit.rollup.js';
|
||||
|
||||
export class HelloWorldAppElement extends PolymerElement {
|
||||
import {getCss} from './app.css.js';
|
||||
import {getHtml} from './app.html.js';
|
||||
|
||||
export class HelloWorldAppElement extends CrLitElement {
|
||||
static get is() {
|
||||
return 'hello-world-app';
|
||||
}
|
||||
|
||||
static get template() {
|
||||
return getTemplate();
|
||||
static override get styles() {
|
||||
return getCss();
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
override render() {
|
||||
return getHtml.bind(this)();
|
||||
}
|
||||
|
||||
static override get properties() {
|
||||
return {
|
||||
message_: {
|
||||
type: String,
|
||||
value: () => loadTimeData.getString('message'),
|
||||
},
|
||||
message_: {String}
|
||||
};
|
||||
}
|
||||
|
||||
protected message_: string = loadTimeData.getString('message');
|
||||
}
|
||||
|
||||
declare global {
|
||||
@ -86,26 +117,6 @@ declare global {
|
||||
customElements.define(HelloWorldAppElement.is, HelloWorldAppElement);
|
||||
```
|
||||
|
||||
Add a `tsconfig_base.json` file to configure TypeScript options. Typical
|
||||
options needed by Polymer UIs include:
|
||||
- disabling `noUncheckedIndexAccess`
|
||||
- disabling `noUnusedLocals`: private members from Elements are accessed from
|
||||
their HTML template
|
||||
- disabling `strictPropertyInitialization`: Element properties can be
|
||||
initialized via the `property` map.
|
||||
|
||||
`chrome/browser/resources/hello_world/tsconfig_base.json`
|
||||
```json
|
||||
{
|
||||
"extends": "../../../../tools/typescript/tsconfig_base.json",
|
||||
"compilerOptions": {
|
||||
"noUncheckedIndexedAccess": false,
|
||||
"noUnusedLocals": false,
|
||||
"strictPropertyInitialization": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Add a `BUILD.gn` file to get TypeScript compilation and to generate the JS file
|
||||
from which the template will be imported.
|
||||
|
||||
@ -118,14 +129,11 @@ build_webui("build") {
|
||||
|
||||
static_files = [ "hello_world.html", "hello_world.css" ]
|
||||
|
||||
web_component_files = [ "app.ts" ]
|
||||
|
||||
non_web_component_files = [
|
||||
# For example the BrowserProxy file would go here.
|
||||
]
|
||||
non_web_component_files = [ "app.ts", "app.html.ts" ]
|
||||
css_files = [ "app.css" ]
|
||||
|
||||
ts_deps = [
|
||||
"//third_party/polymer/v3_0:library",
|
||||
"//third_party/lit/v3_0:build_ts",
|
||||
"//ui/webui/resources/js:build_ts",
|
||||
]
|
||||
}
|
||||
@ -277,35 +285,20 @@ by the `WebUIController` subclass. It also can enable or disable the UI for
|
||||
different conditions (e.g. feature flag status). You can create a
|
||||
`WebUIConfig` subclass and register it in the `WebUIConfigMap` to ensure your
|
||||
request handler is instantiated and used to handle any requests to the desired
|
||||
scheme + host.
|
||||
scheme + host. If you don't need to pass any arguments to your controller
|
||||
class, inherit from `DefaultWebUIConfig` to reduce the amount of code required:
|
||||
|
||||
`chrome/browser/ui/webui/hello_world/hello_world_ui.h`
|
||||
```c++
|
||||
class HelloWorldUIConfig : public content::WebUIConfig {
|
||||
// Forward declaration so that config definition can come before controller.
|
||||
class HelloWorldUI;
|
||||
|
||||
class HelloWorldUIConfig : public content::DefaultWebUIConfig<HelloWorldUI> {
|
||||
public:
|
||||
HelloWorldUIConfig();
|
||||
~HelloWorldUIConfig() override;
|
||||
|
||||
// content::WebUIConfig:
|
||||
std::unique_ptr<content::WebUIController> CreateWebUIController(
|
||||
content::WebUI* web_ui,
|
||||
const GURL& url) override;
|
||||
HelloWorldUIConfig()
|
||||
: DefaultWebUIConfig(content::kChromeUIScheme,
|
||||
chrome::kChromeUIHelloWorldHost) {}
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
`chrome/browser/ui/webui/hello_world/hello_world_ui.cc`
|
||||
```c++
|
||||
HelloWorldUIConfig::HelloWorldUIConfig()
|
||||
: WebUIConfig(content::kChromeUIScheme, chrome::kChromeUIHelloWorldHost) {}
|
||||
|
||||
HelloWorldUIConfig::~HelloWorldUIConfig() = default;
|
||||
|
||||
std::unique_ptr<content::WebUIController>
|
||||
HelloWorldUIConfig::CreateWebUIController(content::WebUI* web_ui,
|
||||
const GURL& url) {
|
||||
return std::make_unique<HelloWorldUI>(web_ui);
|
||||
}
|
||||
```
|
||||
|
||||
Register your config in `chrome_web_ui_configs.cc`, for trusted UIs, or
|
||||
@ -440,15 +433,16 @@ Finally, you will need to do something to actually show your dialog, which can b
|
||||
## More elaborate configurations
|
||||
|
||||
### Referencing resources from another webui page
|
||||
Any code that is located in `ui/webui/resources` and served from
|
||||
`chrome://resources` and `chrome-untrusted://resources` can be used from any
|
||||
WebUI page. If you want to share some additional code from another WebUI page
|
||||
that is not in the shared resources, first see
|
||||
[Sharing Code in WebUI](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/webui_code_sharing.md) to determine the best approach.
|
||||
|
||||
There are already mechanisms to make resources available chrome-wide, by
|
||||
publishing them under `chrome://resources`. If this is not appropriate, there
|
||||
are some ways to serve a file from some other webui page directly through
|
||||
another host.
|
||||
If you determine that the code should be narrowly shared, the following
|
||||
explains how to add the narrowly shared resources to your WebUI data source.
|
||||
|
||||
First, a few explanations. The configuration based on the `build_webui()` BUILD
|
||||
target as presented above generates a few helpers that hide the complexity of
|
||||
the page's configuration. For example, considering the snippet below:
|
||||
In the snippet below:
|
||||
|
||||
```cpp
|
||||
//...
|
||||
@ -477,19 +471,25 @@ const webui::ResourcePath kHelloWorldResources[] = {
|
||||
};
|
||||
```
|
||||
|
||||
Using `WebUIDataSource::AddResourcePaths()` we can add other resources,
|
||||
looking for the right way to declare them by looking through the generated
|
||||
grit files (e.g. via codesearch), or manual registrations if they exist.
|
||||
Using `WebUIDataSource::AddResourcePaths()` we can add the resources from grit
|
||||
files that are generated by limited sharing `build_webui()` targets as follows:
|
||||
|
||||
```cpp
|
||||
#include "chrome/grit/signin_resources.h"
|
||||
#include "chrome/grit/foo_shared_resources.h"
|
||||
#include "chrome/grit/bar_shared_resources.h"
|
||||
// ...
|
||||
HelloWorldUI::HelloWorldUI(content::WebUI* web_ui) {
|
||||
// ...
|
||||
// Add selected resources from foo_shared
|
||||
static constexpr webui::ResourcePath kResources[] = {
|
||||
{"signin_shared.css.js", IDR_SIGNIN_SIGNIN_SHARED_CSS_JS},
|
||||
{"signin_vars.css.js", IDR_SIGNIN_SIGNIN_VARS_CSS_JS},
|
||||
{"foo_shared/foo_shared.css.js", IDR_FOO_SHARED_FOO_SHARED_CSS_JS},
|
||||
{"foo_shared/foo_shared_vars.css.js",
|
||||
IDR_FOO_SHARED_FOO_SHARED_VARS_CSS_JS},
|
||||
};
|
||||
source->AddResourcePaths(kResources);
|
||||
|
||||
// Add all shared resources from bar_shared
|
||||
source->AddResourcePaths(
|
||||
base::make_span(kBarSharedResources, kBarSharedResourcesSize));
|
||||
}
|
||||
```
|
||||
|
@ -387,6 +387,11 @@ if (!enterKey) {
|
||||
|
||||
## Polymer
|
||||
|
||||
***note
|
||||
Lit is now recommended (over Polymer) for any new WebUI development. The
|
||||
guide below still applies for the many existing Polymer UIs in the codebase.
|
||||
***
|
||||
|
||||
Also see the [Google Polymer Style Guide](http://go/polymer-style).
|
||||
|
||||
* Elements with UI should have their HTML in a .html file and logic in a TS file
|
||||
@ -399,7 +404,7 @@ Also see the [Google Polymer Style Guide](http://go/polymer-style).
|
||||
}
|
||||
```
|
||||
|
||||
* In new code, use class based syntax for custom elements. Example:
|
||||
* Use class based syntax for custom elements. Example:
|
||||
```js
|
||||
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
|
||||
import {getTemplate} from './my_app.html.js';
|
||||
@ -517,6 +522,10 @@ https://www.polymer-project.org/2.0/docs/devguide/templates#dom-if):
|
||||
* If reused across multiple WebUI pages, include the SVG in `ui/webui/resources/cr_elements/icons.html` .
|
||||
* You may copy the SVG code from [iron-icons files](https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js).
|
||||
|
||||
## Lit
|
||||
Lit is now recommended (over Polymer) for new WebUI development. Guidance on
|
||||
Lit use in Chromium can be found in a [dedicated doc](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/webui_using_lit.md).
|
||||
|
||||
## Grit processing
|
||||
|
||||
Grit is a tool that runs at compile time to pack resources together into
|
||||
|
Reference in New Issue
Block a user