diff --git a/docs/webui_explainer.md b/docs/webui_explainer.md index bbde551f2124b..35dbad932cba8 100644 --- a/docs/webui_explainer.md +++ b/docs/webui_explainer.md @@ -142,20 +142,23 @@ if (bindings_flags & BINDINGS_POLICY_WEB_UI) { The factory creates a [`WebUIController`](#WebUIController) for a tab using the WebUIConfig. -Here's an example: +Here's an example using the DefaultWebUIConfig: ```c++ +class DonutsUI; + +// This would go in chrome/common/webui_url_constants.cc +namespace chrome { +const char kChromeUIDonutsHost[] = "donuts"; +} // namespace chrome + // Config for chrome://donuts -DonutsUIConfig::DonutsUIConfig() - : WebUIConfig(content::kChromeUIScheme, chrome::kChromeUIDonutsHost) {} - -DonutsUIConfig::~DonutsUIConfig() = default; - -std::unique_ptr<content::WebUIController> -DonutsUIConfig::CreateWebUIController(content::WebUI* web_ui, - const GURL& url) { - return std::make_unique<DonutsUI>(web_ui); -} +class DonutsUIConfig : public content::DefaultWebUIConfig<DonutsUI> { + public: + DonutsUIConfig() + : DefaultWebUIConfig(content::kChromeUIScheme, + chrome::kChromeUIDonutsHost) {} +}; // Controller for chrome://donuts. class DonutsUI : public content::WebUIController { @@ -610,13 +613,17 @@ class DonutsPageHandler : public donuts::mojom::PageHandler { ~DonutsPageHandler() override; // Triggered by some outside event - void DonutsPageHandler::OnBakingDonutsFinished(uint32_t num_donuts); + void OnBakingDonutsFinished(uint32_t num_donuts); // donuts::mojom::PageHandler: void StartPilotLight() override; void BakeDonuts(uint32_t num_donuts) override; void GetNumberOfDonuts(GetNumberOfDonutsCallback callback) override; -} + + private: + mojo::Receiver<donuts::mojom::PageHandler> receiver_; + mojo::Remote<donuts::mojom::Page> page_; +}; ``` The message handler needs to implement all the methods on the PageHandler @@ -646,7 +653,7 @@ void DonutsPageHandler::StartPilotLight() { } // Triggered by bakeDonuts() call in TS. -void DonutsPageHandler::BakeDonuts(int32_t num_donuts) { +void DonutsPageHandler::BakeDonuts(uint32_t num_donuts) { GetOven()->BakeDonuts(); } @@ -667,14 +674,22 @@ added to the build and served from the root (e.g. **chrome/browser/resources/donuts/BUILD.gn** ``` +import("//ui/webui/resources/tools/build_webui.gni") + build_webui("build") { - # ... Other arguments go here + grd_prefix = "donuts" + + # You will add these files in the next step: + non_web_component_files = [ + "donuts.ts", + "browser_proxy.ts", + ] + mojo_files_deps = [ "//chrome/browser/ui/webui/donuts:mojo_bindings_ts__generator" ] mojo_files = [ "$root_gen_dir/chrome/browser/ui/webui/donuts/donuts.mojom-webui.ts", ] - # ... Other arguments can go here } ``` @@ -683,19 +698,23 @@ class: **chrome/browser/resources/donuts/browser_proxy.ts** ```js -import {PageCallbackRouter, PageHandlerFactory, PageHandlerInterface, PageHandlerRemote} from './donuts.mojom-webui.js'; +import {PageCallbackRouter, PageHandlerFactory, PageHandlerRemote} from './donuts.mojom-webui.js'; +import type {PageHandlerInterface} from './donuts.mojom-webui.js'; -class BrowserProxy { +// Exporting the interface helps when creating a TestBrowserProxy wrapper. +export interface BrowserProxy { + callbackRouter: PageCallbackRouter; + handler: PageHandlerInterface; +} + +export class BrowserProxyImpl implements BrowserProxy { callbackRouter: PageCallbackRouter; handler: PageHandlerInterface; - constructor() { + private constructor() { this.callbackRouter = new PageCallbackRouter(); - this.handler = new PageHandlerRemote(); - - const factory = PageHandlerFactory.getRemote(); - factory.createPageHandler( + PageHandlerFactory.getRemote().createPageHandler( this.callbackRouter.$.bindNewPipeAndPassRemote(), (this.handler as PageHandlerRemote).$.bindNewPipeAndPassReceiver()); } @@ -704,8 +723,8 @@ class BrowserProxy { return instance || (instance = new BrowserProxy()); } - static setInstance(obj: BrowserProxy) { - instance = obj; + static setInstance(proxy: BrowserProxy) { + instance = proxy; } } @@ -723,13 +742,13 @@ response from the browser. **chrome/browser/resources/donuts/donuts.ts** ```js -import {BrowserProxy} from './browser_proxy.js'; +import {BrowserProxyImpl} from './browser_proxy.js'; let numDonutsBaked: number = 0; window.onload = function() { // Other page initialization steps go here - const proxy = BrowserProxy.getInstance(); + const proxy = BrowserProxyImpl.getInstance(); // Tells the browser to start the pilot light. proxy.handler.startPilotLight(); // Adds a listener for the asynchronous "donutsBaked" event. @@ -742,7 +761,7 @@ window.onload = function() { function CheckNumberOfDonuts() { // Requests the number of donuts from the browser, and alerts with the // response. - BrowserProxy.getInstance().handler.getNumberOfDonuts().then( + BrowserProxyImpl.getInstance().handler.getNumberOfDonuts().then( (numDonuts: number) => { alert('Yay, there are ' + numDonuts + ' delicious donuts left!'); }); @@ -750,7 +769,7 @@ function CheckNumberOfDonuts() { function BakeDonuts(numDonuts: number) { // Tells the browser to bake |numDonuts| donuts. - BrowserProxy.getInstance().handler.bakeDonuts(numDonuts); + BrowserProxyImpl.getInstance().handler.bakeDonuts(numDonuts); } ```