From bd802127cb5e74be4788c0feed879f8588259ab6 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 17 Oct 2023 18:37:43 +0200 Subject: [PATCH 1/6] Add polyfill bundle --- package-lock.json | 37 ++++++++++++++++++++++++++++++++----- package.json | 6 +++++- rollup.config.mjs | 12 ++++++++++++ src/polyfills.ts | 3 +++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 src/polyfills.ts diff --git a/package-lock.json b/package-lock.json index 599c3c5c..33e490c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,10 @@ "name": "@theoplayer/web-ui", "version": "1.4.0", "license": "MIT", + "dependencies": { + "@webcomponents/webcomponentsjs": "^2.8.0", + "lit-html": "^3.0.0" + }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.1", "@rollup/pluginutils": "^5.0.4", @@ -16,7 +20,6 @@ "@swc/helpers": "^0.5.2", "@types/html-minifier": "^4.0.3", "@webcomponents/shadycss": "^1.11.2", - "@webcomponents/webcomponentsjs": "^2.8.0", "html-minifier": "^4.0.0", "postcss": "^8.4.30", "postcss-mixins": "^9.0.4", @@ -1291,6 +1294,11 @@ "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz", + "integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==" + }, "node_modules/@types/uglify-js": { "version": "3.17.2", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.2.tgz", @@ -1318,8 +1326,7 @@ "node_modules/@webcomponents/webcomponentsjs": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.8.0.tgz", - "integrity": "sha512-loGD63sacRzOzSJgQnB9ZAhaQGkN7wl2Zuw7tsphI5Isa0irijrRo6EnJii/GgjGefIFO8AIO7UivzRhFaEk9w==", - "dev": true + "integrity": "sha512-loGD63sacRzOzSJgQnB9ZAhaQGkN7wl2Zuw7tsphI5Isa0irijrRo6EnJii/GgjGefIFO8AIO7UivzRhFaEk9w==" }, "node_modules/ansi-sequence-parser": { "version": "1.1.1", @@ -2772,6 +2779,14 @@ "node": ">=10" } }, + "node_modules/lit-html": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.0.0.tgz", + "integrity": "sha512-DNJIE8dNY0dQF2Gs0sdMNUppMQT2/CvV4OVnSdg7BXAsGqkVwsE5bqQ04POfkYH5dBIuGnJYdFz5fYYyNnOxiA==", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, "node_modules/loader-utils": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", @@ -5939,6 +5954,11 @@ "@types/node": "*" } }, + "@types/trusted-types": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz", + "integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==" + }, "@types/uglify-js": { "version": "3.17.2", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.2.tgz", @@ -5965,8 +5985,7 @@ "@webcomponents/webcomponentsjs": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.8.0.tgz", - "integrity": "sha512-loGD63sacRzOzSJgQnB9ZAhaQGkN7wl2Zuw7tsphI5Isa0irijrRo6EnJii/GgjGefIFO8AIO7UivzRhFaEk9w==", - "dev": true + "integrity": "sha512-loGD63sacRzOzSJgQnB9ZAhaQGkN7wl2Zuw7tsphI5Isa0irijrRo6EnJii/GgjGefIFO8AIO7UivzRhFaEk9w==" }, "ansi-sequence-parser": { "version": "1.1.1", @@ -6982,6 +7001,14 @@ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true }, + "lit-html": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.0.0.tgz", + "integrity": "sha512-DNJIE8dNY0dQF2Gs0sdMNUppMQT2/CvV4OVnSdg7BXAsGqkVwsE5bqQ04POfkYH5dBIuGnJYdFz5fYYyNnOxiA==", + "requires": { + "@types/trusted-types": "^2.0.2" + } + }, "loader-utils": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", diff --git a/package.json b/package.json index 20908d46..e41fac20 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "import": "./dist/THEOplayerUI.es5.mjs", "default": "./dist/THEOplayerUI.es5.js" }, + "./polyfills": "./dist/THEOplayerUI-polyfills.js", "./dist/*": "./dist/*" }, "files": [ @@ -46,6 +47,10 @@ "type": "git", "url": "git+https://github.com/THEOplayer/web-ui.git" }, + "dependencies": { + "@webcomponents/webcomponentsjs": "^2.8.0", + "lit-html": "^3.0.0" + }, "peerDependencies": { "theoplayer": "^6" }, @@ -57,7 +62,6 @@ "@swc/helpers": "^0.5.2", "@types/html-minifier": "^4.0.3", "@webcomponents/shadycss": "^1.11.2", - "@webcomponents/webcomponentsjs": "^2.8.0", "html-minifier": "^4.0.0", "postcss": "^8.4.30", "postcss-mixins": "^9.0.4", diff --git a/rollup.config.mjs b/rollup.config.mjs index 3b68d5b4..16e9e944 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -32,6 +32,18 @@ export default (cliArgs) => { return defineConfig([ ...jsConfig(outputDir, { es5: false, production, sourcemap: true }), ...jsConfig(outputDir, { es5: true, production, sourcemap: false }), + { + input: './src/polyfills.ts', + output: { + file: path.join(outputDir, `${fileName}.polyfills.js`), + format: 'iife', + sourcemap: false, + indent: false, + banner + }, + context: 'self', + plugins: jsPlugins({ es5: true, module: false, production: true, sourcemap: false }) + }, { input: './src/index.ts', output: { diff --git a/src/polyfills.ts b/src/polyfills.ts new file mode 100644 index 00000000..5f5b4c4c --- /dev/null +++ b/src/polyfills.ts @@ -0,0 +1,3 @@ +import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js'; +import '@webcomponents/webcomponentsjs/webcomponents-bundle.js'; +import 'lit-html/polyfill-support.js'; From 7c3081c39895aa50d93e487770d706b23ccadce9 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 17 Oct 2023 18:45:36 +0200 Subject: [PATCH 2/6] Use our own polyfill bundle in examples --- README.md | 15 ++++++++------- docs/_layouts/example.html | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 19f97750..2b1dc2db 100644 --- a/README.md +++ b/README.md @@ -129,9 +129,12 @@ See [docs/examples/custom-ui.html](https://github.com/THEOplayer/web-ui/blob/mai By default, THEOplayer Web UI targets modern browsers that support modern JavaScript syntax (such as [async/await](https://caniuse.com/async-functions)) and native [Custom Elements](https://caniuse.com/custom-elementsv1). This keeps the download size small, so your viewers can spend less time waiting for your page to load and start watching their video faster. -On older browsers (such as Internet Explorer 11 and older smart TVs), you need to load a different version of the THEOplayer Web UI that uses older JavaScript syntax. You also need to load additional polyfills for missing features such as Promises or Custom Elements. We recommend [Polyfill.io](https://polyfill.io/) and [Web Components Polyfills](https://github.com/webcomponents/polyfills) for these. +On older browsers (such as Internet Explorer 11 and older smart TVs), you need to load a different version of the THEOplayer Web UI that uses older JavaScript syntax. You also need to load additional polyfills for missing features such as Promises or Custom Elements: -- Option 1: in your HTML. This uses [differential serving](https://css-tricks.com/differential-serving/) so modern browsers will load the modern build (with `type="module"`), while legacy browsers will load the legacy build (with `nomodule`). +- For Promises, we recommend [Polyfill.io](https://polyfill.io/). +- For Custom Elements, we recommend loading our polyfill bundle from `@theoplayer/web-ui/polyfills`. Alternatively, you can load the [Web Components Polyfills](https://github.com/webcomponents/polyfills). + +* Option 1: in your HTML. This uses [differential serving](https://css-tricks.com/differential-serving/) so modern browsers will load the modern build (with `type="module"`), while legacy browsers will load the legacy build (with `nomodule`). ```html @@ -147,16 +150,14 @@ On older browsers (such as Internet Explorer 11 and older smart TVs), you need t - - + ``` -- Option 2: in your JavaScript. This will load the legacy build on both modern and legacy browsers, which is suboptimal. Instead, we recommend configuring your bundler to produce a modern and legacy build of your entire web app, and to import the appropriate version of THEOplayer Web UI for each build flavor. +* Option 2: in your JavaScript. This will load the legacy build on both modern and legacy browsers, which is suboptimal. Instead, we recommend configuring your bundler to produce a modern and legacy build of your entire web app, and to import the appropriate version of THEOplayer Web UI for each build flavor. ```js - import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js'; - import '@webcomponents/webcomponentsjs/webcomponents-bundle.js'; + import '@theoplayer/web-ui/polyfills'; import { DefaultUI } from '@theoplayer/web-ui/es5'; // note the "/es5" suffix ``` diff --git a/docs/_layouts/example.html b/docs/_layouts/example.html index 5f86e6c6..1ff9dd74 100644 --- a/docs/_layouts/example.html +++ b/docs/_layouts/example.html @@ -25,9 +25,8 @@ - - + {{ content }} From b60e45bbdf3ddd6e93f50b7a601a3402ad9aebbc Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 17 Oct 2023 18:55:33 +0200 Subject: [PATCH 3/6] Tweak --- rollup.config.mjs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index 16e9e944..1539c69b 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -161,18 +161,16 @@ function jsPlugins({ es5 = false, module = false, production = false, sourcemap externalHelpers: true } }), - ...(production - ? [ - minify({ - sourceMap: sourcemap, - mangle: { - toplevel: true - }, - toplevel: true, - module, - ecma: es5 ? 5 : 2017 - }) - ] - : []) - ]; + production + ? minify({ + sourceMap: sourcemap, + mangle: { + toplevel: true + }, + toplevel: true, + module, + ecma: es5 ? 5 : 2017 + }) + : undefined + ].filter((plugin) => plugin !== undefined); } From ce9e8af9fa4ea4146adaaec323bf5740e69a5b4b Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 17 Oct 2023 18:56:02 +0200 Subject: [PATCH 4/6] Replace `globalThis` in lit-html --- package-lock.json | 32 ++++++++++++++++++++++++++++++++ package.json | 1 + rollup.config.mjs | 11 +++++++++++ 3 files changed, 44 insertions(+) diff --git a/package-lock.json b/package-lock.json index 33e490c3..34991021 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.1", + "@rollup/plugin-replace": "^5.0.4", "@rollup/pluginutils": "^5.0.4", "@swc/cli": "^0.1.62", "@swc/core": "^1.3.89", @@ -893,6 +894,27 @@ } } }, + "node_modules/@rollup/plugin-replace": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.4.tgz", + "integrity": "sha512-E2hmRnlh09K8HGT0rOnnri9OTh+BILGr7NVJGB30S4E3cLRn3J0xjdiyOZ74adPs4NiAMgrjUMGAZNJDBgsdmQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/pluginutils": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz", @@ -5702,6 +5724,16 @@ "resolve": "^1.22.1" } }, + "@rollup/plugin-replace": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.4.tgz", + "integrity": "sha512-E2hmRnlh09K8HGT0rOnnri9OTh+BILGr7NVJGB30S4E3cLRn3J0xjdiyOZ74adPs4NiAMgrjUMGAZNJDBgsdmQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.30.3" + } + }, "@rollup/pluginutils": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz", diff --git a/package.json b/package.json index e41fac20..5870b25d 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.1", + "@rollup/plugin-replace": "^5.0.4", "@rollup/pluginutils": "^5.0.4", "@swc/cli": "^0.1.62", "@swc/core": "^1.3.89", diff --git a/rollup.config.mjs b/rollup.config.mjs index 1539c69b..ce96ddc6 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -8,6 +8,7 @@ import postcssMixins from 'postcss-mixins'; import * as path from 'node:path'; import { readFile } from 'node:fs/promises'; import { string } from 'rollup-plugin-string'; +import replace from '@rollup/plugin-replace'; import dts from 'rollup-plugin-dts'; const fileName = 'THEOplayerUI'; @@ -129,6 +130,16 @@ function jsPlugins({ es5 = false, module = false, production = false, sourcemap string({ include: ['./src/**/*.html', './src/**/*.svg'] }), + // Replace `globalThis` in lit-html. + es5 + ? replace({ + preventAssignment: true, + delimiters: ['\\b', '\\b'], + values: { + globalThis: 'self' + } + }) + : undefined, // Transpile TypeScript. swc({ include: './src/**', From 64eb25d0d7c627af8866c2c11b122bc5bd9b9568 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 17 Oct 2023 19:28:18 +0200 Subject: [PATCH 5/6] Remove need for ES2015 polyfill --- README.md | 10 +++------- docs/_layouts/example.html | 1 - 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2b1dc2db..07fe1567 100644 --- a/README.md +++ b/README.md @@ -129,12 +129,9 @@ See [docs/examples/custom-ui.html](https://github.com/THEOplayer/web-ui/blob/mai By default, THEOplayer Web UI targets modern browsers that support modern JavaScript syntax (such as [async/await](https://caniuse.com/async-functions)) and native [Custom Elements](https://caniuse.com/custom-elementsv1). This keeps the download size small, so your viewers can spend less time waiting for your page to load and start watching their video faster. -On older browsers (such as Internet Explorer 11 and older smart TVs), you need to load a different version of the THEOplayer Web UI that uses older JavaScript syntax. You also need to load additional polyfills for missing features such as Promises or Custom Elements: +On older browsers (such as Internet Explorer 11 and older smart TVs), you need to load a different version of the THEOplayer Web UI that uses older JavaScript syntax. You also need to load additional polyfills for missing features such as Promises or Custom Elements. These are provided by our polyfill bundle in `@theoplayer/web-ui/polyfills`. Alternatively, you can use [Polyfill.io](https://polyfill.io/) and [Web Components Polyfills](https://github.com/webcomponents/polyfills). -- For Promises, we recommend [Polyfill.io](https://polyfill.io/). -- For Custom Elements, we recommend loading our polyfill bundle from `@theoplayer/web-ui/polyfills`. Alternatively, you can load the [Web Components Polyfills](https://github.com/webcomponents/polyfills). - -* Option 1: in your HTML. This uses [differential serving](https://css-tricks.com/differential-serving/) so modern browsers will load the modern build (with `type="module"`), while legacy browsers will load the legacy build (with `nomodule`). +- Option 1: in your HTML. This uses [differential serving](https://css-tricks.com/differential-serving/) so modern browsers will load the modern build (with `type="module"`), while legacy browsers will load the legacy build (with `nomodule`). ```html @@ -149,13 +146,12 @@ On older browsers (such as Internet Explorer 11 and older smart TVs), you need t - ``` -* Option 2: in your JavaScript. This will load the legacy build on both modern and legacy browsers, which is suboptimal. Instead, we recommend configuring your bundler to produce a modern and legacy build of your entire web app, and to import the appropriate version of THEOplayer Web UI for each build flavor. +- Option 2: in your JavaScript. This will load the legacy build on both modern and legacy browsers, which is suboptimal. Instead, we recommend configuring your bundler to produce a modern and legacy build of your entire web app, and to import the appropriate version of THEOplayer Web UI for each build flavor. ```js import '@theoplayer/web-ui/polyfills'; diff --git a/docs/_layouts/example.html b/docs/_layouts/example.html index 1ff9dd74..e96598f0 100644 --- a/docs/_layouts/example.html +++ b/docs/_layouts/example.html @@ -24,7 +24,6 @@ - From bab359a6caeb459713f2084788bfe6be651500b0 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 17 Oct 2023 19:30:40 +0200 Subject: [PATCH 6/6] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42781ea1..3dd5243a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Added support for navigating the UI using a TV remote control. - Added a `tv-focus` attribute to specify which UI element should receive the initial focus when showing the controls on a TV. In the default UI, initial focus is on the seek bar. +- 🚀 Added a polyfill bundle in `@theoplayer/web-ui/polyfills`. This contains all the polyfills needed to use THEOplayer Web UI in legacy browsers, such as ES2015 `Promise` and Custom Elements. ([#41](https://github.com/THEOplayer/web-ui/pull/41)) ## v1.4.0 (2023-10-04)