diff --git a/.hgignore b/.hgignore index 3c7776db6966..037e26c4c346 100644 --- a/.hgignore +++ b/.hgignore @@ -169,6 +169,9 @@ _OPT\.OBJ/ ^tools/browsertime/node_modules/ ^tools/lint/eslint/eslint-plugin-mozilla/node_modules/ ^browser/components/newtab/node_modules/ +^toolkit/content/vendor/lit/node_modules/ +# Bug 1790483 Ignore lit - development only for now. +^toolkit/content/widgets/vendor/lit.all.mjs ^tools/esmify/node_modules/ # Ignore talos virtualenv and tp5n files. diff --git a/toolkit/content/vendor/lit/LICENSE b/toolkit/content/vendor/lit/LICENSE new file mode 100644 index 000000000000..c8ed22676f58 --- /dev/null +++ b/toolkit/content/vendor/lit/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2017 Google LLC. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/toolkit/content/vendor/lit/README.md b/toolkit/content/vendor/lit/README.md new file mode 100644 index 000000000000..81f640b75ebe --- /dev/null +++ b/toolkit/content/vendor/lit/README.md @@ -0,0 +1,31 @@ +# Vendoring for lit + +[lit](https://lit.dev/) can be used to help create Web Components. + +## The lit.all.mjs bundle + +The lit package is imported in a vendoring step and the contents are extracted +into the lit.all.mjs file. This has some differences from using lit in a regular +npm project. Imports that would normally be into a specific file are pulled +directly from the lit.all.mjs file. + +eg. + +``` +// Standard npm package: +import { LitElement } from "lit"; +import { classMap } from "lit/directives/class-map.js"; + +// Using lit.all.mjs (pathing to lit.all.mjs may differ) +import { classMap, LitElement } from "../vendor/lit.all.mjs"; + +## To update the lit bundle + +Using `mach`s `npm` you can update the bundle with: + +``` +cd toolkit/content/vendor/lit +../../../../mach npm run vendor +``` + +Then commit the changes. diff --git a/toolkit/content/vendor/lit/index.mjs b/toolkit/content/vendor/lit/index.mjs new file mode 100644 index 000000000000..1588d1f62440 --- /dev/null +++ b/toolkit/content/vendor/lit/index.mjs @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* eslint-disable import/no-unassigned-import */ +/* eslint-disable import/no-unresolved */ + +export * from "lit"; +export * from "lit/directives/async-append.js"; +export * from "lit/directives/async-replace.js"; +export * from "lit/directives/cache.js"; +export * from "lit/directives/class-map.js"; +export * from "lit/directives/guard.js"; +export * from "lit/directives/if-defined.js"; +export * from "lit/directives/live.js"; +export * from "lit/directives/ref.js"; +export * from "lit/directives/repeat.js"; +export * from "lit/directives/style-map.js"; +export * from "lit/directives/template-content.js"; +export * from "lit/directives/until.js"; +export * from "lit/decorators.js"; diff --git a/toolkit/content/vendor/lit/lit-html-no-inner-html.patch b/toolkit/content/vendor/lit/lit-html-no-inner-html.patch new file mode 100644 index 000000000000..a6128c9ddbc6 --- /dev/null +++ b/toolkit/content/vendor/lit/lit-html-no-inner-html.patch @@ -0,0 +1,17 @@ +--- lit.all.mjs ++++ lit.all.mjs.patched +@@ -358,8 +358,12 @@ + } + } + static createElement(t7, i9) { +- const s8 = h2.createElement("template"); +- return s8.innerHTML = t7, s8; ++ const parser = new DOMParser(); ++ const doc = parser.parseFromString( ++ ``, ++ "text/html" ++ ); ++ return document.importNode(doc.querySelector("template"), true); + } + }; + function P(t7, i9, s8 = t7, e14) { diff --git a/toolkit/content/vendor/lit/moz.yaml b/toolkit/content/vendor/lit/moz.yaml new file mode 100644 index 000000000000..0997a244b168 --- /dev/null +++ b/toolkit/content/vendor/lit/moz.yaml @@ -0,0 +1,14 @@ +schema: 1 + +bugzilla: + product: "Toolkit" + component: "XUL Widgets" + +origin: + name: "lit" + description: + "Lit is a simple library for building fast, lightweight web components." + url: "https://github.com/lit/lit" + license: "BSD-3-Clause" + release: "2.4.0" + revision: "lit@2.4.0" diff --git a/toolkit/content/vendor/lit/package-lock.json b/toolkit/content/vendor/lit/package-lock.json new file mode 100644 index 000000000000..b530f3adf6f1 --- /dev/null +++ b/toolkit/content/vendor/lit/package-lock.json @@ -0,0 +1,185 @@ +{ + "name": "vendor-lit", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "vendor-lit", + "version": "1.0.0", + "license": "MPL-2.0", + "dependencies": { + "lit": "^2.4.0" + }, + "devDependencies": { + "esbuild": "^0.15.10" + } + }, + "node_modules/@lit/reactive-element": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz", + "integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw==" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" + }, + "node_modules/esbuild": { + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz", + "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.15.10", + "@esbuild/linux-loong64": "0.15.10", + "esbuild-android-64": "0.15.10", + "esbuild-android-arm64": "0.15.10", + "esbuild-darwin-64": "0.15.10", + "esbuild-darwin-arm64": "0.15.10", + "esbuild-freebsd-64": "0.15.10", + "esbuild-freebsd-arm64": "0.15.10", + "esbuild-linux-32": "0.15.10", + "esbuild-linux-64": "0.15.10", + "esbuild-linux-arm": "0.15.10", + "esbuild-linux-arm64": "0.15.10", + "esbuild-linux-mips64le": "0.15.10", + "esbuild-linux-ppc64le": "0.15.10", + "esbuild-linux-riscv64": "0.15.10", + "esbuild-linux-s390x": "0.15.10", + "esbuild-netbsd-64": "0.15.10", + "esbuild-openbsd-64": "0.15.10", + "esbuild-sunos-64": "0.15.10", + "esbuild-windows-32": "0.15.10", + "esbuild-windows-64": "0.15.10", + "esbuild-windows-arm64": "0.15.10" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz", + "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/lit": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.4.0.tgz", + "integrity": "sha512-fdgzxEtLrZFQU/BqTtxFQCLwlZd9bdat+ltzSFjvWkZrs7eBmeX0L5MHUMb3kYIkuS8Xlfnii/iI5klirF8/Xg==", + "dependencies": { + "@lit/reactive-element": "^1.4.0", + "lit-element": "^3.2.0", + "lit-html": "^2.4.0" + } + }, + "node_modules/lit-element": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.2.tgz", + "integrity": "sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==", + "dependencies": { + "@lit/reactive-element": "^1.3.0", + "lit-html": "^2.2.0" + } + }, + "node_modules/lit-html": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.4.0.tgz", + "integrity": "sha512-G6qXu4JNUpY6aaF2VMfaszhO9hlWw0hOTRFDmuMheg/nDYGB+2RztUSOyrzALAbr8Nh0Y7qjhYkReh3rPnplVg==", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + } + }, + "dependencies": { + "@lit/reactive-element": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.4.1.tgz", + "integrity": "sha512-qDv4851VFSaBWzpS02cXHclo40jsbAjRXnebNXpm0uVg32kCneZPo9RYVQtrTNICtZ+1wAYHu1ZtxWSWMbKrBw==" + }, + "@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" + }, + "esbuild": { + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz", + "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.15.10", + "@esbuild/linux-loong64": "0.15.10", + "esbuild-android-64": "0.15.10", + "esbuild-android-arm64": "0.15.10", + "esbuild-darwin-64": "0.15.10", + "esbuild-darwin-arm64": "0.15.10", + "esbuild-freebsd-64": "0.15.10", + "esbuild-freebsd-arm64": "0.15.10", + "esbuild-linux-32": "0.15.10", + "esbuild-linux-64": "0.15.10", + "esbuild-linux-arm": "0.15.10", + "esbuild-linux-arm64": "0.15.10", + "esbuild-linux-mips64le": "0.15.10", + "esbuild-linux-ppc64le": "0.15.10", + "esbuild-linux-riscv64": "0.15.10", + "esbuild-linux-s390x": "0.15.10", + "esbuild-netbsd-64": "0.15.10", + "esbuild-openbsd-64": "0.15.10", + "esbuild-sunos-64": "0.15.10", + "esbuild-windows-32": "0.15.10", + "esbuild-windows-64": "0.15.10", + "esbuild-windows-arm64": "0.15.10" + } + }, + "esbuild-windows-64": { + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz", + "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==", + "dev": true, + "optional": true + }, + "lit": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.4.0.tgz", + "integrity": "sha512-fdgzxEtLrZFQU/BqTtxFQCLwlZd9bdat+ltzSFjvWkZrs7eBmeX0L5MHUMb3kYIkuS8Xlfnii/iI5klirF8/Xg==", + "requires": { + "@lit/reactive-element": "^1.4.0", + "lit-element": "^3.2.0", + "lit-html": "^2.4.0" + } + }, + "lit-element": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.2.tgz", + "integrity": "sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==", + "requires": { + "@lit/reactive-element": "^1.3.0", + "lit-html": "^2.2.0" + } + }, + "lit-html": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.4.0.tgz", + "integrity": "sha512-G6qXu4JNUpY6aaF2VMfaszhO9hlWw0hOTRFDmuMheg/nDYGB+2RztUSOyrzALAbr8Nh0Y7qjhYkReh3rPnplVg==", + "requires": { + "@types/trusted-types": "^2.0.2" + } + } + } +} diff --git a/toolkit/content/vendor/lit/package.json b/toolkit/content/vendor/lit/package.json new file mode 100644 index 000000000000..21e8eae1e231 --- /dev/null +++ b/toolkit/content/vendor/lit/package.json @@ -0,0 +1,21 @@ +{ + "name": "vendor-lit", + "version": "1.0.0", + "description": "Vendor the lit package", + "main": "index.mjs", + "scripts": { + "build": "esbuild index.mjs --bundle --outfile=lit.all.mjs --format=esm --legal-comments=inline", + "patch": "patch lit.all.mjs lit-html-no-inner-html.patch", + "mv-dest": "mkdir -p ../../widgets/vendor && mv lit.all.mjs ../../widgets/vendor/lit.all.mjs", + "vendor": "npm install && npm run build && npm run patch && npm run mv-dest", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "MPL-2.0", + "dependencies": { + "lit": "^2.4.0" + }, + "devDependencies": { + "esbuild": "^0.15.10" + } +} diff --git a/toolkit/content/widgets/lit-utils.mjs b/toolkit/content/widgets/lit-utils.mjs new file mode 100644 index 000000000000..5798b5bc1409 --- /dev/null +++ b/toolkit/content/widgets/lit-utils.mjs @@ -0,0 +1,100 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Bug 1790483: Lit is not bundled yet, this is dev only. +// eslint-disable-next-line import/no-unresolved +import { query, queryAll, LitElement } from "./vendor/lit.all.mjs"; + +/** + * MozLitElement provides extensions to the lit-provided LitElement class. + * + ******* + * + * `@query` support (define a getter for a querySelector): + * + * static get queries() { + * return { + * propertyName: ".aNormal .cssSelector", + * anotherName: { all: ".selectorFor .querySelectorAll" }, + * }; + * } + * + * This example would add properties that would be written like this without + * using `queries`: + * + * get propertyName() { + * return this.renderRoot?.querySelector(".aNormal .cssSelector"); + * } + * + * get anotherName() { + * return this.renderRoot?.querySelectorAll(".selectorFor .querySelectorAll"); + * } + ******* + * + * Automatic Fluent support for shadow DOM. + * + * Fluent requires that a shadowRoot be connected before it can use Fluent. + * Shadow roots will get connected automatically. + * + ******* + * + * Test helper for sending events after a change: `dispatchOnUpdateComplete` + * + * When some async stuff is going on and you want to wait for it in a test, you + * can use `this.dispatchOnUpdateComplete(myEvent)` and have the test wait on + * your event. + * + * The component will then wait for your reactive property change to take effect + * and dispatch the desired event. + * + * Example: + * + * async onClick() { + * let response = await this.getServerResponse(this.data); + * // Show the response status to the user. + * this.responseStatus = respose.status; + * this.dispatchOnUpdateComplete( + * new CustomEvent("status-shown") + * ); + * } + * + * add_task(async testButton() { + * let button = this.setupAndGetButton(); + * button.click(); + * await BrowserTestUtils.waitForEvent(button, "status-shown"); + * }); + */ +export class MozLitElement extends LitElement { + constructor() { + super(); + let { queries } = this.constructor; + if (queries) { + for (let [name, selector] of Object.entries(queries)) { + if (selector.all) { + queryAll(selector.all)(this, name); + } else { + query(selector)(this, name); + } + } + } + } + + connectedCallback() { + super.connectedCallback(); + if (!this._l10nRootConnected && document.l10n) { + document.l10n.connectRoot(this.renderRoot); + this._l10nRootConnected = true; + } + } + + async dispatchOnUpdateComplete(event) { + await this.updateComplete; + this.dispatchEvent(event); + } + + update() { + super.update(); + document.l10n.translateFragment(this.renderRoot); + } +} diff --git a/tools/rewriting/ThirdPartyPaths.txt b/tools/rewriting/ThirdPartyPaths.txt index b99167e0bd35..92c88205e19b 100644 --- a/tools/rewriting/ThirdPartyPaths.txt +++ b/tools/rewriting/ThirdPartyPaths.txt @@ -176,6 +176,7 @@ toolkit/components/url-classifier/chromium/ toolkit/components/utils/mozjexl.js toolkit/components/viaduct/fetch_msg_types.pb.cc toolkit/components/viaduct/fetch_msg_types.pb.h +toolkit/content/widgets/vendor/lit.all.mjs toolkit/crashreporter/breakpad-client/ toolkit/crashreporter/google-breakpad/ tools/fuzzing/libfuzzer/