diff --git a/.hgignore b/.hgignore index 343853737325..b269c5fd6959 100644 --- a/.hgignore +++ b/.hgignore @@ -170,6 +170,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/browser/components/storybook/mach_commands.py b/browser/components/storybook/mach_commands.py index d4ffa312b0e6..faf4f5b8e917 100644 --- a/browser/components/storybook/mach_commands.py +++ b/browser/components/storybook/mach_commands.py @@ -37,6 +37,12 @@ def storybook_launch(command_context): description="Install Storybook node dependencies.", ) def storybook_install(command_context): + # Bug 1790483: First, we need to make sure lit is installed + run_mach( + command_context, + "npm", + args=["run", "vendor", "--prefix=toolkit/content/vendor/lit"], + ) return run_npm(command_context, args=["ci"]) diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn index d44125ba7c12..3ca2ad460372 100644 --- a/toolkit/content/jar.mn +++ b/toolkit/content/jar.mn @@ -112,8 +112,6 @@ toolkit.jar: content/global/elements/videocontrols.js (widgets/videocontrols.js) content/global/elements/tree.js (widgets/tree.js) content/global/elements/wizard.js (widgets/wizard.js) - content/global/vendor/lit.all.mjs (widgets/vendor/lit.all.mjs) - content/global/lit-utils.mjs (widgets/lit-utils.mjs) content/global/neterror/aboutNetErrorCodes.js (neterror/aboutNetErrorCodes.js) content/global/neterror/supportpages/connection-not-secure.html (neterror/supportpages/connection-not-secure.html) content/global/neterror/supportpages/time-errors.html (neterror/supportpages/time-errors.html) diff --git a/toolkit/content/vendor/lit/0001-disable-terser-step.patch b/toolkit/content/vendor/lit/0001-disable-terser-step.patch deleted file mode 100644 index 244f528d4c2f..000000000000 --- a/toolkit/content/vendor/lit/0001-disable-terser-step.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 1f0db62374e62965f521c3a44c31c947f702d53d Mon Sep 17 00:00:00 2001 -From: Mark Striemer -Date: Wed, 16 Nov 2022 22:54:20 -0600 -Subject: [PATCH 1/2] disable terser step - ---- - rollup-common.js | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/rollup-common.js b/rollup-common.js -index ebe4b406..6fcac21a 100644 ---- a/rollup-common.js -+++ b/rollup-common.js -@@ -345,7 +345,7 @@ export function litProdConfig({ - virtual({ - [nameCacheSeederInfile]: nameCacheSeederContents, - }), -- terser(nameCacheSeederTerserOptions), -+ // terser(nameCacheSeederTerserOptions), - skipBundleOutput, - ], - }, -@@ -395,7 +395,7 @@ export function litProdConfig({ - // This plugin automatically composes the existing TypeScript -> raw JS - // sourcemap with the raw JS -> minified JS one that we're generating here. - sourcemaps(), -- terser(terserOptions), -+ // terser(terserOptions), - summary({ - showBrotliSize: true, - showGzippedSize: true, -@@ -466,7 +466,7 @@ export function litProdConfig({ - // references properties from reactive-element which will - // otherwise have different names. The default export that - // lit-element will use is minified. -- terser(terserOptions), -+ // terser(terserOptions), - summary({ - showBrotliSize: true, - showGzippedSize: true, -@@ -533,7 +533,7 @@ const litMonoBundleConfig = ({ - // This plugin automatically composes the existing TypeScript -> raw JS - // sourcemap with the raw JS -> minified JS one that we're generating here. - sourcemaps(), -- terser(terserOptions), -+ // terser(terserOptions), - summary({ - showBrotliSize: true, - showGzippedSize: true, --- -2.32.0 (Apple Git-132) - diff --git a/toolkit/content/vendor/lit/0002-use-DOMParser-not-innerHTML.patch b/toolkit/content/vendor/lit/0002-use-DOMParser-not-innerHTML.patch deleted file mode 100644 index 63a489df5b68..000000000000 --- a/toolkit/content/vendor/lit/0002-use-DOMParser-not-innerHTML.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e2fb71a850fda2d1f02a19d41a3db1cd7cf8618d Mon Sep 17 00:00:00 2001 -From: Mark Striemer -Date: Wed, 16 Nov 2022 23:07:57 -0600 -Subject: [PATCH 2/2] use DOMParser not innerHTML= - ---- - packages/lit-html/src/lit-html.ts | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/packages/lit-html/src/lit-html.ts b/packages/lit-html/src/lit-html.ts -index 51941fdf..13914ca7 100644 ---- a/packages/lit-html/src/lit-html.ts -+++ b/packages/lit-html/src/lit-html.ts -@@ -14,6 +14,8 @@ const NODE_MODE = false; - // Use window for browser builds because IE11 doesn't have globalThis. - const global = NODE_MODE ? globalThis : window; - -+const __moz_domParser = new DOMParser(); -+ - /** - * Contains types that are part of the unstable debug API. - * -@@ -1017,9 +1019,14 @@ class Template { - // Overridden via `litHtmlPolyfillSupport` to provide platform support. - /** @nocollapse */ - static createElement(html: TrustedHTML, _options?: RenderOptions) { -- const el = d.createElement('template'); -- el.innerHTML = html as unknown as string; -- return el; -+ const doc = __moz_domParser.parseFromString( -+ ``, -+ 'text/html' -+ ); -+ return document.importNode( -+ doc.querySelector('template') as HTMLTemplateElement, -+ true -+ ); - } - } - --- -2.32.0 (Apple Git-132) - diff --git a/toolkit/content/vendor/lit/LICENSE b/toolkit/content/vendor/lit/LICENSE index be7a97b60d79..c8ed22676f58 100644 --- a/toolkit/content/vendor/lit/LICENSE +++ b/toolkit/content/vendor/lit/LICENSE @@ -25,4 +25,4 @@ 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. \ No newline at end of file +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 index 138c28a8b0da..81f640b75ebe 100644 --- a/toolkit/content/vendor/lit/README.md +++ b/toolkit/content/vendor/lit/README.md @@ -21,26 +21,11 @@ import { classMap, LitElement } from "../vendor/lit.all.mjs"; ## To update the lit bundle -Vendoring runs off of the latest tag in the https://github.com/lit/lit repo. If -the latest tag is a lit@ tag then running the vendor command will update to that -version. If the latest tag isn't for lit@, you may need to bundle manually. See -the moz.yaml file for instructions. - -### Using mach vendor +Using `mach`s `npm` you can update the bundle with: ``` -./mach vendor toolkit/content/vendor/lit/moz.yaml -hg ci -m "Update to lit@" +cd toolkit/content/vendor/lit +../../../../mach npm run vendor ``` -### Manually updating the bundle - -To manually update, you'll need to checkout a copy of lit/lit, find the tag you -want and manually run our import commands. - - 1. Clone https://github.com/lit/lit outside of moz-central - 2. Copy *.patch from this directory into the lit repo - 3. git apply *.patch - 4. npm install && npm run build - 5. Copy packages/lit/lit-all.min.js to toolkit/content/widgets/vendor/lit.all.mjs - 6. hg ci -m "Update to lit@" +Then commit the changes. diff --git a/toolkit/content/vendor/lit/bundle-lit.sh b/toolkit/content/vendor/lit/bundle-lit.sh deleted file mode 100755 index 532b48337f5e..000000000000 --- a/toolkit/content/vendor/lit/bundle-lit.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -cp *.patch lit/ -cd lit -git apply *.patch -../../../../../mach npm install -../../../../../mach npm run build -cp packages/lit/lit-all.min.js ../../../widgets/vendor/lit.all.mjs -rm -rf * .* -cp ../LICENSE . 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/lit/LICENSE b/toolkit/content/vendor/lit/lit/LICENSE deleted file mode 100644 index be7a97b60d79..000000000000 --- a/toolkit/content/vendor/lit/lit/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -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. \ No newline at end of file diff --git a/toolkit/content/vendor/lit/moz.yaml b/toolkit/content/vendor/lit/moz.yaml index b4948b29702f..0997a244b168 100644 --- a/toolkit/content/vendor/lit/moz.yaml +++ b/toolkit/content/vendor/lit/moz.yaml @@ -10,24 +10,5 @@ origin: "Lit is a simple library for building fast, lightweight web components." url: "https://github.com/lit/lit" license: "BSD-3-Clause" - release: lit@2.4.1 (2022-11-03T15:20:49-07:00). - revision: lit@2.4.1 - - -# Since this tracks the latest tag, it's possible that lit isn't the latest tag -# in lit/lit. In that case we may need to manually update lit. See README.md for -# more info. -vendoring: - url: "https://github.com/lit/lit" - source-hosting: github - tracking: tag - # lit/lit is a monorepo that publishes multiple packages. The tags for lit - # are formatted as "lit@2.4.1". - # tag-prefix: 'lit@' - - vendor-directory: toolkit/content/vendor/lit/lit - - update-actions: - - action: run-script - script: '{yaml_dir}/bundle-lit.sh' - cwd: '{yaml_dir}' + 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..3d6b6e5e22a1 --- /dev/null +++ b/toolkit/content/vendor/lit/package-lock.json @@ -0,0 +1,204 @@ +{ + "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", + "mkdirp": "^1.0.4" + } + }, + "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" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + } + }, + "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" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } +} diff --git a/toolkit/content/vendor/lit/package.json b/toolkit/content/vendor/lit/package.json new file mode 100644 index 000000000000..5d727785da0b --- /dev/null +++ b/toolkit/content/vendor/lit/package.json @@ -0,0 +1,22 @@ +{ + "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": "mkdirp ../../widgets/vendor && mv lit.all.mjs ../../widgets/vendor/lit.all.mjs", + "vendor": "npm ci && 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", + "mkdirp": "^1.0.4" + } +} diff --git a/toolkit/content/widgets/fx-toggle/fx-toggle.mjs b/toolkit/content/widgets/fx-toggle/fx-toggle.mjs index df277db6686f..ebda9ded034a 100644 --- a/toolkit/content/widgets/fx-toggle/fx-toggle.mjs +++ b/toolkit/content/widgets/fx-toggle/fx-toggle.mjs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at htp://mozilla.org/MPL/2.0/. */ +// Bug 1790483: Lit is not bundled yet, this is dev only. +// eslint-disable-next-line import/no-unresolved import { html, ifDefined } from "../vendor/lit.all.mjs"; import { MozLitElement } from "../lit-utils.mjs"; diff --git a/toolkit/content/widgets/fx-toggle/fx-toggle.stories.mjs b/toolkit/content/widgets/fx-toggle/fx-toggle.stories.mjs index edf748ce4ff9..7b4ce521c140 100644 --- a/toolkit/content/widgets/fx-toggle/fx-toggle.stories.mjs +++ b/toolkit/content/widgets/fx-toggle/fx-toggle.stories.mjs @@ -2,6 +2,8 @@ * 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 { html, ifDefined } from "../vendor/lit.all.mjs"; // eslint-disable-next-line import/no-unassigned-import import "./fx-toggle.mjs"; diff --git a/toolkit/content/widgets/lit-utils.mjs b/toolkit/content/widgets/lit-utils.mjs index 38dbaaa04f2b..815a2d9b594f 100644 --- a/toolkit/content/widgets/lit-utils.mjs +++ b/toolkit/content/widgets/lit-utils.mjs @@ -2,25 +2,9 @@ * 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/. */ -import { LitElement } from "./vendor/lit.all.mjs"; - -/** - * Helper for our replacement of @query. Used with `static queries` property. - * - * https://github.com/lit/lit/blob/main/packages/reactive-element/src/decorators/query.ts - */ -function query(el, selector) { - return () => el.renderRoot.querySelector(selector); -} - -/** - * Helper for our replacement of @queryAll. Used with `static queries` property. - * - * https://github.com/lit/lit/blob/main/packages/reactive-element/src/decorators/query-all.ts - */ -function queryAll(el, selector) { - return () => el.renderRoot.querySelectorAll(selector); -} +// 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. @@ -88,13 +72,9 @@ export class MozLitElement extends LitElement { if (queries) { for (let [name, selector] of Object.entries(queries)) { if (selector.all) { - Object.defineProperty(this, name, { - get: queryAll(this, selector.all), - }); + queryAll(selector.all)(this, name); } else { - Object.defineProperty(this, name, { - get: query(this, selector), - }); + query(selector)(this, name); } } } diff --git a/toolkit/content/widgets/vendor/lit.all.mjs b/toolkit/content/widgets/vendor/lit.all.mjs deleted file mode 100644 index a7999a4d0dc7..000000000000 --- a/toolkit/content/widgets/vendor/lit.all.mjs +++ /dev/null @@ -1,4497 +0,0 @@ -/** - * @license - * Copyright 2019 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const NODE_MODE$1 = false; -const global$2 = window; -/** - * Whether the current browser supports `adoptedStyleSheets`. - */ -const supportsAdoptingStyleSheets = global$2.ShadowRoot && - (global$2.ShadyCSS === undefined || global$2.ShadyCSS.nativeShadow) && - 'adoptedStyleSheets' in Document.prototype && - 'replace' in CSSStyleSheet.prototype; -const constructionToken = Symbol(); -const cssTagCache = new WeakMap(); -/** - * A container for a string of CSS text, that may be used to create a CSSStyleSheet. - * - * CSSResult is the return value of `css`-tagged template literals and - * `unsafeCSS()`. In order to ensure that CSSResults are only created via the - * `css` tag and `unsafeCSS()`, CSSResult cannot be constructed directly. - */ -class CSSResult { - constructor(cssText, strings, safeToken) { - // This property needs to remain unminified. - this['_$cssResult$'] = true; - if (safeToken !== constructionToken) { - throw new Error('CSSResult is not constructable. Use `unsafeCSS` or `css` instead.'); - } - this.cssText = cssText; - this._strings = strings; - } - // This is a getter so that it's lazy. In practice, this means stylesheets - // are not created until the first element instance is made. - get styleSheet() { - // If `supportsAdoptingStyleSheets` is true then we assume CSSStyleSheet is - // constructable. - let styleSheet = this._styleSheet; - const strings = this._strings; - if (supportsAdoptingStyleSheets && styleSheet === undefined) { - const cacheable = strings !== undefined && strings.length === 1; - if (cacheable) { - styleSheet = cssTagCache.get(strings); - } - if (styleSheet === undefined) { - (this._styleSheet = styleSheet = new CSSStyleSheet()).replaceSync(this.cssText); - if (cacheable) { - cssTagCache.set(strings, styleSheet); - } - } - } - return styleSheet; - } - toString() { - return this.cssText; - } -} -const textFromCSSResult = (value) => { - // This property needs to remain unminified. - if (value['_$cssResult$'] === true) { - return value.cssText; - } - else if (typeof value === 'number') { - return value; - } - else { - throw new Error(`Value passed to 'css' function must be a 'css' function result: ` + - `${value}. Use 'unsafeCSS' to pass non-literal values, but take care ` + - `to ensure page security.`); - } -}; -/** - * Wrap a value for interpolation in a {@linkcode css} tagged template literal. - * - * This is unsafe because untrusted CSS text can be used to phone home - * or exfiltrate data to an attacker controlled site. Take care to only use - * this with trusted input. - */ -const unsafeCSS = (value) => new CSSResult(typeof value === 'string' ? value : String(value), undefined, constructionToken); -/** - * A template literal tag which can be used with LitElement's - * {@linkcode LitElement.styles} property to set element styles. - * - * For security reasons, only literal string values and number may be used in - * embedded expressions. To incorporate non-literal values {@linkcode unsafeCSS} - * may be used inside an expression. - */ -const css = (strings, ...values) => { - const cssText = strings.length === 1 - ? strings[0] - : values.reduce((acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1], strings[0]); - return new CSSResult(cssText, strings, constructionToken); -}; -/** - * Applies the given styles to a `shadowRoot`. When Shadow DOM is - * available but `adoptedStyleSheets` is not, styles are appended to the - * `shadowRoot` to [mimic spec behavior](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets). - * Note, when shimming is used, any styles that are subsequently placed into - * the shadowRoot should be placed *before* any shimmed adopted styles. This - * will match spec behavior that gives adopted sheets precedence over styles in - * shadowRoot. - */ -const adoptStyles = (renderRoot, styles) => { - if (supportsAdoptingStyleSheets) { - renderRoot.adoptedStyleSheets = styles.map((s) => s instanceof CSSStyleSheet ? s : s.styleSheet); - } - else { - styles.forEach((s) => { - const style = document.createElement('style'); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const nonce = global$2['litNonce']; - if (nonce !== undefined) { - style.setAttribute('nonce', nonce); - } - style.textContent = s.cssText; - renderRoot.appendChild(style); - }); - } -}; -const cssResultFromStyleSheet = (sheet) => { - let cssText = ''; - for (const rule of sheet.cssRules) { - cssText += rule.cssText; - } - return unsafeCSS(cssText); -}; -const getCompatibleStyle = supportsAdoptingStyleSheets || - (NODE_MODE$1 ) - ? (s) => s - : (s) => s instanceof CSSStyleSheet ? cssResultFromStyleSheet(s) : s; - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -var _d$1; -var _e; -const global$1 = window; -const trustedTypes$1 = global$1 - .trustedTypes; -// Temporary workaround for https://crbug.com/993268 -// Currently, any attribute starting with "on" is considered to be a -// TrustedScript source. Such boolean attributes must be set to the equivalent -// trusted emptyScript value. -const emptyStringForBooleanAttribute$1 = trustedTypes$1 - ? trustedTypes$1.emptyScript - : ''; -const polyfillSupport$2 = global$1.reactiveElementPolyfillSupport; -/* - * When using Closure Compiler, JSCompiler_renameProperty(property, object) is - * replaced at compile time by the munged name for object[property]. We cannot - * alias this function, so we have to use a small shim that has the same - * behavior when not compiling. - */ -/*@__INLINE__*/ -const JSCompiler_renameProperty = (prop, _obj) => prop; -const defaultConverter = { - toAttribute(value, type) { - switch (type) { - case Boolean: - value = value ? emptyStringForBooleanAttribute$1 : null; - break; - case Object: - case Array: - // if the value is `null` or `undefined` pass this through - // to allow removing/no change behavior. - value = value == null ? value : JSON.stringify(value); - break; - } - return value; - }, - fromAttribute(value, type) { - let fromValue = value; - switch (type) { - case Boolean: - fromValue = value !== null; - break; - case Number: - fromValue = value === null ? null : Number(value); - break; - case Object: - case Array: - // Do *not* generate exception when invalid JSON is set as elements - // don't normally complain on being mis-configured. - // TODO(sorvell): Do generate exception in *dev mode*. - try { - // Assert to adhere to Bazel's "must type assert JSON parse" rule. - fromValue = JSON.parse(value); - } - catch (e) { - fromValue = null; - } - break; - } - return fromValue; - }, -}; -/** - * Change function that returns true if `value` is different from `oldValue`. - * This method is used as the default for a property's `hasChanged` function. - */ -const notEqual = (value, old) => { - // This ensures (old==NaN, value==NaN) always returns false - return old !== value && (old === old || value === value); -}; -const defaultPropertyDeclaration = { - attribute: true, - type: String, - converter: defaultConverter, - reflect: false, - hasChanged: notEqual, -}; -/** - * The Closure JS Compiler doesn't currently have good support for static - * property semantics where "this" is dynamic (e.g. - * https://github.com/google/closure-compiler/issues/3177 and others) so we use - * this hack to bypass any rewriting by the compiler. - */ -const finalized = 'finalized'; -/** - * Base element class which manages element properties and attributes. When - * properties change, the `update` method is asynchronously called. This method - * should be supplied by subclassers to render updates as desired. - * @noInheritDoc - */ -class ReactiveElement extends HTMLElement { - constructor() { - super(); - this.__instanceProperties = new Map(); - /** - * True if there is a pending update as a result of calling `requestUpdate()`. - * Should only be read. - * @category updates - */ - this.isUpdatePending = false; - /** - * Is set to `true` after the first update. The element code cannot assume - * that `renderRoot` exists before the element `hasUpdated`. - * @category updates - */ - this.hasUpdated = false; - /** - * Name of currently reflecting property - */ - this.__reflectingProperty = null; - this._initialize(); - } - /** - * Adds an initializer function to the class that is called during instance - * construction. - * - * This is useful for code that runs against a `ReactiveElement` - * subclass, such as a decorator, that needs to do work for each - * instance, such as setting up a `ReactiveController`. - * - * ```ts - * const myDecorator = (target: typeof ReactiveElement, key: string) => { - * target.addInitializer((instance: ReactiveElement) => { - * // This is run during construction of the element - * new MyController(instance); - * }); - * } - * ``` - * - * Decorating a field will then cause each instance to run an initializer - * that adds a controller: - * - * ```ts - * class MyElement extends LitElement { - * @myDecorator foo; - * } - * ``` - * - * Initializers are stored per-constructor. Adding an initializer to a - * subclass does not add it to a superclass. Since initializers are run in - * constructors, initializers will run in order of the class hierarchy, - * starting with superclasses and progressing to the instance's class. - * - * @nocollapse - */ - static addInitializer(initializer) { - var _a; - this.finalize(); - ((_a = this._initializers) !== null && _a !== void 0 ? _a : (this._initializers = [])).push(initializer); - } - /** - * Returns a list of attributes corresponding to the registered properties. - * @nocollapse - * @category attributes - */ - static get observedAttributes() { - // note: piggy backing on this to ensure we're finalized. - this.finalize(); - const attributes = []; - // Use forEach so this works even if for/of loops are compiled to for loops - // expecting arrays - this.elementProperties.forEach((v, p) => { - const attr = this.__attributeNameForProperty(p, v); - if (attr !== undefined) { - this.__attributeToPropertyMap.set(attr, p); - attributes.push(attr); - } - }); - return attributes; - } - /** - * Creates a property accessor on the element prototype if one does not exist - * and stores a {@linkcode PropertyDeclaration} for the property with the - * given options. The property setter calls the property's `hasChanged` - * property option or uses a strict identity check to determine whether or not - * to request an update. - * - * This method may be overridden to customize properties; however, - * when doing so, it's important to call `super.createProperty` to ensure - * the property is setup correctly. This method calls - * `getPropertyDescriptor` internally to get a descriptor to install. - * To customize what properties do when they are get or set, override - * `getPropertyDescriptor`. To customize the options for a property, - * implement `createProperty` like this: - * - * ```ts - * static createProperty(name, options) { - * options = Object.assign(options, {myOption: true}); - * super.createProperty(name, options); - * } - * ``` - * - * @nocollapse - * @category properties - */ - static createProperty(name, options = defaultPropertyDeclaration) { - // if this is a state property, force the attribute to false. - if (options.state) { - // Cast as any since this is readonly. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - options.attribute = false; - } - // Note, since this can be called by the `@property` decorator which - // is called before `finalize`, we ensure finalization has been kicked off. - this.finalize(); - this.elementProperties.set(name, options); - // Do not generate an accessor if the prototype already has one, since - // it would be lost otherwise and that would never be the user's intention; - // Instead, we expect users to call `requestUpdate` themselves from - // user-defined accessors. Note that if the super has an accessor we will - // still overwrite it - if (!options.noAccessor && !this.prototype.hasOwnProperty(name)) { - const key = typeof name === 'symbol' ? Symbol() : `__${name}`; - const descriptor = this.getPropertyDescriptor(name, key, options); - if (descriptor !== undefined) { - Object.defineProperty(this.prototype, name, descriptor); - } - } - } - /** - * Returns a property descriptor to be defined on the given named property. - * If no descriptor is returned, the property will not become an accessor. - * For example, - * - * ```ts - * class MyElement extends LitElement { - * static getPropertyDescriptor(name, key, options) { - * const defaultDescriptor = - * super.getPropertyDescriptor(name, key, options); - * const setter = defaultDescriptor.set; - * return { - * get: defaultDescriptor.get, - * set(value) { - * setter.call(this, value); - * // custom action. - * }, - * configurable: true, - * enumerable: true - * } - * } - * } - * ``` - * - * @nocollapse - * @category properties - */ - static getPropertyDescriptor(name, key, options) { - return { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - get() { - return this[key]; - }, - set(value) { - const oldValue = this[name]; - this[key] = value; - this.requestUpdate(name, oldValue, options); - }, - configurable: true, - enumerable: true, - }; - } - /** - * Returns the property options associated with the given property. - * These options are defined with a `PropertyDeclaration` via the `properties` - * object or the `@property` decorator and are registered in - * `createProperty(...)`. - * - * Note, this method should be considered "final" and not overridden. To - * customize the options for a given property, override - * {@linkcode createProperty}. - * - * @nocollapse - * @final - * @category properties - */ - static getPropertyOptions(name) { - return this.elementProperties.get(name) || defaultPropertyDeclaration; - } - /** - * Creates property accessors for registered properties, sets up element - * styling, and ensures any superclasses are also finalized. Returns true if - * the element was finalized. - * @nocollapse - */ - static finalize() { - if (this.hasOwnProperty(finalized)) { - return false; - } - this[finalized] = true; - // finalize any superclasses - const superCtor = Object.getPrototypeOf(this); - superCtor.finalize(); - // Create own set of initializers for this class if any exist on the - // superclass and copy them down. Note, for a small perf boost, avoid - // creating initializers unless needed. - if (superCtor._initializers !== undefined) { - this._initializers = [...superCtor._initializers]; - } - this.elementProperties = new Map(superCtor.elementProperties); - // initialize Map populated in observedAttributes - this.__attributeToPropertyMap = new Map(); - // make any properties - // Note, only process "own" properties since this element will inherit - // any properties defined on the superClass, and finalization ensures - // the entire prototype chain is finalized. - if (this.hasOwnProperty(JSCompiler_renameProperty('properties'))) { - const props = this.properties; - // support symbols in properties (IE11 does not support this) - const propKeys = [ - ...Object.getOwnPropertyNames(props), - ...Object.getOwnPropertySymbols(props), - ]; - // This for/of is ok because propKeys is an array - for (const p of propKeys) { - // note, use of `any` is due to TypeScript lack of support for symbol in - // index types - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.createProperty(p, props[p]); - } - } - this.elementStyles = this.finalizeStyles(this.styles); - return true; - } - /** - * Takes the styles the user supplied via the `static styles` property and - * returns the array of styles to apply to the element. - * Override this method to integrate into a style management system. - * - * Styles are deduplicated preserving the _last_ instance in the list. This - * is a performance optimization to avoid duplicated styles that can occur - * especially when composing via subclassing. The last item is kept to try - * to preserve the cascade order with the assumption that it's most important - * that last added styles override previous styles. - * - * @nocollapse - * @category styles - */ - static finalizeStyles(styles) { - const elementStyles = []; - if (Array.isArray(styles)) { - // Dedupe the flattened array in reverse order to preserve the last items. - // Casting to Array works around TS error that - // appears to come from trying to flatten a type CSSResultArray. - const set = new Set(styles.flat(Infinity).reverse()); - // Then preserve original order by adding the set items in reverse order. - for (const s of set) { - elementStyles.unshift(getCompatibleStyle(s)); - } - } - else if (styles !== undefined) { - elementStyles.push(getCompatibleStyle(styles)); - } - return elementStyles; - } - /** - * Returns the property name for the given attribute `name`. - * @nocollapse - */ - static __attributeNameForProperty(name, options) { - const attribute = options.attribute; - return attribute === false - ? undefined - : typeof attribute === 'string' - ? attribute - : typeof name === 'string' - ? name.toLowerCase() - : undefined; - } - /** - * Internal only override point for customizing work done when elements - * are constructed. - * - * @internal - */ - _initialize() { - var _a; - this.__updatePromise = new Promise((res) => (this.enableUpdating = res)); - this._$changedProperties = new Map(); - this.__saveInstanceProperties(); - // ensures first update will be caught by an early access of - // `updateComplete` - this.requestUpdate(); - (_a = this.constructor._initializers) === null || _a === void 0 ? void 0 : _a.forEach((i) => i(this)); - } - /** - * Registers a `ReactiveController` to participate in the element's reactive - * update cycle. The element automatically calls into any registered - * controllers during its lifecycle callbacks. - * - * If the element is connected when `addController()` is called, the - * controller's `hostConnected()` callback will be immediately called. - * @category controllers - */ - addController(controller) { - var _a, _b; - ((_a = this.__controllers) !== null && _a !== void 0 ? _a : (this.__controllers = [])).push(controller); - // If a controller is added after the element has been connected, - // call hostConnected. Note, re-using existence of `renderRoot` here - // (which is set in connectedCallback) to avoid the need to track a - // first connected state. - if (this.renderRoot !== undefined && this.isConnected) { - (_b = controller.hostConnected) === null || _b === void 0 ? void 0 : _b.call(controller); - } - } - /** - * Removes a `ReactiveController` from the element. - * @category controllers - */ - removeController(controller) { - var _a; - // Note, if the indexOf is -1, the >>> will flip the sign which makes the - // splice do nothing. - (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.splice(this.__controllers.indexOf(controller) >>> 0, 1); - } - /** - * Fixes any properties set on the instance before upgrade time. - * Otherwise these would shadow the accessor and break these properties. - * The properties are stored in a Map which is played back after the - * constructor runs. Note, on very old versions of Safari (<=9) or Chrome - * (<=41), properties created for native platform properties like (`id` or - * `name`) may not have default values set in the element constructor. On - * these browsers native properties appear on instances and therefore their - * default value will overwrite any element default (e.g. if the element sets - * this.id = 'id' in the constructor, the 'id' will become '' since this is - * the native platform default). - */ - __saveInstanceProperties() { - // Use forEach so this works even if for/of loops are compiled to for loops - // expecting arrays - this.constructor.elementProperties.forEach((_v, p) => { - if (this.hasOwnProperty(p)) { - this.__instanceProperties.set(p, this[p]); - delete this[p]; - } - }); - } - /** - * Returns the node into which the element should render and by default - * creates and returns an open shadowRoot. Implement to customize where the - * element's DOM is rendered. For example, to render into the element's - * childNodes, return `this`. - * - * @return Returns a node into which to render. - * @category rendering - */ - createRenderRoot() { - var _a; - const renderRoot = (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this.attachShadow(this.constructor.shadowRootOptions); - adoptStyles(renderRoot, this.constructor.elementStyles); - return renderRoot; - } - /** - * On first connection, creates the element's renderRoot, sets up - * element styling, and enables updating. - * @category lifecycle - */ - connectedCallback() { - var _a; - // create renderRoot before first update. - if (this.renderRoot === undefined) { - this.renderRoot = this.createRenderRoot(); - } - this.enableUpdating(true); - (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostConnected) === null || _a === void 0 ? void 0 : _a.call(c); }); - } - /** - * Note, this method should be considered final and not overridden. It is - * overridden on the element instance with a function that triggers the first - * update. - * @category updates - */ - enableUpdating(_requestedUpdate) { } - /** - * Allows for `super.disconnectedCallback()` in extensions while - * reserving the possibility of making non-breaking feature additions - * when disconnecting at some point in the future. - * @category lifecycle - */ - disconnectedCallback() { - var _a; - (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostDisconnected) === null || _a === void 0 ? void 0 : _a.call(c); }); - } - /** - * Synchronizes property values when attributes change. - * - * Specifically, when an attribute is set, the corresponding property is set. - * You should rarely need to implement this callback. If this method is - * overridden, `super.attributeChangedCallback(name, _old, value)` must be - * called. - * - * See [using the lifecycle callbacks](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks) - * on MDN for more information about the `attributeChangedCallback`. - * @category attributes - */ - attributeChangedCallback(name, _old, value) { - this._$attributeToProperty(name, value); - } - __propertyToAttribute(name, value, options = defaultPropertyDeclaration) { - var _a; - const attr = this.constructor.__attributeNameForProperty(name, options); - if (attr !== undefined && options.reflect === true) { - const converter = ((_a = options.converter) === null || _a === void 0 ? void 0 : _a.toAttribute) !== - undefined - ? options.converter - : defaultConverter; - const attrValue = converter.toAttribute(value, options.type); - // Track if the property is being reflected to avoid - // setting the property again via `attributeChangedCallback`. Note: - // 1. this takes advantage of the fact that the callback is synchronous. - // 2. will behave incorrectly if multiple attributes are in the reaction - // stack at time of calling. However, since we process attributes - // in `update` this should not be possible (or an extreme corner case - // that we'd like to discover). - // mark state reflecting - this.__reflectingProperty = name; - if (attrValue == null) { - this.removeAttribute(attr); - } - else { - this.setAttribute(attr, attrValue); - } - // mark state not reflecting - this.__reflectingProperty = null; - } - } - /** @internal */ - _$attributeToProperty(name, value) { - var _a; - const ctor = this.constructor; - // Note, hint this as an `AttributeMap` so closure clearly understands - // the type; it has issues with tracking types through statics - const propName = ctor.__attributeToPropertyMap.get(name); - // Use tracking info to avoid reflecting a property value to an attribute - // if it was just set because the attribute changed. - if (propName !== undefined && this.__reflectingProperty !== propName) { - const options = ctor.getPropertyOptions(propName); - const converter = typeof options.converter === 'function' - ? { fromAttribute: options.converter } - : ((_a = options.converter) === null || _a === void 0 ? void 0 : _a.fromAttribute) !== undefined - ? options.converter - : defaultConverter; - // mark state reflecting - this.__reflectingProperty = propName; - this[propName] = converter.fromAttribute(value, options.type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ); - // mark state not reflecting - this.__reflectingProperty = null; - } - } - /** - * Requests an update which is processed asynchronously. This should be called - * when an element should update based on some state not triggered by setting - * a reactive property. In this case, pass no arguments. It should also be - * called when manually implementing a property setter. In this case, pass the - * property `name` and `oldValue` to ensure that any configured property - * options are honored. - * - * @param name name of requesting property - * @param oldValue old value of requesting property - * @param options property options to use instead of the previously - * configured options - * @category updates - */ - requestUpdate(name, oldValue, options) { - let shouldRequestUpdate = true; - // If we have a property key, perform property update steps. - if (name !== undefined) { - options = - options || - this.constructor.getPropertyOptions(name); - const hasChanged = options.hasChanged || notEqual; - if (hasChanged(this[name], oldValue)) { - if (!this._$changedProperties.has(name)) { - this._$changedProperties.set(name, oldValue); - } - // Add to reflecting properties set. - // Note, it's important that every change has a chance to add the - // property to `_reflectingProperties`. This ensures setting - // attribute + property reflects correctly. - if (options.reflect === true && this.__reflectingProperty !== name) { - if (this.__reflectingProperties === undefined) { - this.__reflectingProperties = new Map(); - } - this.__reflectingProperties.set(name, options); - } - } - else { - // Abort the request if the property should not be considered changed. - shouldRequestUpdate = false; - } - } - if (!this.isUpdatePending && shouldRequestUpdate) { - this.__updatePromise = this.__enqueueUpdate(); - } - // Note, since this no longer returns a promise, in dev mode we return a - // thenable which warns if it's called. - return undefined; - } - /** - * Sets up the element to asynchronously update. - */ - async __enqueueUpdate() { - this.isUpdatePending = true; - try { - // Ensure any previous update has resolved before updating. - // This `await` also ensures that property changes are batched. - await this.__updatePromise; - } - catch (e) { - // Refire any previous errors async so they do not disrupt the update - // cycle. Errors are refired so developers have a chance to observe - // them, and this can be done by implementing - // `window.onunhandledrejection`. - Promise.reject(e); - } - const result = this.scheduleUpdate(); - // If `scheduleUpdate` returns a Promise, we await it. This is done to - // enable coordinating updates with a scheduler. Note, the result is - // checked to avoid delaying an additional microtask unless we need to. - if (result != null) { - await result; - } - return !this.isUpdatePending; - } - /** - * Schedules an element update. You can override this method to change the - * timing of updates by returning a Promise. The update will await the - * returned Promise, and you should resolve the Promise to allow the update - * to proceed. If this method is overridden, `super.scheduleUpdate()` - * must be called. - * - * For instance, to schedule updates to occur just before the next frame: - * - * ```ts - * override protected async scheduleUpdate(): Promise { - * await new Promise((resolve) => requestAnimationFrame(() => resolve())); - * super.scheduleUpdate(); - * } - * ``` - * @category updates - */ - scheduleUpdate() { - return this.performUpdate(); - } - /** - * Performs an element update. Note, if an exception is thrown during the - * update, `firstUpdated` and `updated` will not be called. - * - * Call `performUpdate()` to immediately process a pending update. This should - * generally not be needed, but it can be done in rare cases when you need to - * update synchronously. - * - * Note: To ensure `performUpdate()` synchronously completes a pending update, - * it should not be overridden. In LitElement 2.x it was suggested to override - * `performUpdate()` to also customizing update scheduling. Instead, you should now - * override `scheduleUpdate()`. For backwards compatibility with LitElement 2.x, - * scheduling updates via `performUpdate()` continues to work, but will make - * also calling `performUpdate()` to synchronously process updates difficult. - * - * @category updates - */ - performUpdate() { - var _b; - // Abort any update if one is not pending when this is called. - // This can happen if `performUpdate` is called early to "flush" - // the update. - if (!this.isUpdatePending) { - return; - } - // create renderRoot before first update. - if (!this.hasUpdated) ; - // Mixin instance properties once, if they exist. - if (this.__instanceProperties) { - // Use forEach so this works even if for/of loops are compiled to for loops - // expecting arrays - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.__instanceProperties.forEach((v, p) => (this[p] = v)); - this.__instanceProperties = undefined; - } - let shouldUpdate = false; - const changedProperties = this._$changedProperties; - try { - shouldUpdate = this.shouldUpdate(changedProperties); - if (shouldUpdate) { - this.willUpdate(changedProperties); - (_b = this.__controllers) === null || _b === void 0 ? void 0 : _b.forEach((c) => { var _a; return (_a = c.hostUpdate) === null || _a === void 0 ? void 0 : _a.call(c); }); - this.update(changedProperties); - } - else { - this.__markUpdated(); - } - } - catch (e) { - // Prevent `firstUpdated` and `updated` from running when there's an - // update exception. - shouldUpdate = false; - // Ensure element can accept additional updates after an exception. - this.__markUpdated(); - throw e; - } - // The update is no longer considered pending and further updates are now allowed. - if (shouldUpdate) { - this._$didUpdate(changedProperties); - } - } - /** - * Invoked before `update()` to compute values needed during the update. - * - * Implement `willUpdate` to compute property values that depend on other - * properties and are used in the rest of the update process. - * - * ```ts - * willUpdate(changedProperties) { - * // only need to check changed properties for an expensive computation. - * if (changedProperties.has('firstName') || changedProperties.has('lastName')) { - * this.sha = computeSHA(`${this.firstName} ${this.lastName}`); - * } - * } - * - * render() { - * return html`SHA: ${this.sha}`; - * } - * ``` - * - * @category updates - */ - willUpdate(_changedProperties) { } - // Note, this is an override point for polyfill-support. - // @internal - _$didUpdate(changedProperties) { - var _a; - (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostUpdated) === null || _a === void 0 ? void 0 : _a.call(c); }); - if (!this.hasUpdated) { - this.hasUpdated = true; - this.firstUpdated(changedProperties); - } - this.updated(changedProperties); - } - __markUpdated() { - this._$changedProperties = new Map(); - this.isUpdatePending = false; - } - /** - * Returns a Promise that resolves when the element has completed updating. - * The Promise value is a boolean that is `true` if the element completed the - * update without triggering another update. The Promise result is `false` if - * a property was set inside `updated()`. If the Promise is rejected, an - * exception was thrown during the update. - * - * To await additional asynchronous work, override the `getUpdateComplete` - * method. For example, it is sometimes useful to await a rendered element - * before fulfilling this Promise. To do this, first await - * `super.getUpdateComplete()`, then any subsequent state. - * - * @return A promise of a boolean that resolves to true if the update completed - * without triggering another update. - * @category updates - */ - get updateComplete() { - return this.getUpdateComplete(); - } - /** - * Override point for the `updateComplete` promise. - * - * It is not safe to override the `updateComplete` getter directly due to a - * limitation in TypeScript which means it is not possible to call a - * superclass getter (e.g. `super.updateComplete.then(...)`) when the target - * language is ES5 (https://github.com/microsoft/TypeScript/issues/338). - * This method should be overridden instead. For example: - * - * ```ts - * class MyElement extends LitElement { - * override async getUpdateComplete() { - * const result = await super.getUpdateComplete(); - * await this._myChild.updateComplete; - * return result; - * } - * } - * ``` - * - * @return A promise of a boolean that resolves to true if the update completed - * without triggering another update. - * @category updates - */ - getUpdateComplete() { - return this.__updatePromise; - } - /** - * Controls whether or not `update()` should be called when the element requests - * an update. By default, this method always returns `true`, but this can be - * customized to control when to update. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - shouldUpdate(_changedProperties) { - return true; - } - /** - * Updates the element. This method reflects property values to attributes. - * It can be overridden to render and keep updated element DOM. - * Setting properties inside this method will *not* trigger - * another update. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - update(_changedProperties) { - if (this.__reflectingProperties !== undefined) { - // Use forEach so this works even if for/of loops are compiled to for - // loops expecting arrays - this.__reflectingProperties.forEach((v, k) => this.__propertyToAttribute(k, this[k], v)); - this.__reflectingProperties = undefined; - } - this.__markUpdated(); - } - /** - * Invoked whenever the element is updated. Implement to perform - * post-updating tasks via DOM APIs, for example, focusing an element. - * - * Setting properties inside this method will trigger the element to update - * again after this update cycle completes. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - updated(_changedProperties) { } - /** - * Invoked when the element is first updated. Implement to perform one time - * work on the element after update. - * - * ```ts - * firstUpdated() { - * this.renderRoot.getElementById('my-text-area').focus(); - * } - * ``` - * - * Setting properties inside this method will trigger the element to update - * again after this update cycle completes. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - firstUpdated(_changedProperties) { } -} -_e = finalized; -/** - * Marks class as having finished creating properties. - */ -ReactiveElement[_e] = true; -/** - * Memoized list of all element properties, including any superclass properties. - * Created lazily on user subclasses when finalizing the class. - * @nocollapse - * @category properties - */ -ReactiveElement.elementProperties = new Map(); -/** - * Memoized list of all element styles. - * Created lazily on user subclasses when finalizing the class. - * @nocollapse - * @category styles - */ -ReactiveElement.elementStyles = []; -/** - * Options used when calling `attachShadow`. Set this property to customize - * the options for the shadowRoot; for example, to create a closed - * shadowRoot: `{mode: 'closed'}`. - * - * Note, these options are used in `createRenderRoot`. If this method - * is customized, options should be respected if possible. - * @nocollapse - * @category rendering - */ -ReactiveElement.shadowRootOptions = { mode: 'open' }; -// Apply polyfills if available -polyfillSupport$2 === null || polyfillSupport$2 === void 0 ? void 0 : polyfillSupport$2({ ReactiveElement }); -// IMPORTANT: do not change the property name or the assignment expression. -// This line will be used in regexes to search for ReactiveElement usage. -((_d$1 = global$1.reactiveElementVersions) !== null && _d$1 !== void 0 ? _d$1 : (global$1.reactiveElementVersions = [])).push('1.4.2'); - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -var _d; -// Use window for browser builds because IE11 doesn't have globalThis. -const global = window; -const __moz_domParser = new DOMParser(); -const wrap$1 = (node) => node; -const trustedTypes = global.trustedTypes; -/** - * Our TrustedTypePolicy for HTML which is declared using the html template - * tag function. - * - * That HTML is a developer-authored constant, and is parsed with innerHTML - * before any untrusted expressions have been mixed in. Therefor it is - * considered safe by construction. - */ -const policy = trustedTypes - ? trustedTypes.createPolicy('lit-html', { - createHTML: (s) => s, - }) - : undefined; -// Added to an attribute name to mark the attribute as bound so we can find -// it easily. -const boundAttributeSuffix = '$lit$'; -// This marker is used in many syntactic positions in HTML, so it must be -// a valid element name and attribute name. We don't support dynamic names (yet) -// but this at least ensures that the parse tree is closer to the template -// intention. -const marker = `lit$${String(Math.random()).slice(9)}$`; -// String used to tell if a comment is a marker comment -const markerMatch = '?' + marker; -// Text used to insert a comment marker node. We use processing instruction -// syntax because it's slightly smaller, but parses as a comment node. -const nodeMarker = `<${markerMatch}>`; -const d = document; -// Creates a dynamic marker. We never have to search for these in the DOM. -const createMarker$1 = (v = '') => d.createComment(v); -const isPrimitive$1 = (value) => value === null || (typeof value != 'object' && typeof value != 'function'); -const isArray = Array.isArray; -const isIterable = (value) => isArray(value) || - // eslint-disable-next-line @typescript-eslint/no-explicit-any - typeof (value === null || value === void 0 ? void 0 : value[Symbol.iterator]) === 'function'; -const SPACE_CHAR = `[ \t\n\f\r]`; -const ATTR_VALUE_CHAR = `[^ \t\n\f\r"'\`<>=]`; -const NAME_CHAR = `[^\\s"'>=/]`; -// These regexes represent the five parsing states that we care about in the -// Template's HTML scanner. They match the *end* of the state they're named -// after. -// Depending on the match, we transition to a new state. If there's no match, -// we stay in the same state. -// Note that the regexes are stateful. We utilize lastIndex and sync it -// across the multiple regexes used. In addition to the five regexes below -// we also dynamically create a regex to find the matching end tags for raw -// text elements. -/** - * End of text is: `<` followed by: - * (comment start) or (tag) or (dynamic tag binding) - */ -const textEndRegex = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g; -const COMMENT_START = 1; -const TAG_NAME = 2; -const DYNAMIC_TAG_NAME = 3; -const commentEndRegex = /-->/g; -/** - * Comments not started with `--my-button-color` - prop = prop - .replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, '-$&') - .toLowerCase(); - return style + `${prop}:${value};`; - }, ''); - } - update(part, [styleInfo]) { - const { style } = part.element; - if (this._previousStyleProperties === undefined) { - this._previousStyleProperties = new Set(); - for (const name in styleInfo) { - this._previousStyleProperties.add(name); - } - return this.render(styleInfo); - } - // Remove old properties that no longer exist in styleInfo - // We use forEach() instead of for-of so that re don't require down-level - // iteration. - this._previousStyleProperties.forEach((name) => { - // If the name isn't in styleInfo or it's null/undefined - if (styleInfo[name] == null) { - this._previousStyleProperties.delete(name); - if (name.includes('-')) { - style.removeProperty(name); - } - else { - // Note reset using empty string (vs null) as IE11 does not always - // reset via null (https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style#setting_styles) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - style[name] = ''; - } - } - }); - // Add or update properties - for (const name in styleInfo) { - const value = styleInfo[name]; - if (value != null) { - this._previousStyleProperties.add(name); - if (name.includes('-')) { - style.setProperty(name, value); - } - else { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - style[name] = value; - } - } - } - return noChange; - } -} -/** - * A directive that applies CSS properties to an element. - * - * `styleMap` can only be used in the `style` attribute and must be the only - * expression in the attribute. It takes the property names in the - * {@link StyleInfo styleInfo} object and adds the property values as CSS - * properties. Property names with dashes (`-`) are assumed to be valid CSS - * property names and set on the element's style object using `setProperty()`. - * Names without dashes are assumed to be camelCased JavaScript property names - * and set on the element's style object using property assignment, allowing the - * style object to translate JavaScript-style names to CSS property names. - * - * For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size': - * '0'})` sets the `background-color`, `border-top` and `--size` properties. - * - * @param styleInfo - * @see {@link https://lit.dev/docs/templates/directives/#stylemap styleMap code samples on Lit.dev} - */ -const styleMap = directive(StyleMapDirective); - -/** - * @license - * Copyright 2020 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -class TemplateContentDirective extends Directive { - constructor(partInfo) { - super(partInfo); - if (partInfo.type !== PartType.CHILD) { - throw new Error('templateContent can only be used in child bindings'); - } - } - render(template) { - if (this._previousTemplate === template) { - return noChange; - } - this._previousTemplate = template; - return document.importNode(template.content, true); - } -} -/** - * Renders the content of a template element as HTML. - * - * Note, the template should be developer controlled and not user controlled. - * Rendering a user-controlled template with this directive - * could lead to cross-site-scripting vulnerabilities. - */ -const templateContent = directive(TemplateContentDirective); - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const HTML_RESULT = 1; -class UnsafeHTMLDirective extends Directive { - constructor(partInfo) { - super(partInfo); - this._value = nothing; - if (partInfo.type !== PartType.CHILD) { - throw new Error(`${this.constructor.directiveName}() can only be used in child bindings`); - } - } - render(value) { - if (value === nothing || value == null) { - this._templateResult = undefined; - return (this._value = value); - } - if (value === noChange) { - return value; - } - if (typeof value != 'string') { - throw new Error(`${this.constructor.directiveName}() called with a non-string value`); - } - if (value === this._value) { - return this._templateResult; - } - this._value = value; - const strings = [value]; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - strings.raw = strings; - // WARNING: impersonating a TemplateResult like this is extremely - // dangerous. Third-party directives should not do this. - return (this._templateResult = { - // Cast to a known set of integers that satisfy ResultType so that we - // don't have to export ResultType and possibly encourage this pattern. - // This property needs to remain unminified. - ['_$litType$']: this.constructor - .resultType, - strings, - values: [], - }); - } -} -UnsafeHTMLDirective.directiveName = 'unsafeHTML'; -UnsafeHTMLDirective.resultType = HTML_RESULT; -/** - * Renders the result as HTML, rather than text. - * - * The values `undefined`, `null`, and `nothing`, will all result in no content - * (empty string) being rendered. - * - * Note, this is unsafe to use with any user-provided input that hasn't been - * sanitized or escaped, as it may lead to cross-site-scripting - * vulnerabilities. - */ -const unsafeHTML = directive(UnsafeHTMLDirective); - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const SVG_RESULT = 2; -class UnsafeSVGDirective extends UnsafeHTMLDirective { -} -UnsafeSVGDirective.directiveName = 'unsafeSVG'; -UnsafeSVGDirective.resultType = SVG_RESULT; -/** - * Renders the result as SVG, rather than text. - * - * The values `undefined`, `null`, and `nothing`, will all result in no content - * (empty string) being rendered. - * - * Note, this is unsafe to use with any user-provided input that hasn't been - * sanitized or escaped, as it may lead to cross-site-scripting - * vulnerabilities. - */ -const unsafeSVG = directive(UnsafeSVGDirective); - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const isPromise = (x) => { - return !isPrimitive(x) && typeof x.then === 'function'; -}; -// Effectively infinity, but a SMI. -const _infinity = 0x3fffffff; -class UntilDirective extends AsyncDirective { - constructor() { - super(...arguments); - this.__lastRenderedIndex = _infinity; - this.__values = []; - this.__weakThis = new PseudoWeakRef(this); - this.__pauser = new Pauser(); - } - render(...args) { - var _a; - return (_a = args.find((x) => !isPromise(x))) !== null && _a !== void 0 ? _a : noChange; - } - update(_part, args) { - const previousValues = this.__values; - let previousLength = previousValues.length; - this.__values = args; - const weakThis = this.__weakThis; - const pauser = this.__pauser; - // If our initial render occurs while disconnected, ensure that the pauser - // and weakThis are in the disconnected state - if (!this.isConnected) { - this.disconnected(); - } - for (let i = 0; i < args.length; i++) { - // If we've rendered a higher-priority value already, stop. - if (i > this.__lastRenderedIndex) { - break; - } - const value = args[i]; - // Render non-Promise values immediately - if (!isPromise(value)) { - this.__lastRenderedIndex = i; - // Since a lower-priority value will never overwrite a higher-priority - // synchronous value, we can stop processing now. - return value; - } - // If this is a Promise we've already handled, skip it. - if (i < previousLength && value === previousValues[i]) { - continue; - } - // We have a Promise that we haven't seen before, so priorities may have - // changed. Forget what we rendered before. - this.__lastRenderedIndex = _infinity; - previousLength = 0; - // Note, the callback avoids closing over `this` so that the directive - // can be gc'ed before the promise resolves; instead `this` is retrieved - // from `weakThis`, which can break the hard reference in the closure when - // the directive disconnects - Promise.resolve(value).then(async (result) => { - // If we're disconnected, wait until we're (maybe) reconnected - // The while loop here handles the case that the connection state - // thrashes, causing the pauser to resume and then get re-paused - while (pauser.get()) { - await pauser.get(); - } - // If the callback gets here and there is no `this`, it means that the - // directive has been disconnected and garbage collected and we don't - // need to do anything else - const _this = weakThis.deref(); - if (_this !== undefined) { - const index = _this.__values.indexOf(value); - // If state.values doesn't contain the value, we've re-rendered without - // the value, so don't render it. Then, only render if the value is - // higher-priority than what's already been rendered. - if (index > -1 && index < _this.__lastRenderedIndex) { - _this.__lastRenderedIndex = index; - _this.setValue(result); - } - } - }); - } - return noChange; - } - disconnected() { - this.__weakThis.disconnect(); - this.__pauser.pause(); - } - reconnected() { - this.__weakThis.reconnect(this); - this.__pauser.resume(); - } -} -/** - * Renders one of a series of values, including Promises, to a Part. - * - * Values are rendered in priority order, with the first argument having the - * highest priority and the last argument having the lowest priority. If a - * value is a Promise, low-priority values will be rendered until it resolves. - * - * The priority of values can be used to create placeholder content for async - * data. For example, a Promise with pending content can be the first, - * highest-priority, argument, and a non_promise loading indicator template can - * be used as the second, lower-priority, argument. The loading indicator will - * render immediately, and the primary content will render when the Promise - * resolves. - * - * Example: - * - * ```js - * const content = fetch('./content.txt').then(r => r.text()); - * html`${until(content, html`Loading...`)}` - * ``` - */ -const until = directive(UntilDirective); -/** - * The type of the class that powers this directive. Necessary for naming the - * directive's return type. - */ -// export type {UntilDirective}; - -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -function when(condition, trueCase, falseCase) { - return condition ? trueCase() : falseCase === null || falseCase === void 0 ? void 0 : falseCase(); -} - -/** - * @license - * Copyright 2020 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/** - * Prevents JSON injection attacks. - * - * The goals of this brand: - * 1) fast to check - * 2) code is small on the wire - * 3) multiple versions of Lit in a single page will all produce mutually - * interoperable StaticValues - * 4) normal JSON.parse (without an unusual reviver) can not produce a - * StaticValue - * - * Symbols satisfy (1), (2), and (4). We use Symbol.for to satisfy (3), but - * we don't care about the key, so we break ties via (2) and use the empty - * string. - */ -const brand = Symbol.for(''); -/** Safely extracts the string part of a StaticValue. */ -const unwrapStaticValue = (value) => { - if ((value === null || value === void 0 ? void 0 : value.r) !== brand) { - return undefined; - } - return value === null || value === void 0 ? void 0 : value['_$litStatic$']; -}; -/** - * Wraps a string so that it behaves like part of the static template - * strings instead of a dynamic value. - * - * Users must take care to ensure that adding the static string to the template - * results in well-formed HTML, or else templates may break unexpectedly. - * - * Note that this function is unsafe to use on untrusted content, as it will be - * directly parsed into HTML. Do not pass user input to this function - * without sanitizing it. - * - * Static values can be changed, but they will cause a complete re-render - * since they effectively create a new template. - */ -const unsafeStatic = (value) => ({ - ['_$litStatic$']: value, - r: brand, -}); -const textFromStatic = (value) => { - if (value['_$litStatic$'] !== undefined) { - return value['_$litStatic$']; - } - else { - throw new Error(`Value passed to 'literal' function must be a 'literal' result: ${value}. Use 'unsafeStatic' to pass non-literal values, but - take care to ensure page security.`); - } -}; -/** - * Tags a string literal so that it behaves like part of the static template - * strings instead of a dynamic value. - * - * The only values that may be used in template expressions are other tagged - * `literal` results or `unsafeStatic` values (note that untrusted content - * should never be passed to `unsafeStatic`). - * - * Users must take care to ensure that adding the static string to the template - * results in well-formed HTML, or else templates may break unexpectedly. - * - * Static values can be changed, but they will cause a complete re-render since - * they effectively create a new template. - */ -const literal = (strings, ...values) => ({ - ['_$litStatic$']: values.reduce((acc, v, idx) => acc + textFromStatic(v) + strings[idx + 1], strings[0]), - r: brand, -}); -const stringsCache = new Map(); -/** - * Wraps a lit-html template tag (`html` or `svg`) to add static value support. - */ -const withStatic = (coreTag) => (strings, ...values) => { - const l = values.length; - let staticValue; - let dynamicValue; - const staticStrings = []; - const dynamicValues = []; - let i = 0; - let hasStatics = false; - let s; - while (i < l) { - s = strings[i]; - // Collect any unsafeStatic values, and their following template strings - // so that we treat a run of template strings and unsafe static values as - // a single template string. - while (i < l && - ((dynamicValue = values[i]), - (staticValue = unwrapStaticValue(dynamicValue))) !== undefined) { - s += staticValue + strings[++i]; - hasStatics = true; - } - dynamicValues.push(dynamicValue); - staticStrings.push(s); - i++; - } - // If the last value isn't static (which would have consumed the last - // string), then we need to add the last string. - if (i === l) { - staticStrings.push(strings[l]); - } - if (hasStatics) { - const key = staticStrings.join('$$lit$$'); - strings = stringsCache.get(key); - if (strings === undefined) { - // Beware: in general this pattern is unsafe, and doing so may bypass - // lit's security checks and allow an attacker to execute arbitrary - // code and inject arbitrary content. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - staticStrings.raw = staticStrings; - stringsCache.set(key, (strings = staticStrings)); - } - values = dynamicValues; - } - return coreTag(strings, ...values); -}; -/** - * Interprets a template literal as an HTML template that can efficiently - * render to and update a container. - * - * Includes static value support from `lit-html/static.js`. - */ -const html = withStatic(html$1); -/** - * Interprets a template literal as an SVG template that can efficiently - * render to and update a container. - * - * Includes static value support from `lit-html/static.js`. - */ -const svg = withStatic(svg$1); - -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -if (!window.litDisableBundleWarning) { - console.warn('Lit has been loaded from a bundle that combines all core features into ' + - 'a single file. To reduce transfer size and parsing cost, consider ' + - 'using the `lit` npm package directly in your project.'); -} - -export { AsyncDirective, AsyncReplaceDirective, CSSResult, Directive, LitElement, PartType, ReactiveElement, TemplateResultType, UnsafeHTMLDirective, UntilDirective, UpdatingElement, _$LE, _$LH, adoptStyles, asyncAppend, asyncReplace, cache, choose, classMap, clearPart, createRef, css, defaultConverter, directive, getCommittedValue, getCompatibleStyle, getDirectiveClass, guard, html$1 as html, ifDefined, insertPart, isDirectiveResult, isPrimitive, isServer, isSingleExpression, isTemplateResult, join, keyed, literal, live, map, noChange, notEqual, nothing, range, ref, removePart, render, repeat, setChildPartValue, setCommittedValue, html as staticHtml, svg as staticSvg, styleMap, supportsAdoptingStyleSheets, svg$1 as svg, templateContent, unsafeCSS, unsafeHTML, unsafeSVG, unsafeStatic, until, when, withStatic }; -//# sourceMappingURL=lit-all.min.js.map