From 2bd4fd368e801bb3fc251443d4a1cf6694a36ffe Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Thu, 14 Jan 2021 15:21:33 +0200 Subject: [PATCH 01/19] feat: create @ui5/webcomponents-compatibility package --- package.json | 11 +++-- packages/base/bundle.es5.js | 28 ------------ packages/base/bundle.esm.js | 3 +- packages/base/package-scripts.js | 7 ++- packages/base/package.json | 5 +-- packages/base/src/UI5Element.js | 8 ++-- packages/base/src/boot.js | 6 ++- .../base/src/features/browsersupport/IE11.js | 43 ------------------- packages/base/src/theming/applyTheme.js | 6 +-- packages/base/test/pages/AllTestElements.html | 3 -- packages/base/test/pages/Configuration.html | 2 - .../base/test/pages/ConfigurationScript.html | 2 - packages/compatibility/.eslintignore | 4 ++ packages/compatibility/.npmrc | 2 + packages/compatibility/README.md | 25 +++++++++++ packages/compatibility/config/.eslintrc.js | 3 ++ packages/compatibility/package-scripts.js | 14 ++++++ packages/compatibility/package.json | 37 ++++++++++++++++ .../src/LegacyBrowsersSupport.js | 19 ++++++++ .../src/features}/Edge.js | 4 +- packages/compatibility/src/features/IE11.js | 43 +++++++++++++++++++ .../IE11WithWebComponentsPolyfill.js | 2 +- .../src}/patchNodeValue.js | 0 .../src/theming/CSSVarsPonyfill.js | 0 .../src/theming/adaptCSSForIE.js | 0 .../src/theming/createComponentStyleTag.js | 6 +-- .../src/thirdparty/Array.from.js | 0 .../src/thirdparty/Array.prototype.fill.js | 0 .../src/thirdparty/Array.prototype.find.js | 0 .../thirdparty/Array.prototype.findIndex.js | 0 .../thirdparty/Array.prototype.includes.js | 0 .../thirdparty/Element.prototype.closest.js | 0 .../thirdparty/Element.prototype.matches.js | 0 .../src/thirdparty/Map.prototype.keys.js | 0 .../src/thirdparty/Number.isInteger.js | 0 .../src/thirdparty/Number.isNaN.js | 0 .../src/thirdparty/Number.parseFloat.js | 0 .../src/thirdparty/Number.parseInt.js | 0 .../src/thirdparty/Object.assign.js | 0 .../src/thirdparty/Object.entries.js | 0 .../src/thirdparty/Symbol.js | 0 .../src/thirdparty/WeakSet.js | 0 .../src/thirdparty/es6-string-methods.js | 0 .../src/thirdparty/events-polyfills.js | 0 .../src/thirdparty/fetch.js | 0 .../src/thirdparty/template.js | 0 .../src/thirdparty/webcomponents-sd-ce-pf.js | 0 .../src}/whenPolyfillLoaded.js | 0 packages/fiori/bundle.es5.js | 2 +- packages/fiori/package.json | 1 + packages/main/bundle.es5.js | 2 +- packages/main/bundle.esm.js | 3 -- packages/main/package.json | 1 + packages/tools/components-package/rollup.js | 4 +- 54 files changed, 184 insertions(+), 112 deletions(-) delete mode 100644 packages/base/bundle.es5.js delete mode 100644 packages/base/src/features/browsersupport/IE11.js create mode 100644 packages/compatibility/.eslintignore create mode 100644 packages/compatibility/.npmrc create mode 100644 packages/compatibility/README.md create mode 100644 packages/compatibility/config/.eslintrc.js create mode 100644 packages/compatibility/package-scripts.js create mode 100644 packages/compatibility/package.json create mode 100644 packages/compatibility/src/LegacyBrowsersSupport.js rename packages/{base/src/features/browsersupport => compatibility/src/features}/Edge.js (62%) create mode 100644 packages/compatibility/src/features/IE11.js rename packages/{base/src/features/browsersupport => compatibility/src/features}/IE11WithWebComponentsPolyfill.js (76%) rename packages/{base/src/compatibility => compatibility/src}/patchNodeValue.js (100%) rename packages/{base => compatibility}/src/theming/CSSVarsPonyfill.js (100%) rename packages/{base => compatibility}/src/theming/adaptCSSForIE.js (100%) rename packages/{base => compatibility}/src/theming/createComponentStyleTag.js (82%) rename packages/{base => compatibility}/src/thirdparty/Array.from.js (100%) rename packages/{base => compatibility}/src/thirdparty/Array.prototype.fill.js (100%) rename packages/{base => compatibility}/src/thirdparty/Array.prototype.find.js (100%) rename packages/{base => compatibility}/src/thirdparty/Array.prototype.findIndex.js (100%) rename packages/{base => compatibility}/src/thirdparty/Array.prototype.includes.js (100%) rename packages/{base => compatibility}/src/thirdparty/Element.prototype.closest.js (100%) rename packages/{base => compatibility}/src/thirdparty/Element.prototype.matches.js (100%) rename packages/{base => compatibility}/src/thirdparty/Map.prototype.keys.js (100%) rename packages/{base => compatibility}/src/thirdparty/Number.isInteger.js (100%) rename packages/{base => compatibility}/src/thirdparty/Number.isNaN.js (100%) rename packages/{base => compatibility}/src/thirdparty/Number.parseFloat.js (100%) rename packages/{base => compatibility}/src/thirdparty/Number.parseInt.js (100%) rename packages/{base => compatibility}/src/thirdparty/Object.assign.js (100%) rename packages/{base => compatibility}/src/thirdparty/Object.entries.js (100%) rename packages/{base => compatibility}/src/thirdparty/Symbol.js (100%) rename packages/{base => compatibility}/src/thirdparty/WeakSet.js (100%) rename packages/{base => compatibility}/src/thirdparty/es6-string-methods.js (100%) rename packages/{base => compatibility}/src/thirdparty/events-polyfills.js (100%) rename packages/{base => compatibility}/src/thirdparty/fetch.js (100%) rename packages/{base => compatibility}/src/thirdparty/template.js (100%) rename packages/{base => compatibility}/src/thirdparty/webcomponents-sd-ce-pf.js (100%) rename packages/{base/src/compatibility => compatibility/src}/whenPolyfillLoaded.js (100%) diff --git a/package.json b/package.json index 2236b0c76186..23686a440692 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,10 @@ "ui5" ], "scripts": { - "build": "npm-run-all --sequential build:base build:localization build:theme-base build:icons build:icons-tnt build:main build:fiori", + "build": "npm-run-all --sequential build:base build:compatibility build:localization build:theme-base build:icons build:icons-tnt build:main build:fiori", "build:localization": "cd packages/localization && yarn build", "build:base": "cd packages/base && yarn build", + "build:compatibility": "cd packages/compatibility && yarn build", "build:theme-base": "cd packages/theme-base && yarn build", "build:icons": "cd packages/icons && yarn build", "build:icons-tnt": "cd packages/icons-tnt && yarn build", @@ -19,9 +20,10 @@ "build:fiori": "cd packages/fiori && yarn build", "build:playground": "yarn build:main && yarn build:fiori && cd packages/playground && yarn build", "build:playground:master": "yarn build:main && yarn build:fiori && cd packages/playground && yarn build:master", - "clean": "npm-run-all --sequential clean:base clean:localization clean:theme-base clean:icons clean:icons-tnt clean:main clean:fiori", + "clean": "npm-run-all --sequential clean:base clean:compatibility clean:localization clean:theme-base clean:icons clean:icons-tnt clean:main clean:fiori", "clean:localization": "cd packages/localization && yarn clean", "clean:base": "cd packages/base && yarn clean", + "clean:compatibility": "cd packages/compatibility && yarn clean", "clean:theme-base": "cd packages/theme-base && yarn clean", "clean:icons": "cd packages/icons && yarn clean", "clean:icons-tnt": "cd packages/icons-tnt && yarn clean", @@ -37,8 +39,8 @@ "dev:fiori": "cd packages/fiori && nps dev", "scopeDev:main": "cd packages/main && nps scope.dev", "scopeDev:fiori": "cd packages/fiori && nps scope.dev", - "start": "npm-run-all --sequential build:base build:localization build:theme-base build:icons build:icons-tnt prepare:main prepare:fiori start:all", - "startWithScope": "npm-run-all --sequential build:base build:localization build:theme-base build:icons build:icons-tnt scopePrepare:main scopePrepare:fiori scopeStart:all", + "start": "npm-run-all --sequential build:base build:compatibility build:localization build:theme-base build:icons build:icons-tnt prepare:main prepare:fiori start:all", + "startWithScope": "npm-run-all --sequential build:base build:compatibility build:localization build:theme-base build:icons build:icons-tnt scopePrepare:main scopePrepare:fiori scopeStart:all", "start:all": "npm-run-all --parallel dev:base dev:localization dev:main dev:fiori", "scopeStart:all": "npm-run-all --parallel dev:base dev:localization scopeDev:main scopeDev:fiori", "start:base": "cd packages/base && yarn start", @@ -71,6 +73,7 @@ "packages/fiori", "packages/icons", "packages/icons-tnt", + "packages/compatibility", "packages/tools", "packages/playground" ] diff --git a/packages/base/bundle.es5.js b/packages/base/bundle.es5.js deleted file mode 100644 index 2ca0fe163c10..000000000000 --- a/packages/base/bundle.es5.js +++ /dev/null @@ -1,28 +0,0 @@ -// ES5 bundle targets IE11 only -import "./dist/features/browsersupport/IE11.js"; - -import "./bundle.esm.js"; - -import { getAnimationMode } from "./dist/config/AnimationMode.js"; -import { getLanguage } from "./dist/config/Language.js"; -import { getCalendarType } from "./dist/config/CalendarType.js"; -import { getTheme, setTheme } from "./dist/config/Theme.js"; -import { getNoConflict, setNoConflict } from "./dist/config/NoConflict.js"; -import { getRTL } from "./dist/config/RTL.js"; -import { getFirstDayOfWeek } from "./dist/config/FormatSettings.js"; -import { getRegisteredNames as getIconNames } from "./dist/SVGIconRegistry.js" -const configuration = { - getAnimationMode, - getLanguage, - getTheme, - setTheme, - getNoConflict, - setNoConflict, - getCalendarType, - getRTL, - getFirstDayOfWeek, -}; -export { - configuration, - getIconNames, -}; diff --git a/packages/base/bundle.esm.js b/packages/base/bundle.esm.js index 79e1051fdb9f..9ca625ded77f 100644 --- a/packages/base/bundle.esm.js +++ b/packages/base/bundle.esm.js @@ -1,7 +1,6 @@ import { registerThemeProperties } from "./dist/AssetRegistry.js"; -// ESM bundle targets Edge + browsers with native support -import "./dist/features/browsersupport/Edge.js"; +// ESM bundle targets browsers with native support import "./dist/features/OpenUI5Support.js"; // Test components diff --git a/packages/base/package-scripts.js b/packages/base/package-scripts.js index af84f33e21a9..0e55eb561ddc 100644 --- a/packages/base/package-scripts.js +++ b/packages/base/package-scripts.js @@ -12,20 +12,19 @@ const scripts = { prepare: "nps clean copy generateAssetParameters", build: { default: "nps lint prepare build.bundle", - bundle: "rollup --config config/rollup.config.js --environment ES5_BUILD", + bundle: "rollup --config config/rollup.config.js --environment", }, copy: { - default: "nps copy.src copy.test copy.webcomponents-polyfill", + default: "nps copy.src copy.test", src: "copy-and-watch \"src/**/*.js\" dist/", test: "copy-and-watch \"test/**/*.*\" dist/test-resources", - "webcomponents-polyfill": "copy-and-watch \"../../node_modules/@webcomponents/webcomponentsjs/**/*.*\" dist/webcomponentsjs/", }, generateAssetParameters: `node "${assetParametersScript}"`, watch: { default: 'concurrently "nps watch.test" "nps watch.src" "nps watch.bundle"', src: 'nps "copy.src --watch --skip-initial-copy"', test: 'nps "copy.test --watch --skip-initial-copy"', - bundle: "rollup --config config/rollup.config.js -w --environment ES5_BUILD,DEV", + bundle: "rollup --config config/rollup.config.js -w --environment DEV", }, dev: 'concurrently "nps serve" "nps watch"', start: "nps prepare dev", diff --git a/packages/base/package.json b/packages/base/package.json index 52ee231a3bdf..8fd932d03310 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -24,10 +24,7 @@ "prepublishOnly": "npm run clean && npm run build" }, "dependencies": { - "css-vars-ponyfill": "^2.1.2", - "lit-html": "^1.0.0", - "regenerator-runtime": "0.12.1", - "url-search-params-polyfill": "^5.0.0" + "lit-html": "^1.0.0" }, "devDependencies": { "@ui5/webcomponents-tools": "1.0.0-rc.11", diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index 0f0a848e8faa..112d6a5294f5 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -10,7 +10,6 @@ import DOMObserver from "./compatibility/DOMObserver.js"; import { skipOriginalEvent } from "./config/NoConflict.js"; import { getRTL } from "./config/RTL.js"; import getConstructableStyle from "./theming/getConstructableStyle.js"; -import createComponentStyleTag from "./theming/createComponentStyleTag.js"; import getEffectiveStyle from "./theming/getEffectiveStyle.js"; import Integer from "./types/Integer.js"; import Float from "./types/Float.js"; @@ -19,6 +18,9 @@ import isValidPropertyName from "./util/isValidPropertyName.js"; import isSlot from "./util/isSlot.js"; import arraysAreEqual from "./util/arraysAreEqual.js"; import { markAsRtlAware } from "./locale/RTLAwareRegistry.js"; +import { getFeature } from "./FeaturesRegistry.js"; + +const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); let autoId = 0; @@ -628,8 +630,8 @@ class UI5Element extends HTMLElement { const renderResult = executeTemplate(this.constructor.template, this); // IE11, Edge - if (window.ShadyDOM) { - createComponentStyleTag(this.constructor); + if (window.ShadyDOM && LegacyBrowsersSupport) { + LegacyBrowsersSupport.createComponentStyleTag(this.constructor); } // Chrome diff --git a/packages/base/src/boot.js b/packages/base/src/boot.js index 72a9c3aefb6e..d9adc04671f5 100644 --- a/packages/base/src/boot.js +++ b/packages/base/src/boot.js @@ -3,7 +3,6 @@ import insertFontFace from "./FontFace.js"; import insertSystemCSSVars from "./SystemCSSVars.js"; import { getTheme } from "./config/Theme.js"; import applyTheme from "./theming/applyTheme.js"; -import whenPolyfillLoaded from "./compatibility/whenPolyfillLoaded.js"; import { getFeature } from "./FeaturesRegistry.js"; let bootPromise; @@ -15,6 +14,7 @@ const boot = () => { bootPromise = new Promise(async resolve => { const OpenUI5Support = getFeature("OpenUI5Support"); + const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); if (OpenUI5Support) { await OpenUI5Support.init(); } @@ -24,7 +24,9 @@ const boot = () => { OpenUI5Support && OpenUI5Support.attachListeners(); insertFontFace(); insertSystemCSSVars(); - await whenPolyfillLoaded(); + if (LegacyBrowsersSupport) { + await LegacyBrowsersSupport.whenPolyfillLoaded(); + } resolve(); }); diff --git a/packages/base/src/features/browsersupport/IE11.js b/packages/base/src/features/browsersupport/IE11.js deleted file mode 100644 index 96c67c3d18ae..000000000000 --- a/packages/base/src/features/browsersupport/IE11.js +++ /dev/null @@ -1,43 +0,0 @@ -// CSS Custom Properties -import cssVars from "css-vars-ponyfill/dist/css-vars-ponyfill.esm.js"; - -// String -import "../../thirdparty/es6-string-methods.js"; - -// Object -import "../../thirdparty/Object.entries.js"; - -// Array -import "../../thirdparty/Array.prototype.fill.js"; -import "../../thirdparty/Array.prototype.find.js"; -import "../../thirdparty/Array.prototype.findIndex.js"; -import "../../thirdparty/Array.prototype.includes.js"; - -// Map -import "../../thirdparty/Map.prototype.keys.js"; - -// Number -import "../../thirdparty/Number.isInteger.js"; -import "../../thirdparty/Number.isNaN.js"; -import "../../thirdparty/Number.parseFloat.js"; -import "../../thirdparty/Number.parseInt.js"; - -// Element -import "../../thirdparty/Element.prototype.matches.js"; -import "../../thirdparty/Element.prototype.closest.js"; - -// WeakSet -import "../../thirdparty/WeakSet.js"; - -// fetch -import "../../thirdparty/fetch.js"; - -// async - await -import "regenerator-runtime/runtime.js"; - -// Plus all polyfills needed for Edge are also needed for IE11 -import "./Edge.js"; - -window.CSSVarsPonyfill = { - cssVars, -}; diff --git a/packages/base/src/theming/applyTheme.js b/packages/base/src/theming/applyTheme.js index d8f4bf3015f1..9c88ab745de5 100644 --- a/packages/base/src/theming/applyTheme.js +++ b/packages/base/src/theming/applyTheme.js @@ -1,7 +1,6 @@ import { getThemeProperties, getRegisteredPackages, isThemeRegistered } from "../asset-registries/Themes.js"; import createThemePropertiesStyleTag from "./createThemePropertiesStyleTag.js"; import getThemeDesignerTheme from "./getThemeDesignerTheme.js"; -import { ponyfillNeeded, runPonyfill } from "./CSSVarsPonyfill.js"; import { fireThemeLoaded } from "./ThemeLoaded.js"; import { getFeature } from "../FeaturesRegistry.js"; @@ -74,8 +73,9 @@ const applyTheme = async theme => { await loadComponentPackages(packagesTheme); // When changing the theme, run the ponyfill immediately - if (ponyfillNeeded()) { - runPonyfill(); + const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); + if (LegacyBrowsersSupport && LegacyBrowsersSupport.ponyfillNeeded()) { + LegacyBrowsersSupport.runPonyfill(); } fireThemeLoaded(theme); diff --git a/packages/base/test/pages/AllTestElements.html b/packages/base/test/pages/AllTestElements.html index 86c22fdf2802..8fb086ca365a 100644 --- a/packages/base/test/pages/AllTestElements.html +++ b/packages/base/test/pages/AllTestElements.html @@ -6,10 +6,7 @@ Base package default test page - - - diff --git a/packages/base/test/pages/Configuration.html b/packages/base/test/pages/Configuration.html index 353974047b51..875fdf7fbaf7 100644 --- a/packages/base/test/pages/Configuration.html +++ b/packages/base/test/pages/Configuration.html @@ -6,9 +6,7 @@ Base package default test page - - diff --git a/packages/base/test/pages/ConfigurationScript.html b/packages/base/test/pages/ConfigurationScript.html index 6f681b4d9d26..74d789a69e30 100644 --- a/packages/base/test/pages/ConfigurationScript.html +++ b/packages/base/test/pages/ConfigurationScript.html @@ -22,9 +22,7 @@ } - - diff --git a/packages/compatibility/.eslintignore b/packages/compatibility/.eslintignore new file mode 100644 index 000000000000..59ce86b1d411 --- /dev/null +++ b/packages/compatibility/.eslintignore @@ -0,0 +1,4 @@ +# Note: Changes to this file also must be applied to the top level .eslintignore file. +lib +dist +src/thirdparty diff --git a/packages/compatibility/.npmrc b/packages/compatibility/.npmrc new file mode 100644 index 000000000000..5ea30aae908b --- /dev/null +++ b/packages/compatibility/.npmrc @@ -0,0 +1,2 @@ +# Enforce public npm registry +registry = https://registry.npmjs.org/ diff --git a/packages/compatibility/README.md b/packages/compatibility/README.md new file mode 100644 index 000000000000..f52e42c335ec --- /dev/null +++ b/packages/compatibility/README.md @@ -0,0 +1,25 @@ +![UI5 icon](https://raw.githubusercontent.com/SAP/ui5-webcomponents/master/docs/images/UI5_logo_wide.png) + +# UI5 Web Components - Compatibility + +[![Travis CI Build Status](https://travis-ci.org/SAP/ui5-webcomponents.svg?branch=master)](https://travis-ci.org/SAP/ui5-webcomponents) +[![npm Package Version](https://badge.fury.io/js/%40ui5%2Fwebcomponents.svg)](https://www.npmjs.com/package/@ui5/webcomponents) + +Contains the base files for all Web Components, most notably `@ui5/webcomponents-base/dist/UI5Element.js`. + +For a complete list of all app development related public module imports from the `base` package, click [here](../../docs/Public%20Module%20Imports.md#base): + +## Resources +- [UI5 Web Components - README.md](https://github.com/SAP/ui5-webcomponents/blob/master/README.md) +- [UI5 Web Components - Home Page](https://sap.github.io/ui5-webcomponents) +- [UI5 Web Components - Playground and API Reference](https://sap.github.io/ui5-webcomponents/playground/) + +## Support +We welcome all comments, suggestions, questions, and bug reports. Please follow our [Support Guidelines](https://github.com/SAP/ui5-webcomponents/blob/master/SUPPORT.md#-content) on how to report an issue, or chat with us in the `#webcomponents` channel of the [OpenUI5 Community Slack](https://join-ui5-slack.herokuapp.com/). + +## Contribute +Please check our [Contribution Guidelines](https://github.com/SAP/ui5-webcomponents/blob/master/CONTRIBUTING.md). + +## License +Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. +This file is licensed under the Apache Software License, Version 2.0 except as noted otherwise in the [LICENSE](https://github.com/SAP/ui5-webcomponents/blob/master/LICENSE.txt) file. diff --git a/packages/compatibility/config/.eslintrc.js b/packages/compatibility/config/.eslintrc.js new file mode 100644 index 000000000000..2d19042b2aba --- /dev/null +++ b/packages/compatibility/config/.eslintrc.js @@ -0,0 +1,3 @@ +const config = require("@ui5/webcomponents-tools/components-package/eslint.js"); + +module.exports = config; diff --git a/packages/compatibility/package-scripts.js b/packages/compatibility/package-scripts.js new file mode 100644 index 000000000000..5f6b53f92884 --- /dev/null +++ b/packages/compatibility/package-scripts.js @@ -0,0 +1,14 @@ +const scripts = { + clean: "rimraf dist", + lint: "eslint . --config config/.eslintrc.js", + copy: `copy-and-watch "src/**/*.js" dist/`, + build: { + "default": "path-exists dist/ || nps build.all", + all: "nps lint clean copy", + }, +}; + + +module.exports = { + scripts, +}; diff --git a/packages/compatibility/package.json b/packages/compatibility/package.json new file mode 100644 index 000000000000..1983dcfcfd1b --- /dev/null +++ b/packages/compatibility/package.json @@ -0,0 +1,37 @@ +{ + "name": "@ui5/webcomponents-compatibility", + "version": "0.28.0", + "description": "UI5 Web Components: webcomponents.compatibility", + "author": "SAP SE (https://www.sap.com)", + "license": "Apache-2.0", + "module": "index.js", + "keywords": [ + "openui5", + "sapui5", + "ui5" + ], + "repository": { + "type": "git", + "url": "https://github.com/SAP/ui5-webcomponents.git", + "directory": "packages/compatibility" + }, + "scripts": { + "clean": "nps clean", + "lint": "nps lint", + "build": "nps build", + "prepublishOnly": "npm run clean && npm run build" + }, + "dependencies": { + "@ui5/webcomponents-base": "0.28.0", + "css-vars-ponyfill": "^2.1.2", + "regenerator-runtime": "0.12.1", + "url-search-params-polyfill": "^5.0.0" + }, + "devDependencies": { + "@ui5/webcomponents-tools": "1.0.0-rc.11", + "copy-and-watch": "^0.1.4", + "eslint": "^5.13.0", + "eslint-config-airbnb-base": "^13.1.0", + "path-exists-cli": "^1.0.0" + } +} diff --git a/packages/compatibility/src/LegacyBrowsersSupport.js b/packages/compatibility/src/LegacyBrowsersSupport.js new file mode 100644 index 000000000000..de133d9f5198 --- /dev/null +++ b/packages/compatibility/src/LegacyBrowsersSupport.js @@ -0,0 +1,19 @@ +import { registerFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; + +import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; +import adaptCSSForIE from "./theming/adaptCSSForIE.js"; +import createComponentStyleTag from "./theming/createComponentStyleTag.js"; +import { + ponyfillNeeded, + runPonyfill, + schedulePonyfill, +} from "./theming/CSSVarsPonyfill.js"; + +registerFeature("LegacyBrowsersSupport", { + whenPolyfillLoaded, + adaptCSSForIE, + createComponentStyleTag, + ponyfillNeeded, + runPonyfill, + schedulePonyfill, +}); diff --git a/packages/base/src/features/browsersupport/Edge.js b/packages/compatibility/src/features/Edge.js similarity index 62% rename from packages/base/src/features/browsersupport/Edge.js rename to packages/compatibility/src/features/Edge.js index 6478a4d8d625..156cf06fbe39 100644 --- a/packages/base/src/features/browsersupport/Edge.js +++ b/packages/compatibility/src/features/Edge.js @@ -3,4 +3,6 @@ import "url-search-params-polyfill/index.js"; // "pseudo mutation observer" fix for nodeValue -import "../../compatibility/patchNodeValue.js"; +import "../patchNodeValue.js"; + +import "../LegacyBrowsersSupport.js"; diff --git a/packages/compatibility/src/features/IE11.js b/packages/compatibility/src/features/IE11.js new file mode 100644 index 000000000000..d4cc880074e3 --- /dev/null +++ b/packages/compatibility/src/features/IE11.js @@ -0,0 +1,43 @@ +// CSS Custom Properties +import cssVars from "css-vars-ponyfill/dist/css-vars-ponyfill.esm.js"; + +// String +import "../thirdparty/es6-string-methods.js"; + +// Object +import "../thirdparty/Object.entries.js"; + +// Array +import "../thirdparty/Array.prototype.fill.js"; +import "../thirdparty/Array.prototype.find.js"; +import "../thirdparty/Array.prototype.findIndex.js"; +import "../thirdparty/Array.prototype.includes.js"; + +// Map +import "../thirdparty/Map.prototype.keys.js"; + +// Number +import "../thirdparty/Number.isInteger.js"; +import "../thirdparty/Number.isNaN.js"; +import "../thirdparty/Number.parseFloat.js"; +import "../thirdparty/Number.parseInt.js"; + +// Element +import "../thirdparty/Element.prototype.matches.js"; +import "../thirdparty/Element.prototype.closest.js"; + +// WeakSet +import "../thirdparty/WeakSet.js"; + +// fetch +import "../thirdparty/fetch.js"; + +// async - await +import "regenerator-runtime/runtime.js"; + +// Plus all polyfills needed for Edge are also needed for IE11 +import "./Edge.js"; + +window.CSSVarsPonyfill = { + cssVars, +}; diff --git a/packages/base/src/features/browsersupport/IE11WithWebComponentsPolyfill.js b/packages/compatibility/src/features/IE11WithWebComponentsPolyfill.js similarity index 76% rename from packages/base/src/features/browsersupport/IE11WithWebComponentsPolyfill.js rename to packages/compatibility/src/features/IE11WithWebComponentsPolyfill.js index b0557004de51..a4e0e27a511a 100644 --- a/packages/base/src/features/browsersupport/IE11WithWebComponentsPolyfill.js +++ b/packages/compatibility/src/features/IE11WithWebComponentsPolyfill.js @@ -1,5 +1,5 @@ // All web components polyfills (including platform) with "window" passed as argument to the iife -import "../../thirdparty/webcomponents-sd-ce-pf.js"; +import "../thirdparty/webcomponents-sd-ce-pf.js"; // All IE11 polyfills, needed by the project itself import "./IE11.js"; diff --git a/packages/base/src/compatibility/patchNodeValue.js b/packages/compatibility/src/patchNodeValue.js similarity index 100% rename from packages/base/src/compatibility/patchNodeValue.js rename to packages/compatibility/src/patchNodeValue.js diff --git a/packages/base/src/theming/CSSVarsPonyfill.js b/packages/compatibility/src/theming/CSSVarsPonyfill.js similarity index 100% rename from packages/base/src/theming/CSSVarsPonyfill.js rename to packages/compatibility/src/theming/CSSVarsPonyfill.js diff --git a/packages/base/src/theming/adaptCSSForIE.js b/packages/compatibility/src/theming/adaptCSSForIE.js similarity index 100% rename from packages/base/src/theming/adaptCSSForIE.js rename to packages/compatibility/src/theming/adaptCSSForIE.js diff --git a/packages/base/src/theming/createComponentStyleTag.js b/packages/compatibility/src/theming/createComponentStyleTag.js similarity index 82% rename from packages/base/src/theming/createComponentStyleTag.js rename to packages/compatibility/src/theming/createComponentStyleTag.js index bde64ec6a7fd..5a108cd0ce34 100644 --- a/packages/base/src/theming/createComponentStyleTag.js +++ b/packages/compatibility/src/theming/createComponentStyleTag.js @@ -1,8 +1,8 @@ -import createStyleInHead from "../util/createStyleInHead.js"; -import getEffectiveStyle from "./getEffectiveStyle.js"; +import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHead.js"; +import getEffectiveStyle from "@ui5/webcomponents-base/dist/theming/getEffectiveStyle.js"; +import { attachCustomCSSChange } from "@ui5/webcomponents-base/dist/theming/CustomStyle.js"; import adaptCSSForIE from "./adaptCSSForIE.js"; import { ponyfillNeeded, schedulePonyfill } from "./CSSVarsPonyfill.js"; -import { attachCustomCSSChange } from "./CustomStyle.js"; const IEStyleSet = new Set(); diff --git a/packages/base/src/thirdparty/Array.from.js b/packages/compatibility/src/thirdparty/Array.from.js similarity index 100% rename from packages/base/src/thirdparty/Array.from.js rename to packages/compatibility/src/thirdparty/Array.from.js diff --git a/packages/base/src/thirdparty/Array.prototype.fill.js b/packages/compatibility/src/thirdparty/Array.prototype.fill.js similarity index 100% rename from packages/base/src/thirdparty/Array.prototype.fill.js rename to packages/compatibility/src/thirdparty/Array.prototype.fill.js diff --git a/packages/base/src/thirdparty/Array.prototype.find.js b/packages/compatibility/src/thirdparty/Array.prototype.find.js similarity index 100% rename from packages/base/src/thirdparty/Array.prototype.find.js rename to packages/compatibility/src/thirdparty/Array.prototype.find.js diff --git a/packages/base/src/thirdparty/Array.prototype.findIndex.js b/packages/compatibility/src/thirdparty/Array.prototype.findIndex.js similarity index 100% rename from packages/base/src/thirdparty/Array.prototype.findIndex.js rename to packages/compatibility/src/thirdparty/Array.prototype.findIndex.js diff --git a/packages/base/src/thirdparty/Array.prototype.includes.js b/packages/compatibility/src/thirdparty/Array.prototype.includes.js similarity index 100% rename from packages/base/src/thirdparty/Array.prototype.includes.js rename to packages/compatibility/src/thirdparty/Array.prototype.includes.js diff --git a/packages/base/src/thirdparty/Element.prototype.closest.js b/packages/compatibility/src/thirdparty/Element.prototype.closest.js similarity index 100% rename from packages/base/src/thirdparty/Element.prototype.closest.js rename to packages/compatibility/src/thirdparty/Element.prototype.closest.js diff --git a/packages/base/src/thirdparty/Element.prototype.matches.js b/packages/compatibility/src/thirdparty/Element.prototype.matches.js similarity index 100% rename from packages/base/src/thirdparty/Element.prototype.matches.js rename to packages/compatibility/src/thirdparty/Element.prototype.matches.js diff --git a/packages/base/src/thirdparty/Map.prototype.keys.js b/packages/compatibility/src/thirdparty/Map.prototype.keys.js similarity index 100% rename from packages/base/src/thirdparty/Map.prototype.keys.js rename to packages/compatibility/src/thirdparty/Map.prototype.keys.js diff --git a/packages/base/src/thirdparty/Number.isInteger.js b/packages/compatibility/src/thirdparty/Number.isInteger.js similarity index 100% rename from packages/base/src/thirdparty/Number.isInteger.js rename to packages/compatibility/src/thirdparty/Number.isInteger.js diff --git a/packages/base/src/thirdparty/Number.isNaN.js b/packages/compatibility/src/thirdparty/Number.isNaN.js similarity index 100% rename from packages/base/src/thirdparty/Number.isNaN.js rename to packages/compatibility/src/thirdparty/Number.isNaN.js diff --git a/packages/base/src/thirdparty/Number.parseFloat.js b/packages/compatibility/src/thirdparty/Number.parseFloat.js similarity index 100% rename from packages/base/src/thirdparty/Number.parseFloat.js rename to packages/compatibility/src/thirdparty/Number.parseFloat.js diff --git a/packages/base/src/thirdparty/Number.parseInt.js b/packages/compatibility/src/thirdparty/Number.parseInt.js similarity index 100% rename from packages/base/src/thirdparty/Number.parseInt.js rename to packages/compatibility/src/thirdparty/Number.parseInt.js diff --git a/packages/base/src/thirdparty/Object.assign.js b/packages/compatibility/src/thirdparty/Object.assign.js similarity index 100% rename from packages/base/src/thirdparty/Object.assign.js rename to packages/compatibility/src/thirdparty/Object.assign.js diff --git a/packages/base/src/thirdparty/Object.entries.js b/packages/compatibility/src/thirdparty/Object.entries.js similarity index 100% rename from packages/base/src/thirdparty/Object.entries.js rename to packages/compatibility/src/thirdparty/Object.entries.js diff --git a/packages/base/src/thirdparty/Symbol.js b/packages/compatibility/src/thirdparty/Symbol.js similarity index 100% rename from packages/base/src/thirdparty/Symbol.js rename to packages/compatibility/src/thirdparty/Symbol.js diff --git a/packages/base/src/thirdparty/WeakSet.js b/packages/compatibility/src/thirdparty/WeakSet.js similarity index 100% rename from packages/base/src/thirdparty/WeakSet.js rename to packages/compatibility/src/thirdparty/WeakSet.js diff --git a/packages/base/src/thirdparty/es6-string-methods.js b/packages/compatibility/src/thirdparty/es6-string-methods.js similarity index 100% rename from packages/base/src/thirdparty/es6-string-methods.js rename to packages/compatibility/src/thirdparty/es6-string-methods.js diff --git a/packages/base/src/thirdparty/events-polyfills.js b/packages/compatibility/src/thirdparty/events-polyfills.js similarity index 100% rename from packages/base/src/thirdparty/events-polyfills.js rename to packages/compatibility/src/thirdparty/events-polyfills.js diff --git a/packages/base/src/thirdparty/fetch.js b/packages/compatibility/src/thirdparty/fetch.js similarity index 100% rename from packages/base/src/thirdparty/fetch.js rename to packages/compatibility/src/thirdparty/fetch.js diff --git a/packages/base/src/thirdparty/template.js b/packages/compatibility/src/thirdparty/template.js similarity index 100% rename from packages/base/src/thirdparty/template.js rename to packages/compatibility/src/thirdparty/template.js diff --git a/packages/base/src/thirdparty/webcomponents-sd-ce-pf.js b/packages/compatibility/src/thirdparty/webcomponents-sd-ce-pf.js similarity index 100% rename from packages/base/src/thirdparty/webcomponents-sd-ce-pf.js rename to packages/compatibility/src/thirdparty/webcomponents-sd-ce-pf.js diff --git a/packages/base/src/compatibility/whenPolyfillLoaded.js b/packages/compatibility/src/whenPolyfillLoaded.js similarity index 100% rename from packages/base/src/compatibility/whenPolyfillLoaded.js rename to packages/compatibility/src/whenPolyfillLoaded.js diff --git a/packages/fiori/bundle.es5.js b/packages/fiori/bundle.es5.js index 788dda545ff1..2e6f837f5d34 100644 --- a/packages/fiori/bundle.es5.js +++ b/packages/fiori/bundle.es5.js @@ -1,5 +1,5 @@ // ES5 bundle targets IE11 only -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11.js"; +import "@ui5/webcomponents-compatibility/dist/features/IE11.js"; import testAssets from "./bundle.esm.js"; diff --git a/packages/fiori/package.json b/packages/fiori/package.json index f7ae2a0c8196..d5f5219caed6 100644 --- a/packages/fiori/package.json +++ b/packages/fiori/package.json @@ -32,6 +32,7 @@ "dependencies": { "@ui5/webcomponents": "1.0.0-rc.11", "@ui5/webcomponents-base": "0.28.0", + "@ui5/webcomponents-compatibility": "0.28.0", "@ui5/webcomponents-icons": "1.0.0-rc.11", "@ui5/webcomponents-theme-base": "1.0.0-rc.11" }, diff --git a/packages/main/bundle.es5.js b/packages/main/bundle.es5.js index 788dda545ff1..2e6f837f5d34 100644 --- a/packages/main/bundle.es5.js +++ b/packages/main/bundle.es5.js @@ -1,5 +1,5 @@ // ES5 bundle targets IE11 only -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11.js"; +import "@ui5/webcomponents-compatibility/dist/features/IE11.js"; import testAssets from "./bundle.esm.js"; diff --git a/packages/main/bundle.esm.js b/packages/main/bundle.esm.js index 605a86927684..851442ac981d 100644 --- a/packages/main/bundle.esm.js +++ b/packages/main/bundle.esm.js @@ -15,9 +15,6 @@ import "@ui5/webcomponents-localization/dist/features/calendar/Islamic.js"; import "@ui5/webcomponents-localization/dist/features/calendar/Japanese.js"; import "@ui5/webcomponents-localization/dist/features/calendar/Persian.js"; -// ESM bundle targets Edge + browsers with native support -import "@ui5/webcomponents-base/dist/features/browsersupport/Edge.js"; - // CLDR import getLocaleData from "@ui5/webcomponents-localization/dist/locale/getLocaleData.js"; diff --git a/packages/main/package.json b/packages/main/package.json index db19643039ca..a4ecbf5a97ef 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -31,6 +31,7 @@ }, "dependencies": { "@ui5/webcomponents-base": "0.28.0", + "@ui5/webcomponents-compatibility": "0.28.0", "@ui5/webcomponents-icons": "1.0.0-rc.11", "@ui5/webcomponents-localization": "0.28.0", "@ui5/webcomponents-theme-base": "1.0.0-rc.11" diff --git a/packages/tools/components-package/rollup.js b/packages/tools/components-package/rollup.js index 392b9be8aa69..ae0935c64855 100644 --- a/packages/tools/components-package/rollup.js +++ b/packages/tools/components-package/rollup.js @@ -92,7 +92,7 @@ const getES6Config = (input = "bundle.esm.js") => { sourcemap: true }, moduleContext: (id) => { - if (id.includes("url-search-params-polyfill")) { + if (typeof id === "string" && id.includes("url-search-params-polyfill")) { // suppress the rollup error for this module as it uses this in the global scope correctly even without changing the context here return "window"; } @@ -130,7 +130,7 @@ const getES5Config = (input = "bundle.es5.js") => { let config = getES6Config(); -if (process.env.ES5_BUILD) { +if (process.env.ES5_BUILD && fs.existsSync("bundle.es5.js")) { config = config.concat(getES5Config()); } From 5571ec1176aa0a6c5d00114c1c2561278a8c4818 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Thu, 14 Jan 2021 17:48:58 +0200 Subject: [PATCH 02/19] isLegacyBrowser --- packages/base/src/StaticAreaItem.js | 5 ++++- packages/base/src/UI5Element.js | 9 +++++---- packages/compatibility/src/LegacyBrowsersSupport.js | 2 ++ packages/compatibility/src/isLegacyBrowser.js | 3 +++ 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 packages/compatibility/src/isLegacyBrowser.js diff --git a/packages/base/src/StaticAreaItem.js b/packages/base/src/StaticAreaItem.js index 327df9df263c..cf69f70557db 100644 --- a/packages/base/src/StaticAreaItem.js +++ b/packages/base/src/StaticAreaItem.js @@ -2,6 +2,9 @@ import { getStaticAreaInstance, removeStaticArea } from "./StaticArea.js"; import RenderScheduler from "./RenderScheduler.js"; import getStylesString from "./theming/getStylesString.js"; import executeTemplate from "./renderer/executeTemplate.js"; +import { getFeature } from "./FeaturesRegistry.js"; + +const Legacy = getFeature("LegacyBrowsersSupport"); /** * @class @@ -24,7 +27,7 @@ class StaticAreaItem { */ _updateFragment() { const renderResult = executeTemplate(this.ui5ElementContext.constructor.staticAreaTemplate, this.ui5ElementContext), - stylesToAdd = window.ShadyDOM ? false : getStylesString(this.ui5ElementContext.constructor.staticAreaStyles); + stylesToAdd = Legacy && Legacy.isLegacyBrowser() ? false : getStylesString(this.ui5ElementContext.constructor.staticAreaStyles); if (!this.staticAreaItemDomRef) { // Initial rendering of fragment diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index 112d6a5294f5..c5535567fad5 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -20,7 +20,7 @@ import arraysAreEqual from "./util/arraysAreEqual.js"; import { markAsRtlAware } from "./locale/RTLAwareRegistry.js"; import { getFeature } from "./FeaturesRegistry.js"; -const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); +const Legacy = getFeature("LegacyBrowsersSupport"); let autoId = 0; @@ -628,10 +628,11 @@ class UI5Element extends HTMLElement { let styleToPrepend; const renderResult = executeTemplate(this.constructor.template, this); + const isLegacyBrowser = Legacy && Legacy.isLegacyBrowser(); // IE11, Edge - if (window.ShadyDOM && LegacyBrowsersSupport) { - LegacyBrowsersSupport.createComponentStyleTag(this.constructor); + if (isLegacyBrowser) { + Legacy.createComponentStyleTag(this.constructor); } // Chrome @@ -640,7 +641,7 @@ class UI5Element extends HTMLElement { } // FF, Safari - if (!document.adoptedStyleSheets && !window.ShadyDOM) { + if (!document.adoptedStyleSheets && !isLegacyBrowser) { styleToPrepend = getEffectiveStyle(this.constructor); } diff --git a/packages/compatibility/src/LegacyBrowsersSupport.js b/packages/compatibility/src/LegacyBrowsersSupport.js index de133d9f5198..6cedabbed6b8 100644 --- a/packages/compatibility/src/LegacyBrowsersSupport.js +++ b/packages/compatibility/src/LegacyBrowsersSupport.js @@ -1,5 +1,6 @@ import { registerFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; +import isLegacyBrowser from "./isLegacyBrowser.js"; import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; import adaptCSSForIE from "./theming/adaptCSSForIE.js"; import createComponentStyleTag from "./theming/createComponentStyleTag.js"; @@ -10,6 +11,7 @@ import { } from "./theming/CSSVarsPonyfill.js"; registerFeature("LegacyBrowsersSupport", { + isLegacyBrowser, whenPolyfillLoaded, adaptCSSForIE, createComponentStyleTag, diff --git a/packages/compatibility/src/isLegacyBrowser.js b/packages/compatibility/src/isLegacyBrowser.js new file mode 100644 index 000000000000..11d7bedef891 --- /dev/null +++ b/packages/compatibility/src/isLegacyBrowser.js @@ -0,0 +1,3 @@ +const isLegacyBrowser = () => !!window.ShadyDOM; + +export default isLegacyBrowser; From 0f113d230f1d67a4d285adf029145a27edb50172 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Thu, 14 Jan 2021 21:39:45 +0200 Subject: [PATCH 03/19] dom observer rework --- packages/base/src/DOMObserver.js | 29 +++++++++ packages/base/src/UI5Element.js | 6 +- .../base/src/compatibility/DOMObserver.js | 62 ------------------- packages/compatibility/src/DOMObserver.js | 31 ++++++++++ .../src/LegacyBrowsersSupport.js | 2 + 5 files changed, 65 insertions(+), 65 deletions(-) create mode 100644 packages/base/src/DOMObserver.js delete mode 100644 packages/base/src/compatibility/DOMObserver.js create mode 100644 packages/compatibility/src/DOMObserver.js diff --git a/packages/base/src/DOMObserver.js b/packages/base/src/DOMObserver.js new file mode 100644 index 000000000000..b8be8c9ed0f0 --- /dev/null +++ b/packages/base/src/DOMObserver.js @@ -0,0 +1,29 @@ +const observers = new WeakMap(); + +class DOMObserver { + /** + * @param node + * @param callback + * @param options + */ + static observeDOMNode(node, callback, options) { + const observerObject = new MutationObserver(callback); + observerObject.observe(node, options); + observers.set(node, observerObject); + } + + /** + * @param node + */ + static unobserveDOMNode(node) { + const observerObject = observers.get(node); + if (!observerObject) { + return; + } + + observerObject.disconnect(); + observers.delete(node); + } +} + +export default DOMObserver; diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index c5535567fad5..3634af9d6659 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -6,7 +6,7 @@ import executeTemplate from "./renderer/executeTemplate.js"; import StaticAreaItem from "./StaticAreaItem.js"; import RenderScheduler from "./RenderScheduler.js"; import { registerTag, isTagRegistered, recordTagRegistrationFailure } from "./CustomElementsRegistry.js"; -import DOMObserver from "./compatibility/DOMObserver.js"; +import DOMObserver from "./DOMObserver.js"; import { skipOriginalEvent } from "./config/NoConflict.js"; import { getRTL } from "./config/RTL.js"; import getConstructableStyle from "./theming/getConstructableStyle.js"; @@ -197,14 +197,14 @@ class UI5Element extends HTMLElement { subtree: canSlotText, characterData: canSlotText, }; - DOMObserver.observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); + (Legacy ? Legacy.DOMObserver : DOMObserver).observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); } /** * @private */ _stopObservingDOMChildren() { - DOMObserver.unobserveDOMNode(this); + (Legacy ? Legacy.DOMObserver : DOMObserver).unobserveDOMNode(this); } /** diff --git a/packages/base/src/compatibility/DOMObserver.js b/packages/base/src/compatibility/DOMObserver.js deleted file mode 100644 index 0a7af55e4e70..000000000000 --- a/packages/base/src/compatibility/DOMObserver.js +++ /dev/null @@ -1,62 +0,0 @@ -// Shorthands -const w = window; - -// Map of observer objects per dom node -const observers = new WeakMap(); - -/** - * Implements universal DOM node observation methods. - */ -class DOMObserver { - constructor() { - throw new Error("Static class"); - } - - /** - * This function abstracts out mutation observer usage inside shadow DOM. - * For native shadow DOM the native mutation observer is used. - * When the polyfill is used, the observeChildren ShadyDOM method is used instead. - * - * @throws Exception - * Note: does not allow several mutation observers per node. If there is a valid use-case, this behavior can be changed. - * - * @param node - * @param callback - * @param options - Only used for the native mutation observer - */ - static observeDOMNode(node, callback, options) { - let observerObject = observers.get(node); - if (observerObject) { - throw new Error("A mutation/ShadyDOM observer is already assigned to this node."); - } - - if (w.ShadyDOM) { - observerObject = w.ShadyDOM.observeChildren(node, callback); - } else { - observerObject = new MutationObserver(callback); - observerObject.observe(node, options); - } - - observers.set(node, observerObject); - } - - /** - * De-registers the mutation observer, depending on its type - * @param node - */ - static unobserveDOMNode(node) { - const observerObject = observers.get(node); - if (!observerObject) { - return; - } - - if (observerObject instanceof MutationObserver) { - observerObject.disconnect(); - } else { - w.ShadyDOM.unobserveChildren(observerObject); - } - observers.delete(node); - } -} - -export default DOMObserver; diff --git a/packages/compatibility/src/DOMObserver.js b/packages/compatibility/src/DOMObserver.js new file mode 100644 index 000000000000..4ef8197376a4 --- /dev/null +++ b/packages/compatibility/src/DOMObserver.js @@ -0,0 +1,31 @@ +// Map of observer objects per dom node +const observers = new WeakMap(); + +/** + * Implements universal DOM node observation methods. + */ +class DOMObserver { + /** + * @param node + * @param callback + */ + static observeDOMNode(node, callback) { + const observerObject = window.ShadyDOM.observeChildren(node, callback); + observers.set(node, observerObject); + } + + /** + * @param node + */ + static unobserveDOMNode(node) { + const observerObject = observers.get(node); + if (!observerObject) { + return; + } + + window.ShadyDOM.unobserveChildren(observerObject); + observers.delete(node); + } +} + +export default DOMObserver; diff --git a/packages/compatibility/src/LegacyBrowsersSupport.js b/packages/compatibility/src/LegacyBrowsersSupport.js index 6cedabbed6b8..034946c04bbc 100644 --- a/packages/compatibility/src/LegacyBrowsersSupport.js +++ b/packages/compatibility/src/LegacyBrowsersSupport.js @@ -2,6 +2,7 @@ import { registerFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.j import isLegacyBrowser from "./isLegacyBrowser.js"; import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; +import DOMObserver from "./DOMObserver.js"; import adaptCSSForIE from "./theming/adaptCSSForIE.js"; import createComponentStyleTag from "./theming/createComponentStyleTag.js"; import { @@ -13,6 +14,7 @@ import { registerFeature("LegacyBrowsersSupport", { isLegacyBrowser, whenPolyfillLoaded, + DOMObserver, adaptCSSForIE, createComponentStyleTag, ponyfillNeeded, From 665a67ae0737bf603927aa327b6f5114806b324a Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Fri, 15 Jan 2021 10:36:25 +0200 Subject: [PATCH 04/19] icon --- packages/main/src/Icon.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/main/src/Icon.js b/packages/main/src/Icon.js index 40027b76f1d4..932cbe0bcd99 100644 --- a/packages/main/src/Icon.js +++ b/packages/main/src/Icon.js @@ -4,6 +4,7 @@ import { getIconData, getIconDataSync } from "@ui5/webcomponents-base/dist/SVGIc import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHead.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; +import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import IconTemplate from "./generated/templates/IconTemplate.lit.js"; // Styles @@ -11,6 +12,8 @@ import iconCss from "./generated/themes/Icon.css.js"; const ICON_NOT_FOUND = "ICON_NOT_FOUND"; +const Legacy = getFeature("LegacyBrowsersSupport"); + /** * @public */ @@ -238,7 +241,7 @@ class Icon extends UI5Element { } static createGlobalStyle() { - if (!window.ShadyDOM) { + if (!Legacy || !Legacy.isLegacyBrowser()) { return; } const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); @@ -248,7 +251,7 @@ class Icon extends UI5Element { } static removeGlobalStyle() { - if (!window.ShadyDOM) { + if (!Legacy || !Legacy.isLegacyBrowser()) { return; } const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); From 9e7ca243dd9e0f30526a4f4aa9c9cf78994a4488 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Fri, 15 Jan 2021 11:13:04 +0200 Subject: [PATCH 05/19] button example --- packages/base/package-scripts.js | 2 +- packages/main/src/Button.js | 3 +- packages/main/src/themes/Button.css | 51 ---------------------- packages/main/src/themes/Button.legacy.css | 48 ++++++++++++++++++++ 4 files changed, 51 insertions(+), 53 deletions(-) create mode 100644 packages/main/src/themes/Button.legacy.css diff --git a/packages/base/package-scripts.js b/packages/base/package-scripts.js index 0e55eb561ddc..c0220d4ae221 100644 --- a/packages/base/package-scripts.js +++ b/packages/base/package-scripts.js @@ -12,7 +12,7 @@ const scripts = { prepare: "nps clean copy generateAssetParameters", build: { default: "nps lint prepare build.bundle", - bundle: "rollup --config config/rollup.config.js --environment", + bundle: "rollup --config config/rollup.config.js", }, copy: { default: "nps copy.src copy.test", diff --git a/packages/main/src/Button.js b/packages/main/src/Button.js index 002669679940..6145ee24bb6e 100644 --- a/packages/main/src/Button.js +++ b/packages/main/src/Button.js @@ -12,6 +12,7 @@ import { BUTTON_ARIA_TYPE_ACCEPT, BUTTON_ARIA_TYPE_REJECT, BUTTON_ARIA_TYPE_EMPH // Styles import buttonCss from "./generated/themes/Button.css.js"; +import buttonLegacyCss from "./generated/themes/ButtonLegacy.css.js"; let isGlobalHandlerAttached = false; let activeButton = null; @@ -286,7 +287,7 @@ class Button extends UI5Element { } static get styles() { - return buttonCss; + return [buttonCss, buttonLegacyCss]; } static get render() { diff --git a/packages/main/src/themes/Button.css b/packages/main/src/themes/Button.css index 39cd976a93c5..49c4abd03a57 100644 --- a/packages/main/src/themes/Button.css +++ b/packages/main/src/themes/Button.css @@ -238,54 +238,3 @@ bdi { :host([design="Transparent"]:not([active]):hover) { border-color: var(--_ui5_button_transparent_hover_border_color); } - -/* IE Specific CSS */ - -[ui5-button][focused] { - outline: none; -} - -[ui5-button][focused] .ui5-button-root { - position: relative; -} - -[ui5-button][focused] .ui5-button-root::after { - content: ""; - position: absolute; - border-width: 1px; - border-style: dotted; - border-color: var(--_ui5_button_focus_color); - top: var(--_ui5_button_focus_offset); - bottom: var(--_ui5_button_focus_offset); - left: var(--_ui5_button_focus_offset); - right: var(--_ui5_button_focus_offset); -} - -[ui5-button][active] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-button][design="Positive"][focused] .ui5-button-root::after { - border-color: var(--_ui5_button_positive_border_focus_hover_color); -} - -[ui5-button][design="Positive"][active][focused] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-button][design="Negative"][focused] .ui5-button-root::after { - border-color: var(--_ui5_button_positive_border_focus_hover_color); -} - -[ui5-button][design="Negative"][active][focused] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-button][design="Emphasized"][focused] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-button] [ui5-icon].ui5-button-icon { - height: var(--_ui5_button_icon_font_size); /* Center vertically all icons*/ - top: 0; -} diff --git a/packages/main/src/themes/Button.legacy.css b/packages/main/src/themes/Button.legacy.css new file mode 100644 index 000000000000..268ae9babc0b --- /dev/null +++ b/packages/main/src/themes/Button.legacy.css @@ -0,0 +1,48 @@ +[ui5-button][focused] { + outline: none; +} + +[ui5-button][focused] .ui5-button-root { + position: relative; +} + +[ui5-button][focused] .ui5-button-root::after { + content: ""; + position: absolute; + border-width: 1px; + border-style: dotted; + border-color: var(--_ui5_button_focus_color); + top: var(--_ui5_button_focus_offset); + bottom: var(--_ui5_button_focus_offset); + left: var(--_ui5_button_focus_offset); + right: var(--_ui5_button_focus_offset); +} + +[ui5-button][active] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-button][design="Positive"][focused] .ui5-button-root::after { + border-color: var(--_ui5_button_positive_border_focus_hover_color); +} + +[ui5-button][design="Positive"][active][focused] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-button][design="Negative"][focused] .ui5-button-root::after { + border-color: var(--_ui5_button_positive_border_focus_hover_color); +} + +[ui5-button][design="Negative"][active][focused] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-button][design="Emphasized"][focused] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-button] [ui5-icon].ui5-button-icon { + height: var(--_ui5_button_icon_font_size); /* Center vertically all icons*/ + top: 0; +} From f515ae3c8f854f5123d759f806e4ae705da2c491 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Fri, 15 Jan 2021 13:23:42 +0200 Subject: [PATCH 06/19] big refactoring --- packages/base/src/StaticAreaItem.js | 51 +++++++++++++------ packages/base/src/UI5Element.js | 33 +++++------- packages/base/src/boot.js | 2 +- packages/base/src/isLegacyBrowser.js | 9 ++++ packages/base/src/theming/applyTheme.js | 7 ++- .../base/src/theming/getConstructableStyle.js | 13 ++--- .../base/src/theming/getEffectiveStyle.js | 23 ++++++--- .../src/LegacyBrowsersSupport.js | 41 ++++++++++----- packages/compatibility/src/isLegacyBrowser.js | 3 -- .../src/theming/CSSVarsPonyfill.js | 19 +++---- .../src/theming/createComponentStyleTag.js | 7 ++- packages/main/src/Button.js | 5 +- packages/main/src/ToggleButton.js | 4 +- packages/main/src/themes/ToggleButton.css | 29 ----------- .../main/src/themes/ToggleButton.legacy.css | 28 ++++++++++ packages/main/test/pages/DatePicker.html | 2 +- packages/main/test/pages/List.html | 2 +- 17 files changed, 159 insertions(+), 119 deletions(-) create mode 100644 packages/base/src/isLegacyBrowser.js delete mode 100644 packages/compatibility/src/isLegacyBrowser.js create mode 100644 packages/main/src/themes/ToggleButton.legacy.css diff --git a/packages/base/src/StaticAreaItem.js b/packages/base/src/StaticAreaItem.js index cf69f70557db..6da2f565d3b7 100644 --- a/packages/base/src/StaticAreaItem.js +++ b/packages/base/src/StaticAreaItem.js @@ -1,10 +1,9 @@ import { getStaticAreaInstance, removeStaticArea } from "./StaticArea.js"; import RenderScheduler from "./RenderScheduler.js"; -import getStylesString from "./theming/getStylesString.js"; +import getEffectiveStyle from "./theming/getEffectiveStyle.js"; import executeTemplate from "./renderer/executeTemplate.js"; -import { getFeature } from "./FeaturesRegistry.js"; - -const Legacy = getFeature("LegacyBrowsersSupport"); +import isLegacyBrowser from "./isLegacyBrowser.js"; +import getConstructableStyle from "./theming/getConstructableStyle.js"; /** * @class @@ -23,25 +22,45 @@ class StaticAreaItem { } /** - * @protected + * @private */ - _updateFragment() { - const renderResult = executeTemplate(this.ui5ElementContext.constructor.staticAreaTemplate, this.ui5ElementContext), - stylesToAdd = Legacy && Legacy.isLegacyBrowser() ? false : getStylesString(this.ui5ElementContext.constructor.staticAreaStyles); + _createStaticAreaItem() { + if (this.staticAreaItemDomRef) { + return; + } - if (!this.staticAreaItemDomRef) { - // Initial rendering of fragment + // Initial rendering of fragment + this.staticAreaItemDomRef = document.createElement("ui5-static-area-item"); + this.staticAreaItemDomRef.attachShadow({ mode: "open" }); + this.staticAreaItemDomRef.classList.add(this.ui5ElementContext._id); // used for getting the popover in the tests - this.staticAreaItemDomRef = document.createElement("ui5-static-area-item"); - this.staticAreaItemDomRef.attachShadow({ mode: "open" }); - this.staticAreaItemDomRef.classList.add(this.ui5ElementContext._id); // used for getting the popover in the tests + getStaticAreaInstance().appendChild(this.staticAreaItemDomRef); + this._rendered = true; + } - getStaticAreaInstance().appendChild(this.staticAreaItemDomRef); - this._rendered = true; + /** + * @private + */ + _updateStaticAreaItemShadowRoot() { + const renderResult = executeTemplate(this.ui5ElementContext.constructor.staticAreaTemplate, this.ui5ElementContext); + let stylesToPrepend; + + if (document.adoptedStyleSheets) { // Chrome + this.staticAreaItemDomRef.shadowRoot.adoptedStyleSheets = getConstructableStyle(this.ui5ElementContext.constructor, true); + } else if (!isLegacyBrowser()) { // FF, Safari + stylesToPrepend = getEffectiveStyle(this.ui5ElementContext.constructor, true); } + this.ui5ElementContext.constructor.render(renderResult, this.staticAreaItemDomRef.shadowRoot, stylesToPrepend, { eventContext: this.ui5ElementContext }); + } + + /** + * @protected + */ + _updateFragment() { + this._createStaticAreaItem(); this._updateContentDensity(this.ui5ElementContext.isCompact); - this.ui5ElementContext.constructor.render(renderResult, this.staticAreaItemDomRef.shadowRoot, stylesToAdd, { eventContext: this.ui5ElementContext }); + this._updateStaticAreaItemShadowRoot(); } /** diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index 3634af9d6659..1a4568b43ddc 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -19,8 +19,10 @@ import isSlot from "./util/isSlot.js"; import arraysAreEqual from "./util/arraysAreEqual.js"; import { markAsRtlAware } from "./locale/RTLAwareRegistry.js"; import { getFeature } from "./FeaturesRegistry.js"; +import isLegacyBrowser from "./isLegacyBrowser.js"; -const Legacy = getFeature("LegacyBrowsersSupport"); +const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); +const effectiveDOMObserver = isLegacyBrowser() ? LegacyBrowsersSupport.DOMObserver : DOMObserver; let autoId = 0; @@ -197,14 +199,14 @@ class UI5Element extends HTMLElement { subtree: canSlotText, characterData: canSlotText, }; - (Legacy ? Legacy.DOMObserver : DOMObserver).observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); + effectiveDOMObserver.observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); } /** * @private */ _stopObservingDOMChildren() { - (Legacy ? Legacy.DOMObserver : DOMObserver).unobserveDOMNode(this); + effectiveDOMObserver.unobserveDOMNode(this); } /** @@ -601,7 +603,12 @@ class UI5Element extends HTMLElement { this._changedState = []; // Update shadow root and static area item - this._updateShadowRoot(); + if (LegacyBrowsersSupport) { + LegacyBrowsersSupport.onComponentRender(this); + } + if (this.constructor._needsShadowDOM()) { + this._updateShadowRoot(); + } if (this._shouldUpdateFragment()) { this.staticAreaItem._updateFragment(this); this.staticAreaItemDomRef = this.staticAreaItem.staticAreaItemDomRef.shadowRoot; @@ -622,26 +629,12 @@ class UI5Element extends HTMLElement { * @private */ _updateShadowRoot() { - if (!this.constructor._needsShadowDOM()) { - return; - } - let styleToPrepend; const renderResult = executeTemplate(this.constructor.template, this); - const isLegacyBrowser = Legacy && Legacy.isLegacyBrowser(); - // IE11, Edge - if (isLegacyBrowser) { - Legacy.createComponentStyleTag(this.constructor); - } - - // Chrome - if (document.adoptedStyleSheets) { + if (document.adoptedStyleSheets) { // Chrome this.shadowRoot.adoptedStyleSheets = getConstructableStyle(this.constructor); - } - - // FF, Safari - if (!document.adoptedStyleSheets && !isLegacyBrowser) { + } else if (!isLegacyBrowser()) { // FF, Safari styleToPrepend = getEffectiveStyle(this.constructor); } diff --git a/packages/base/src/boot.js b/packages/base/src/boot.js index d9adc04671f5..acaa3db6e21f 100644 --- a/packages/base/src/boot.js +++ b/packages/base/src/boot.js @@ -25,7 +25,7 @@ const boot = () => { insertFontFace(); insertSystemCSSVars(); if (LegacyBrowsersSupport) { - await LegacyBrowsersSupport.whenPolyfillLoaded(); + await LegacyBrowsersSupport.onBoot(); } resolve(); }); diff --git a/packages/base/src/isLegacyBrowser.js b/packages/base/src/isLegacyBrowser.js new file mode 100644 index 000000000000..2ee8afb9091d --- /dev/null +++ b/packages/base/src/isLegacyBrowser.js @@ -0,0 +1,9 @@ +import { getFeature } from "./FeaturesRegistry.js"; + +const Legacy = getFeature("LegacyBrowsersSupport"); + +const isLegacyBrowser = () => { + return Legacy && Legacy.isLegacyBrowser(); +}; + +export default isLegacyBrowser; diff --git a/packages/base/src/theming/applyTheme.js b/packages/base/src/theming/applyTheme.js index 9c88ab745de5..572187d4f5a9 100644 --- a/packages/base/src/theming/applyTheme.js +++ b/packages/base/src/theming/applyTheme.js @@ -4,6 +4,7 @@ import getThemeDesignerTheme from "./getThemeDesignerTheme.js"; import { fireThemeLoaded } from "./ThemeLoaded.js"; import { getFeature } from "../FeaturesRegistry.js"; +const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); const BASE_THEME_PACKAGE = "@ui5/webcomponents-theme-base"; const isThemeBaseRegistered = () => { @@ -72,10 +73,8 @@ const applyTheme = async theme => { const packagesTheme = isThemeRegistered(theme) ? theme : extTheme && extTheme.baseThemeName; await loadComponentPackages(packagesTheme); - // When changing the theme, run the ponyfill immediately - const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); - if (LegacyBrowsersSupport && LegacyBrowsersSupport.ponyfillNeeded()) { - LegacyBrowsersSupport.runPonyfill(); + if (LegacyBrowsersSupport) { + LegacyBrowsersSupport.onApplyTheme(); } fireThemeLoaded(theme); diff --git a/packages/base/src/theming/getConstructableStyle.js b/packages/base/src/theming/getConstructableStyle.js index ce86eedeb033..dbe097597b54 100644 --- a/packages/base/src/theming/getConstructableStyle.js +++ b/packages/base/src/theming/getConstructableStyle.js @@ -4,7 +4,7 @@ import { attachCustomCSSChange } from "./CustomStyle.js"; const constructableStyleMap = new Map(); attachCustomCSSChange(tag => { - constructableStyleMap.delete(tag); + constructableStyleMap.delete(`${tag}_normal`); // there is custom CSS only for the component itself, not for its static area part }); /** @@ -13,17 +13,18 @@ attachCustomCSSChange(tag => { * @param ElementClass * @returns {*} */ -const getConstructableStyle = ElementClass => { +const getConstructableStyle = (ElementClass, forStaticArea = false) => { const tag = ElementClass.getMetadata().getTag(); + const key = `${tag}_${forStaticArea ? "static" : "normal"}`; - if (!constructableStyleMap.has(tag)) { - const styleContent = getEffectiveStyle(ElementClass); + if (!constructableStyleMap.has(key)) { + const styleContent = getEffectiveStyle(ElementClass, forStaticArea); const style = new CSSStyleSheet(); style.replaceSync(styleContent); - constructableStyleMap.set(tag, [style]); + constructableStyleMap.set(key, [style]); } - return constructableStyleMap.get(tag); + return constructableStyleMap.get(key); }; export default getConstructableStyle; diff --git a/packages/base/src/theming/getEffectiveStyle.js b/packages/base/src/theming/getEffectiveStyle.js index 9f40f329451f..949a4aa74fe7 100644 --- a/packages/base/src/theming/getEffectiveStyle.js +++ b/packages/base/src/theming/getEffectiveStyle.js @@ -4,20 +4,27 @@ import getStylesString from "./getStylesString.js"; const effectiveStyleMap = new Map(); attachCustomCSSChange(tag => { - effectiveStyleMap.delete(tag); + effectiveStyleMap.delete(`${tag}_normal`); // there is custom CSS only for the component itself, not for its static area part }); -const getEffectiveStyle = ElementClass => { +const getEffectiveStyle = (ElementClass, forStaticArea = false) => { const tag = ElementClass.getMetadata().getTag(); + const key = `${tag}_${forStaticArea ? "static" : "normal"}`; - if (!effectiveStyleMap.has(tag)) { - const customStyle = getCustomCSS(tag) || ""; - const builtInStyles = getStylesString(ElementClass.styles); - const effectiveStyle = `${builtInStyles} ${customStyle}`; - effectiveStyleMap.set(tag, effectiveStyle); + if (!effectiveStyleMap.has(key)) { + let effectiveStyle; + + if (forStaticArea) { + effectiveStyle = getStylesString(ElementClass.staticAreaStyles); + } else { + const customStyle = getCustomCSS(tag) || ""; + const builtInStyles = getStylesString(ElementClass.styles); + effectiveStyle = `${builtInStyles} ${customStyle}`; + } + effectiveStyleMap.set(key, effectiveStyle); } - return effectiveStyleMap.get(tag); + return effectiveStyleMap.get(key); }; export default getEffectiveStyle; diff --git a/packages/compatibility/src/LegacyBrowsersSupport.js b/packages/compatibility/src/LegacyBrowsersSupport.js index 034946c04bbc..d366a16103bc 100644 --- a/packages/compatibility/src/LegacyBrowsersSupport.js +++ b/packages/compatibility/src/LegacyBrowsersSupport.js @@ -1,23 +1,36 @@ import { registerFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; - -import isLegacyBrowser from "./isLegacyBrowser.js"; import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; import DOMObserver from "./DOMObserver.js"; -import adaptCSSForIE from "./theming/adaptCSSForIE.js"; import createComponentStyleTag from "./theming/createComponentStyleTag.js"; -import { - ponyfillNeeded, - runPonyfill, - schedulePonyfill, -} from "./theming/CSSVarsPonyfill.js"; +import { runPonyfill } from "./theming/CSSVarsPonyfill.js"; + +const isLegacyBrowser = () => !!window.ShadyDOM; + +// Executed once on boot +const onBoot = async () => { + await (isLegacyBrowser() ? whenPolyfillLoaded() : Promise.resolve()); +}; + +// Executed on each theme application +const onApplyTheme = () => { + isLegacyBrowser() && runPonyfill(); +}; + +// Executed on each component render +const onComponentRender = component => { + if (!isLegacyBrowser()) { + return; + } + + if (component.constructor._needsShadowDOM() || component.constructor._needsStaticArea()) { + createComponentStyleTag(component.constructor); + } +}; registerFeature("LegacyBrowsersSupport", { isLegacyBrowser, - whenPolyfillLoaded, DOMObserver, - adaptCSSForIE, - createComponentStyleTag, - ponyfillNeeded, - runPonyfill, - schedulePonyfill, + onBoot, + onApplyTheme, + onComponentRender, }); diff --git a/packages/compatibility/src/isLegacyBrowser.js b/packages/compatibility/src/isLegacyBrowser.js deleted file mode 100644 index 11d7bedef891..000000000000 --- a/packages/compatibility/src/isLegacyBrowser.js +++ /dev/null @@ -1,3 +0,0 @@ -const isLegacyBrowser = () => !!window.ShadyDOM; - -export default isLegacyBrowser; diff --git a/packages/compatibility/src/theming/CSSVarsPonyfill.js b/packages/compatibility/src/theming/CSSVarsPonyfill.js index f7acbe3511f8..d4d7c124202f 100644 --- a/packages/compatibility/src/theming/CSSVarsPonyfill.js +++ b/packages/compatibility/src/theming/CSSVarsPonyfill.js @@ -22,18 +22,20 @@ const cleanPonyfillMetadata = (rootElement = document.head) => { }; const runPonyfill = () => { - ponyfillTimer = undefined; + if (ponyfillNeeded()) { + ponyfillTimer = undefined; - cleanPonyfillMetadata(); - window.CSSVarsPonyfill.cssVars({ - rootElement: document.head, - variables: isCompact() ? getCompactModeVars() : {}, - silent: true, - }); + cleanPonyfillMetadata(); + window.CSSVarsPonyfill.cssVars({ + rootElement: document.head, + variables: isCompact() ? getCompactModeVars() : {}, + silent: true, + }); + } }; const schedulePonyfill = () => { - if (!ponyfillTimer) { + if (!ponyfillTimer && ponyfillNeeded()) { ponyfillTimer = window.setTimeout(runPonyfill, 0); } }; @@ -62,7 +64,6 @@ const getCompactModeVars = () => { }; export { - ponyfillNeeded, runPonyfill, schedulePonyfill, }; diff --git a/packages/compatibility/src/theming/createComponentStyleTag.js b/packages/compatibility/src/theming/createComponentStyleTag.js index 5a108cd0ce34..f650a24d84ce 100644 --- a/packages/compatibility/src/theming/createComponentStyleTag.js +++ b/packages/compatibility/src/theming/createComponentStyleTag.js @@ -2,7 +2,7 @@ import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHe import getEffectiveStyle from "@ui5/webcomponents-base/dist/theming/getEffectiveStyle.js"; import { attachCustomCSSChange } from "@ui5/webcomponents-base/dist/theming/CustomStyle.js"; import adaptCSSForIE from "./adaptCSSForIE.js"; -import { ponyfillNeeded, schedulePonyfill } from "./CSSVarsPonyfill.js"; +import { schedulePonyfill } from "./CSSVarsPonyfill.js"; const IEStyleSet = new Set(); @@ -44,9 +44,8 @@ const createComponentStyleTag = ElementClass => { createStyleInHead(cssContent, { "data-ui5-element-styles": tag, }); - if (ponyfillNeeded()) { - schedulePonyfill(); - } + + schedulePonyfill(); IEStyleSet.add(tag); }; diff --git a/packages/main/src/Button.js b/packages/main/src/Button.js index 6145ee24bb6e..7264809b1c00 100644 --- a/packages/main/src/Button.js +++ b/packages/main/src/Button.js @@ -4,6 +4,7 @@ import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; +import isLegacyBrowser from "@ui5/webcomponents-base/dist/isLegacyBrowser.js"; import ButtonDesign from "./types/ButtonDesign.js"; import ButtonTemplate from "./generated/templates/ButtonTemplate.lit.js"; import Icon from "./Icon.js"; @@ -12,7 +13,7 @@ import { BUTTON_ARIA_TYPE_ACCEPT, BUTTON_ARIA_TYPE_REJECT, BUTTON_ARIA_TYPE_EMPH // Styles import buttonCss from "./generated/themes/Button.css.js"; -import buttonLegacyCss from "./generated/themes/ButtonLegacy.css.js"; +import buttonLegacyCss from "./generated/themes/Button.legacy.css.js"; let isGlobalHandlerAttached = false; let activeButton = null; @@ -287,7 +288,7 @@ class Button extends UI5Element { } static get styles() { - return [buttonCss, buttonLegacyCss]; + return [buttonCss, isLegacyBrowser() ? buttonLegacyCss : undefined]; } static get render() { diff --git a/packages/main/src/ToggleButton.js b/packages/main/src/ToggleButton.js index 28e4112238b3..edb52f0ded83 100644 --- a/packages/main/src/ToggleButton.js +++ b/packages/main/src/ToggleButton.js @@ -1,8 +1,10 @@ +import isLegacyBrowser from "@ui5/webcomponents-base/dist/isLegacyBrowser.js"; import Button from "./Button.js"; import ToggleButtonTemplate from "./generated/templates/ToggleButtonTemplate.lit.js"; // Styles import toggleBtnCss from "./generated/themes/ToggleButton.css.js"; +import toggleBtnLegacyCss from "./generated/themes/ToggleButton.legacy.css.js"; /** * @public @@ -58,7 +60,7 @@ class ToggleButton extends Button { } static get styles() { - return [Button.styles, toggleBtnCss]; + return [Button.styles, toggleBtnCss, isLegacyBrowser() ? toggleBtnLegacyCss : undefined]; } _onclick() { diff --git a/packages/main/src/themes/ToggleButton.css b/packages/main/src/themes/ToggleButton.css index 0e4d782ef315..6d5121d84a94 100644 --- a/packages/main/src/themes/ToggleButton.css +++ b/packages/main/src/themes/ToggleButton.css @@ -75,32 +75,3 @@ left: var(--_ui5_button_focus_offset); right: var(--_ui5_button_focus_offset); } - -[ui5-togglebutton][active] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-togglebutton][design="Positive"][focused] .ui5-button-root::after { - border-color: var(--_ui5_button_positive_border_focus_hover_color); -} - -[ui5-togglebutton][design="Positive"][active][focused] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-togglebutton][design="Negative"][focused] .ui5-button-root::after { - border-color: var(--_ui5_button_positive_border_focus_hover_color); -} - -[ui5-togglebutton][design="Negative"][active][focused] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-togglebutton][design="Emphasized"][focused] .ui5-button-root::after { - border-color: var(--sapContent_ContrastFocusColor); -} - -[ui5-togglebutton] [ui5-icon].ui5-button-icon { - height: var(--_ui5_button_icon_font_size); /* Center vertically all icons*/ - top: 0; -} diff --git a/packages/main/src/themes/ToggleButton.legacy.css b/packages/main/src/themes/ToggleButton.legacy.css new file mode 100644 index 000000000000..3bb26152fc70 --- /dev/null +++ b/packages/main/src/themes/ToggleButton.legacy.css @@ -0,0 +1,28 @@ +[ui5-togglebutton][active] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-togglebutton][design="Positive"][focused] .ui5-button-root::after { + border-color: var(--_ui5_button_positive_border_focus_hover_color); +} + +[ui5-togglebutton][design="Positive"][active][focused] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-togglebutton][design="Negative"][focused] .ui5-button-root::after { + border-color: var(--_ui5_button_positive_border_focus_hover_color); +} + +[ui5-togglebutton][design="Negative"][active][focused] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-togglebutton][design="Emphasized"][focused] .ui5-button-root::after { + border-color: var(--sapContent_ContrastFocusColor); +} + +[ui5-togglebutton] [ui5-icon].ui5-button-icon { + height: var(--_ui5_button_icon_font_size); /* Center vertically all icons*/ + top: 0; +} diff --git a/packages/main/test/pages/DatePicker.html b/packages/main/test/pages/DatePicker.html index 798cc604a399..7c67929c7f75 100644 --- a/packages/main/test/pages/DatePicker.html +++ b/packages/main/test/pages/DatePicker.html @@ -7,7 +7,7 @@ DatePicker test page diff --git a/packages/main/test/pages/List.html b/packages/main/test/pages/List.html index 297810c0be1e..f5beaef00228 100644 --- a/packages/main/test/pages/List.html +++ b/packages/main/test/pages/List.html @@ -287,7 +287,7 @@

Items 3/3

var value = event.detail.selectedOption.textContent; visualizationList.mode = modes[value]; - visualizationList.headerText = visualizationList.headerText.replace(/\(.+\)/, `(Current mode: ${value})`); + visualizationList.headerText = visualizationList.headerText.replace(/\(.+\)/, "(Current mode: " + value + ")"); }); var getItems = function getItems(items) { From 0c3abe04fa4fc85188e19500b8e76926ab88d752 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Fri, 15 Jan 2021 14:13:14 +0200 Subject: [PATCH 07/19] use adapter --- packages/base/src/LegacyBrowsersAdapter.js | 20 +++++++++++++++++++ packages/base/src/StaticAreaItem.js | 2 +- packages/base/src/UI5Element.js | 14 ++++--------- packages/base/src/boot.js | 7 +++---- packages/base/src/isLegacyBrowser.js | 9 --------- packages/base/src/theming/applyTheme.js | 6 ++---- ...yBrowsersSupport.js => LegacyInterface.js} | 2 +- packages/compatibility/src/features/Edge.js | 2 +- packages/main/src/Button.js | 2 +- packages/main/src/Icon.js | 8 +++----- packages/main/src/ToggleButton.js | 2 +- 11 files changed, 37 insertions(+), 37 deletions(-) create mode 100644 packages/base/src/LegacyBrowsersAdapter.js delete mode 100644 packages/base/src/isLegacyBrowser.js rename packages/compatibility/src/{LegacyBrowsersSupport.js => LegacyInterface.js} (95%) diff --git a/packages/base/src/LegacyBrowsersAdapter.js b/packages/base/src/LegacyBrowsersAdapter.js new file mode 100644 index 000000000000..e1102a35c1ef --- /dev/null +++ b/packages/base/src/LegacyBrowsersAdapter.js @@ -0,0 +1,20 @@ +import { getFeature } from "./FeaturesRegistry.js"; + +const LegacyInterface = getFeature("LegacyInterface"); + +const emptyFn = () => undefined; +const falsyFn = () => false; + +const isLegacyBrowser = LegacyInterface ? LegacyInterface.isLegacyBrowser : falsyFn; +const LegacyDOMObserver = LegacyInterface ? LegacyInterface.DOMObserver : undefined; +const onLegacyBoot = LegacyInterface ? LegacyInterface.onBoot : emptyFn; +const onLegacyApplyTheme = LegacyInterface ? LegacyInterface.onApplyTheme : emptyFn; +const onLegacyComponentRender = LegacyInterface ? LegacyInterface.onComponentRender : emptyFn; + +export { + isLegacyBrowser, + LegacyDOMObserver, + onLegacyBoot, + onLegacyApplyTheme, + onLegacyComponentRender, +}; diff --git a/packages/base/src/StaticAreaItem.js b/packages/base/src/StaticAreaItem.js index 6da2f565d3b7..8e0d9b501a29 100644 --- a/packages/base/src/StaticAreaItem.js +++ b/packages/base/src/StaticAreaItem.js @@ -2,7 +2,7 @@ import { getStaticAreaInstance, removeStaticArea } from "./StaticArea.js"; import RenderScheduler from "./RenderScheduler.js"; import getEffectiveStyle from "./theming/getEffectiveStyle.js"; import executeTemplate from "./renderer/executeTemplate.js"; -import isLegacyBrowser from "./isLegacyBrowser.js"; +import { isLegacyBrowser } from "./LegacyBrowsersAdapter.js"; import getConstructableStyle from "./theming/getConstructableStyle.js"; /** diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index 1a4568b43ddc..94a7fa3a1ae1 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -18,11 +18,7 @@ import isValidPropertyName from "./util/isValidPropertyName.js"; import isSlot from "./util/isSlot.js"; import arraysAreEqual from "./util/arraysAreEqual.js"; import { markAsRtlAware } from "./locale/RTLAwareRegistry.js"; -import { getFeature } from "./FeaturesRegistry.js"; -import isLegacyBrowser from "./isLegacyBrowser.js"; - -const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); -const effectiveDOMObserver = isLegacyBrowser() ? LegacyBrowsersSupport.DOMObserver : DOMObserver; +import { isLegacyBrowser, LegacyDOMObserver, onLegacyComponentRender } from "./LegacyBrowsersAdapter.js"; let autoId = 0; @@ -199,14 +195,14 @@ class UI5Element extends HTMLElement { subtree: canSlotText, characterData: canSlotText, }; - effectiveDOMObserver.observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); + (LegacyDOMObserver || DOMObserver).observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); } /** * @private */ _stopObservingDOMChildren() { - effectiveDOMObserver.unobserveDOMNode(this); + (LegacyDOMObserver || DOMObserver).unobserveDOMNode(this); } /** @@ -603,9 +599,7 @@ class UI5Element extends HTMLElement { this._changedState = []; // Update shadow root and static area item - if (LegacyBrowsersSupport) { - LegacyBrowsersSupport.onComponentRender(this); - } + onLegacyComponentRender(this); if (this.constructor._needsShadowDOM()) { this._updateShadowRoot(); } diff --git a/packages/base/src/boot.js b/packages/base/src/boot.js index acaa3db6e21f..94d3e8d1532c 100644 --- a/packages/base/src/boot.js +++ b/packages/base/src/boot.js @@ -4,6 +4,7 @@ import insertSystemCSSVars from "./SystemCSSVars.js"; import { getTheme } from "./config/Theme.js"; import applyTheme from "./theming/applyTheme.js"; import { getFeature } from "./FeaturesRegistry.js"; +import { onLegacyBoot } from "./LegacyBrowsersAdapter.js"; let bootPromise; @@ -14,7 +15,6 @@ const boot = () => { bootPromise = new Promise(async resolve => { const OpenUI5Support = getFeature("OpenUI5Support"); - const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); if (OpenUI5Support) { await OpenUI5Support.init(); } @@ -24,9 +24,8 @@ const boot = () => { OpenUI5Support && OpenUI5Support.attachListeners(); insertFontFace(); insertSystemCSSVars(); - if (LegacyBrowsersSupport) { - await LegacyBrowsersSupport.onBoot(); - } + await onLegacyBoot(); + resolve(); }); diff --git a/packages/base/src/isLegacyBrowser.js b/packages/base/src/isLegacyBrowser.js deleted file mode 100644 index 2ee8afb9091d..000000000000 --- a/packages/base/src/isLegacyBrowser.js +++ /dev/null @@ -1,9 +0,0 @@ -import { getFeature } from "./FeaturesRegistry.js"; - -const Legacy = getFeature("LegacyBrowsersSupport"); - -const isLegacyBrowser = () => { - return Legacy && Legacy.isLegacyBrowser(); -}; - -export default isLegacyBrowser; diff --git a/packages/base/src/theming/applyTheme.js b/packages/base/src/theming/applyTheme.js index 572187d4f5a9..ca65ef6ccb28 100644 --- a/packages/base/src/theming/applyTheme.js +++ b/packages/base/src/theming/applyTheme.js @@ -3,8 +3,8 @@ import createThemePropertiesStyleTag from "./createThemePropertiesStyleTag.js"; import getThemeDesignerTheme from "./getThemeDesignerTheme.js"; import { fireThemeLoaded } from "./ThemeLoaded.js"; import { getFeature } from "../FeaturesRegistry.js"; +import { onLegacyApplyTheme } from "../LegacyBrowsersAdapter.js"; -const LegacyBrowsersSupport = getFeature("LegacyBrowsersSupport"); const BASE_THEME_PACKAGE = "@ui5/webcomponents-theme-base"; const isThemeBaseRegistered = () => { @@ -73,9 +73,7 @@ const applyTheme = async theme => { const packagesTheme = isThemeRegistered(theme) ? theme : extTheme && extTheme.baseThemeName; await loadComponentPackages(packagesTheme); - if (LegacyBrowsersSupport) { - LegacyBrowsersSupport.onApplyTheme(); - } + onLegacyApplyTheme(); fireThemeLoaded(theme); }; diff --git a/packages/compatibility/src/LegacyBrowsersSupport.js b/packages/compatibility/src/LegacyInterface.js similarity index 95% rename from packages/compatibility/src/LegacyBrowsersSupport.js rename to packages/compatibility/src/LegacyInterface.js index d366a16103bc..6486e6180d69 100644 --- a/packages/compatibility/src/LegacyBrowsersSupport.js +++ b/packages/compatibility/src/LegacyInterface.js @@ -27,7 +27,7 @@ const onComponentRender = component => { } }; -registerFeature("LegacyBrowsersSupport", { +registerFeature("LegacyInterface", { isLegacyBrowser, DOMObserver, onBoot, diff --git a/packages/compatibility/src/features/Edge.js b/packages/compatibility/src/features/Edge.js index 156cf06fbe39..716dbeea894a 100644 --- a/packages/compatibility/src/features/Edge.js +++ b/packages/compatibility/src/features/Edge.js @@ -5,4 +5,4 @@ import "url-search-params-polyfill/index.js"; // "pseudo mutation observer" fix for nodeValue import "../patchNodeValue.js"; -import "../LegacyBrowsersSupport.js"; +import "../LegacyInterface.js"; diff --git a/packages/main/src/Button.js b/packages/main/src/Button.js index 7264809b1c00..028214b3eb21 100644 --- a/packages/main/src/Button.js +++ b/packages/main/src/Button.js @@ -4,7 +4,7 @@ import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; -import isLegacyBrowser from "@ui5/webcomponents-base/dist/isLegacyBrowser.js"; +import { isLegacyBrowser } from "@ui5/webcomponents-base/dist/LegacyBrowsersAdapter.js"; import ButtonDesign from "./types/ButtonDesign.js"; import ButtonTemplate from "./generated/templates/ButtonTemplate.lit.js"; import Icon from "./Icon.js"; diff --git a/packages/main/src/Icon.js b/packages/main/src/Icon.js index 932cbe0bcd99..6c9511e4cc2a 100644 --- a/packages/main/src/Icon.js +++ b/packages/main/src/Icon.js @@ -4,7 +4,7 @@ import { getIconData, getIconDataSync } from "@ui5/webcomponents-base/dist/SVGIc import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHead.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; -import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; +import { isLegacyBrowser } from "@ui5/webcomponents-base/dist/LegacyBrowsersAdapter.js"; import IconTemplate from "./generated/templates/IconTemplate.lit.js"; // Styles @@ -12,8 +12,6 @@ import iconCss from "./generated/themes/Icon.css.js"; const ICON_NOT_FOUND = "ICON_NOT_FOUND"; -const Legacy = getFeature("LegacyBrowsersSupport"); - /** * @public */ @@ -241,7 +239,7 @@ class Icon extends UI5Element { } static createGlobalStyle() { - if (!Legacy || !Legacy.isLegacyBrowser()) { + if (!isLegacyBrowser()) { return; } const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); @@ -251,7 +249,7 @@ class Icon extends UI5Element { } static removeGlobalStyle() { - if (!Legacy || !Legacy.isLegacyBrowser()) { + if (!isLegacyBrowser()) { return; } const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); diff --git a/packages/main/src/ToggleButton.js b/packages/main/src/ToggleButton.js index edb52f0ded83..fd4b636cd698 100644 --- a/packages/main/src/ToggleButton.js +++ b/packages/main/src/ToggleButton.js @@ -1,4 +1,4 @@ -import isLegacyBrowser from "@ui5/webcomponents-base/dist/isLegacyBrowser.js"; +import { isLegacyBrowser } from "@ui5/webcomponents-base/dist/LegacyBrowsersAdapter.js"; import Button from "./Button.js"; import ToggleButtonTemplate from "./generated/templates/ToggleButtonTemplate.lit.js"; From cb58856796bc10d3fe179c959973275eb83b1fbc Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Fri, 15 Jan 2021 16:51:02 +0200 Subject: [PATCH 08/19] rename package --- README.md | 3 ++- docs/Public Module Imports.md | 24 ++++--------------- .../Creating UI5 Web Components Packages.md | 9 +++++-- package.json | 19 ++++++++------- packages/compatibility/src/features/Edge.js | 8 ------- packages/fiori/bundle.es5.js | 2 +- packages/fiori/package.json | 2 +- .../{compatibility => ie11}/.eslintignore | 0 packages/{compatibility => ie11}/.npmrc | 0 packages/{compatibility => ie11}/README.md | 6 ++--- .../config/.eslintrc.js | 0 .../package-scripts.js | 7 +++--- packages/{compatibility => ie11}/package.json | 9 ++++--- .../src/DOMObserver.js | 0 .../src/LegacyInterface.js | 0 .../src/features/IE11.js | 11 +++++++-- .../features/IE11WithWebComponentsPolyfill.js | 0 .../src/patchNodeValue.js | 0 .../src/theming/CSSVarsPonyfill.js | 0 .../src/theming/adaptCSSForIE.js | 0 .../src/theming/createComponentStyleTag.js | 0 .../src/thirdparty/Array.from.js | 0 .../src/thirdparty/Array.prototype.fill.js | 0 .../src/thirdparty/Array.prototype.find.js | 0 .../thirdparty/Array.prototype.findIndex.js | 0 .../thirdparty/Array.prototype.includes.js | 0 .../thirdparty/Element.prototype.closest.js | 0 .../thirdparty/Element.prototype.matches.js | 0 .../src/thirdparty/Map.prototype.keys.js | 0 .../src/thirdparty/Number.isInteger.js | 0 .../src/thirdparty/Number.isNaN.js | 0 .../src/thirdparty/Number.parseFloat.js | 0 .../src/thirdparty/Number.parseInt.js | 0 .../src/thirdparty/Object.assign.js | 0 .../src/thirdparty/Object.entries.js | 0 .../src/thirdparty/Symbol.js | 0 .../src/thirdparty/WeakSet.js | 0 .../src/thirdparty/es6-string-methods.js | 0 .../src/thirdparty/events-polyfills.js | 0 .../src/thirdparty/fetch.js | 0 .../src/thirdparty/template.js | 0 .../src/thirdparty/webcomponents-sd-ce-pf.js | 0 .../src/whenPolyfillLoaded.js | 0 packages/main/bundle.es5.js | 2 +- packages/main/package.json | 2 +- .../lib/init-package/resources/bundle.es5.js | 2 +- .../lib/init-package/resources/bundle.esm.js | 3 --- 47 files changed, 47 insertions(+), 62 deletions(-) delete mode 100644 packages/compatibility/src/features/Edge.js rename packages/{compatibility => ie11}/.eslintignore (100%) rename packages/{compatibility => ie11}/.npmrc (100%) rename packages/{compatibility => ie11}/README.md (82%) rename packages/{compatibility => ie11}/config/.eslintrc.js (100%) rename packages/{compatibility => ie11}/package-scripts.js (62%) rename packages/{compatibility => ie11}/package.json (76%) rename packages/{compatibility => ie11}/src/DOMObserver.js (100%) rename packages/{compatibility => ie11}/src/LegacyInterface.js (100%) rename packages/{compatibility => ie11}/src/features/IE11.js (81%) rename packages/{compatibility => ie11}/src/features/IE11WithWebComponentsPolyfill.js (100%) rename packages/{compatibility => ie11}/src/patchNodeValue.js (100%) rename packages/{compatibility => ie11}/src/theming/CSSVarsPonyfill.js (100%) rename packages/{compatibility => ie11}/src/theming/adaptCSSForIE.js (100%) rename packages/{compatibility => ie11}/src/theming/createComponentStyleTag.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Array.from.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Array.prototype.fill.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Array.prototype.find.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Array.prototype.findIndex.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Array.prototype.includes.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Element.prototype.closest.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Element.prototype.matches.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Map.prototype.keys.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Number.isInteger.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Number.isNaN.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Number.parseFloat.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Number.parseInt.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Object.assign.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Object.entries.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/Symbol.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/WeakSet.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/es6-string-methods.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/events-polyfills.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/fetch.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/template.js (100%) rename packages/{compatibility => ie11}/src/thirdparty/webcomponents-sd-ce-pf.js (100%) rename packages/{compatibility => ie11}/src/whenPolyfillLoaded.js (100%) diff --git a/README.md b/README.md index bc890b8af9aa..7ed725f82944 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ Safari | Native Edge | Native IE 11 | With Polyfill -If your app needs to support **IE11** or **legacy Edge**, please follow the [instructions](https://github.com/SAP/ui5-webcomponents/blob/master/docs/Public%20Module%20Imports.md#1-old-browser-support-edge-ie11). +If your app needs to support **IE11**, please follow the [instructions](https://github.com/SAP/ui5-webcomponents/blob/master/docs/Public%20Module%20Imports.md#1-old-browser-support-ie11). ## Project structure, development and build @@ -128,6 +128,7 @@ Project | NPM Package | Description `base` | [UI5 Web Components Base](https://www.npmjs.com/package/@ui5/webcomponents-base) | The UI5 Web Components framework itself `theme-base` | [UI5 Web Components Theme Base](https://www.npmjs.com/package/@ui5/webcomponents-theme-base) | Theming assets (the default theme and additional accessibility themes) `localization` | [UI5 Web Components Localization](https://www.npmjs.com/package/@ui5/webcomponents-localization) | `i18n` functionality and `CLDR` assets +`ie11` | [UI5 Web Components IE11](https://www.npmjs.com/package/@ui5/webcomponents-ie11) | Internet Explorer 11 polyfills and adapter code `playground` | N/A | The playground application ### How to run the project locally: diff --git a/docs/Public Module Imports.md b/docs/Public Module Imports.md index 0eee928f8f5b..9843abe14c36 100644 --- a/docs/Public Module Imports.md +++ b/docs/Public Module Imports.md @@ -204,23 +204,16 @@ The `base` package provides not only the UI5 Web Components framework, but also all UI5 Web Components. -### 1. Old browser support (Edge, IE11) +### 1. Old browser support ( IE11) Most modern browsers - **Chrome, Firefox, Safari, Edge (Chromium-based)**, support Web Components natively. -If your app needs to be able to run additionally on the old **Edge (EdgeHTML-based)**, you should import the following module: +If your app needs to run on **IE11**, you should import: ```js -import "@ui5/webcomponents-base/dist/features/browsersupport/Edge.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11.js"; ``` -And if your app needs to run on both **Edge** and **IE11**, you should instead import: - -```js -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11.js"; -``` -(this also includes Edge support). - In addition, you should load the official Web Components polyfill in your index file, as described [here](https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs). @@ -238,22 +231,15 @@ As shown in the example above, it's recommended to load the Web Components Polyf Finally, there is an alternative to the `IE11.js` import: ```js -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11WithWebComponentsPolyfill.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11WithWebComponentsPolyfill.js"; ``` that includes the Web Components Polyfill too, so you don't have to import it manually. -This may be useful in certain use cases when your app has polyfills of its own and you need to guarantee the order of exectution. +This may be useful in certain use cases when your app has polyfills of its own and you need to guarantee the order of execution. The three old browser support options are summarized below: -| |`Edge.js` | `IE11.js` | `IE11WithWebComponentsPolyfill.js` | -|---|----------|-----------|------------------------------------| -|Browsers supported| Edge | Edge & IE11 | Edge & IE11 | -|Includes Web Components Polyfill | No* | No* | Yes| - -`* You must include the Web Components Polyfill manually` - ### 2. Theming diff --git a/docs/dev/Creating UI5 Web Components Packages.md b/docs/dev/Creating UI5 Web Components Packages.md index 17067fd3f658..e54d44e0540e 100644 --- a/docs/dev/Creating UI5 Web Components Packages.md +++ b/docs/dev/Creating UI5 Web Components Packages.md @@ -20,12 +20,14 @@ The name that you give to your package will be used by the UI5 Web Components to ## Step 2 - add the UI5 Web Components packages as dependencies With `npm`: - - `npm i --save @ui5/webcomponents-base @ui5/webcomponents-theme-base @ui5/webcomponents-tools` + - `npm i --save @ui5/webcomponents-base @ui5/webcomponents-theme-base @ui5/webcomponents-tools @ui5/webcomponents-ie11` - `npm i --save-dev chromedriver` + - (Optional) `npm i --save @ui5/webcomponents-ie11` or with `yarn`: - `yarn add @ui5/webcomponents-base @ui5/webcomponents-theme-base @ui5/webcomponents-tools` - `yarn add -D chromedriver` + - (Optional) `yarn add @ui5/webcomponents-ie11` These three `@ui5/` packages will serve as foundation for your own package and web components. @@ -34,11 +36,14 @@ Package | Description `@ui5/webcomponents-base` | Base classes and Framework `@ui5/webcomponents-theme-base` | Base theming assets `@ui5/webcomponents-tools` | Build and configuration assets +`@ui5/webcomponents-ie11` | (Optional) Internet Explorer 11 polyfills and adapter code *Note:* `chromedriver` is a peer dependency of `@ui5/webcomponents-tools` so that you get to choose the exact version, if necessary. This is useful if, for example, you manually update Chrome on your system and you'd prefer to not have a fixed `chromedriver` version packaged with `@ui5/webcomponents-tools`. +*Note:* `@ui5/webcomponents-ie11` is optional and should not be installed unless you need Internet Explorer 11 support. + ## Step 3 - run the package initialization script Run the initialization script, optionally with parameters from the following table: @@ -126,7 +131,7 @@ File | Purpose .eslintignore | Excludes the `dist/` and `test/` directories from static code scans package-scripts.js | An [nps](https://www.npmjs.com/package/nps) package scripts configuration file bundle.esm.js | Entry point for the ES6 bundle, used for development and tests. Intended for modern browsers. -bundle.es5.js | Entry point for the ES5 bundle, used for development and tests. Intended for IE11 only. +bundle.es5.js | Entry point for the ES5 bundle, used for development and tests. Intended for IE11 only. Delete this file if you don't need IE11 support. You'll likely only need to change `bundle.esm.js` to import your new components there. diff --git a/package.json b/package.json index 23686a440692..a962775edb48 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,10 @@ "ui5" ], "scripts": { - "build": "npm-run-all --sequential build:base build:compatibility build:localization build:theme-base build:icons build:icons-tnt build:main build:fiori", + "build": "npm-run-all --sequential build:base build:ie11 build:localization build:theme-base build:icons build:icons-tnt build:main build:fiori", "build:localization": "cd packages/localization && yarn build", "build:base": "cd packages/base && yarn build", - "build:compatibility": "cd packages/compatibility && yarn build", + "build:ie11": "cd packages/ie11 && yarn build", "build:theme-base": "cd packages/theme-base && yarn build", "build:icons": "cd packages/icons && yarn build", "build:icons-tnt": "cd packages/icons-tnt && yarn build", @@ -20,10 +20,10 @@ "build:fiori": "cd packages/fiori && yarn build", "build:playground": "yarn build:main && yarn build:fiori && cd packages/playground && yarn build", "build:playground:master": "yarn build:main && yarn build:fiori && cd packages/playground && yarn build:master", - "clean": "npm-run-all --sequential clean:base clean:compatibility clean:localization clean:theme-base clean:icons clean:icons-tnt clean:main clean:fiori", + "clean": "npm-run-all --sequential clean:base clean:ie11 clean:localization clean:theme-base clean:icons clean:icons-tnt clean:main clean:fiori", "clean:localization": "cd packages/localization && yarn clean", "clean:base": "cd packages/base && yarn clean", - "clean:compatibility": "cd packages/compatibility && yarn clean", + "clean:ie11": "cd packages/ie11 && yarn clean", "clean:theme-base": "cd packages/theme-base && yarn clean", "clean:icons": "cd packages/icons && yarn clean", "clean:icons-tnt": "cd packages/icons-tnt && yarn clean", @@ -34,15 +34,16 @@ "scopePrepare:main": "cd packages/main && nps scope.prepare", "scopePrepare:fiori": "cd packages/fiori && nps scope.prepare", "dev:base": "cd packages/base && nps watch", + "dev:ie11": "cd packages/ie11 && nps watch", "dev:localization": "cd packages/localization && nps watch", "dev:main": "cd packages/main && nps dev", "dev:fiori": "cd packages/fiori && nps dev", "scopeDev:main": "cd packages/main && nps scope.dev", "scopeDev:fiori": "cd packages/fiori && nps scope.dev", - "start": "npm-run-all --sequential build:base build:compatibility build:localization build:theme-base build:icons build:icons-tnt prepare:main prepare:fiori start:all", - "startWithScope": "npm-run-all --sequential build:base build:compatibility build:localization build:theme-base build:icons build:icons-tnt scopePrepare:main scopePrepare:fiori scopeStart:all", - "start:all": "npm-run-all --parallel dev:base dev:localization dev:main dev:fiori", - "scopeStart:all": "npm-run-all --parallel dev:base dev:localization scopeDev:main scopeDev:fiori", + "start": "npm-run-all --sequential build:base build:ie11 build:localization build:theme-base build:icons build:icons-tnt prepare:main prepare:fiori start:all", + "startWithScope": "npm-run-all --sequential build:base build:ie11 build:localization build:theme-base build:icons build:icons-tnt scopePrepare:main scopePrepare:fiori scopeStart:all", + "start:all": "npm-run-all --parallel dev:base dev:ie11 dev:localization dev:main dev:fiori", + "scopeStart:all": "npm-run-all --parallel dev:base dev:ie11 dev:localization scopeDev:main scopeDev:fiori", "start:base": "cd packages/base && yarn start", "start:main": "cd packages/main && yarn start", "start:fiori": "cd packages/fiori && yarn start", @@ -73,7 +74,7 @@ "packages/fiori", "packages/icons", "packages/icons-tnt", - "packages/compatibility", + "packages/ie11", "packages/tools", "packages/playground" ] diff --git a/packages/compatibility/src/features/Edge.js b/packages/compatibility/src/features/Edge.js deleted file mode 100644 index 716dbeea894a..000000000000 --- a/packages/compatibility/src/features/Edge.js +++ /dev/null @@ -1,8 +0,0 @@ -// URLSearchParams -import "url-search-params-polyfill/index.js"; - - -// "pseudo mutation observer" fix for nodeValue -import "../patchNodeValue.js"; - -import "../LegacyInterface.js"; diff --git a/packages/fiori/bundle.es5.js b/packages/fiori/bundle.es5.js index 2e6f837f5d34..3e9631ac0a03 100644 --- a/packages/fiori/bundle.es5.js +++ b/packages/fiori/bundle.es5.js @@ -1,5 +1,5 @@ // ES5 bundle targets IE11 only -import "@ui5/webcomponents-compatibility/dist/features/IE11.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11.js"; import testAssets from "./bundle.esm.js"; diff --git a/packages/fiori/package.json b/packages/fiori/package.json index 399b409a7204..c9e6d6d24f23 100644 --- a/packages/fiori/package.json +++ b/packages/fiori/package.json @@ -32,7 +32,7 @@ "dependencies": { "@ui5/webcomponents": "1.0.0-rc.11", "@ui5/webcomponents-base": "0.28.0", - "@ui5/webcomponents-compatibility": "0.28.0", + "@ui5/webcomponents-ie11": "0.28.0", "@ui5/webcomponents-icons": "1.0.0-rc.11", "@ui5/webcomponents-theme-base": "1.0.0-rc.11" }, diff --git a/packages/compatibility/.eslintignore b/packages/ie11/.eslintignore similarity index 100% rename from packages/compatibility/.eslintignore rename to packages/ie11/.eslintignore diff --git a/packages/compatibility/.npmrc b/packages/ie11/.npmrc similarity index 100% rename from packages/compatibility/.npmrc rename to packages/ie11/.npmrc diff --git a/packages/compatibility/README.md b/packages/ie11/README.md similarity index 82% rename from packages/compatibility/README.md rename to packages/ie11/README.md index f52e42c335ec..8d6580bbbbba 100644 --- a/packages/compatibility/README.md +++ b/packages/ie11/README.md @@ -1,13 +1,11 @@ ![UI5 icon](https://raw.githubusercontent.com/SAP/ui5-webcomponents/master/docs/images/UI5_logo_wide.png) -# UI5 Web Components - Compatibility +# UI5 Web Components - IE11 [![Travis CI Build Status](https://travis-ci.org/SAP/ui5-webcomponents.svg?branch=master)](https://travis-ci.org/SAP/ui5-webcomponents) [![npm Package Version](https://badge.fury.io/js/%40ui5%2Fwebcomponents.svg)](https://www.npmjs.com/package/@ui5/webcomponents) -Contains the base files for all Web Components, most notably `@ui5/webcomponents-base/dist/UI5Element.js`. - -For a complete list of all app development related public module imports from the `base` package, click [here](../../docs/Public%20Module%20Imports.md#base): +Contains polyfills and adapter code for Internet Explorer 11 ## Resources - [UI5 Web Components - README.md](https://github.com/SAP/ui5-webcomponents/blob/master/README.md) diff --git a/packages/compatibility/config/.eslintrc.js b/packages/ie11/config/.eslintrc.js similarity index 100% rename from packages/compatibility/config/.eslintrc.js rename to packages/ie11/config/.eslintrc.js diff --git a/packages/compatibility/package-scripts.js b/packages/ie11/package-scripts.js similarity index 62% rename from packages/compatibility/package-scripts.js rename to packages/ie11/package-scripts.js index 5f6b53f92884..733c947b81a9 100644 --- a/packages/compatibility/package-scripts.js +++ b/packages/ie11/package-scripts.js @@ -2,10 +2,9 @@ const scripts = { clean: "rimraf dist", lint: "eslint . --config config/.eslintrc.js", copy: `copy-and-watch "src/**/*.js" dist/`, - build: { - "default": "path-exists dist/ || nps build.all", - all: "nps lint clean copy", - }, + build: "nps lint clean copy", + watch: `nps "copy --watch --skip-initial-copy"`, + start: "nps watch", }; diff --git a/packages/compatibility/package.json b/packages/ie11/package.json similarity index 76% rename from packages/compatibility/package.json rename to packages/ie11/package.json index 1983dcfcfd1b..7e4aead27807 100644 --- a/packages/compatibility/package.json +++ b/packages/ie11/package.json @@ -1,7 +1,7 @@ { - "name": "@ui5/webcomponents-compatibility", + "name": "@ui5/webcomponents-ie11", "version": "0.28.0", - "description": "UI5 Web Components: webcomponents.compatibility", + "description": "UI5 Web Components: webcomponents.ie11", "author": "SAP SE (https://www.sap.com)", "license": "Apache-2.0", "module": "index.js", @@ -13,7 +13,7 @@ "repository": { "type": "git", "url": "https://github.com/SAP/ui5-webcomponents.git", - "directory": "packages/compatibility" + "directory": "packages/ie11" }, "scripts": { "clean": "nps clean", @@ -31,7 +31,6 @@ "@ui5/webcomponents-tools": "1.0.0-rc.11", "copy-and-watch": "^0.1.4", "eslint": "^5.13.0", - "eslint-config-airbnb-base": "^13.1.0", - "path-exists-cli": "^1.0.0" + "eslint-config-airbnb-base": "^13.1.0" } } diff --git a/packages/compatibility/src/DOMObserver.js b/packages/ie11/src/DOMObserver.js similarity index 100% rename from packages/compatibility/src/DOMObserver.js rename to packages/ie11/src/DOMObserver.js diff --git a/packages/compatibility/src/LegacyInterface.js b/packages/ie11/src/LegacyInterface.js similarity index 100% rename from packages/compatibility/src/LegacyInterface.js rename to packages/ie11/src/LegacyInterface.js diff --git a/packages/compatibility/src/features/IE11.js b/packages/ie11/src/features/IE11.js similarity index 81% rename from packages/compatibility/src/features/IE11.js rename to packages/ie11/src/features/IE11.js index d4cc880074e3..175bc9da2c51 100644 --- a/packages/compatibility/src/features/IE11.js +++ b/packages/ie11/src/features/IE11.js @@ -35,8 +35,15 @@ import "../thirdparty/fetch.js"; // async - await import "regenerator-runtime/runtime.js"; -// Plus all polyfills needed for Edge are also needed for IE11 -import "./Edge.js"; +// URLSearchParams +import "url-search-params-polyfill/index.js"; + +// "pseudo mutation observer" fix for nodeValue +import "../patchNodeValue.js"; + +// Register the "LegacyInterface" feature +import "../LegacyInterface.js"; + window.CSSVarsPonyfill = { cssVars, diff --git a/packages/compatibility/src/features/IE11WithWebComponentsPolyfill.js b/packages/ie11/src/features/IE11WithWebComponentsPolyfill.js similarity index 100% rename from packages/compatibility/src/features/IE11WithWebComponentsPolyfill.js rename to packages/ie11/src/features/IE11WithWebComponentsPolyfill.js diff --git a/packages/compatibility/src/patchNodeValue.js b/packages/ie11/src/patchNodeValue.js similarity index 100% rename from packages/compatibility/src/patchNodeValue.js rename to packages/ie11/src/patchNodeValue.js diff --git a/packages/compatibility/src/theming/CSSVarsPonyfill.js b/packages/ie11/src/theming/CSSVarsPonyfill.js similarity index 100% rename from packages/compatibility/src/theming/CSSVarsPonyfill.js rename to packages/ie11/src/theming/CSSVarsPonyfill.js diff --git a/packages/compatibility/src/theming/adaptCSSForIE.js b/packages/ie11/src/theming/adaptCSSForIE.js similarity index 100% rename from packages/compatibility/src/theming/adaptCSSForIE.js rename to packages/ie11/src/theming/adaptCSSForIE.js diff --git a/packages/compatibility/src/theming/createComponentStyleTag.js b/packages/ie11/src/theming/createComponentStyleTag.js similarity index 100% rename from packages/compatibility/src/theming/createComponentStyleTag.js rename to packages/ie11/src/theming/createComponentStyleTag.js diff --git a/packages/compatibility/src/thirdparty/Array.from.js b/packages/ie11/src/thirdparty/Array.from.js similarity index 100% rename from packages/compatibility/src/thirdparty/Array.from.js rename to packages/ie11/src/thirdparty/Array.from.js diff --git a/packages/compatibility/src/thirdparty/Array.prototype.fill.js b/packages/ie11/src/thirdparty/Array.prototype.fill.js similarity index 100% rename from packages/compatibility/src/thirdparty/Array.prototype.fill.js rename to packages/ie11/src/thirdparty/Array.prototype.fill.js diff --git a/packages/compatibility/src/thirdparty/Array.prototype.find.js b/packages/ie11/src/thirdparty/Array.prototype.find.js similarity index 100% rename from packages/compatibility/src/thirdparty/Array.prototype.find.js rename to packages/ie11/src/thirdparty/Array.prototype.find.js diff --git a/packages/compatibility/src/thirdparty/Array.prototype.findIndex.js b/packages/ie11/src/thirdparty/Array.prototype.findIndex.js similarity index 100% rename from packages/compatibility/src/thirdparty/Array.prototype.findIndex.js rename to packages/ie11/src/thirdparty/Array.prototype.findIndex.js diff --git a/packages/compatibility/src/thirdparty/Array.prototype.includes.js b/packages/ie11/src/thirdparty/Array.prototype.includes.js similarity index 100% rename from packages/compatibility/src/thirdparty/Array.prototype.includes.js rename to packages/ie11/src/thirdparty/Array.prototype.includes.js diff --git a/packages/compatibility/src/thirdparty/Element.prototype.closest.js b/packages/ie11/src/thirdparty/Element.prototype.closest.js similarity index 100% rename from packages/compatibility/src/thirdparty/Element.prototype.closest.js rename to packages/ie11/src/thirdparty/Element.prototype.closest.js diff --git a/packages/compatibility/src/thirdparty/Element.prototype.matches.js b/packages/ie11/src/thirdparty/Element.prototype.matches.js similarity index 100% rename from packages/compatibility/src/thirdparty/Element.prototype.matches.js rename to packages/ie11/src/thirdparty/Element.prototype.matches.js diff --git a/packages/compatibility/src/thirdparty/Map.prototype.keys.js b/packages/ie11/src/thirdparty/Map.prototype.keys.js similarity index 100% rename from packages/compatibility/src/thirdparty/Map.prototype.keys.js rename to packages/ie11/src/thirdparty/Map.prototype.keys.js diff --git a/packages/compatibility/src/thirdparty/Number.isInteger.js b/packages/ie11/src/thirdparty/Number.isInteger.js similarity index 100% rename from packages/compatibility/src/thirdparty/Number.isInteger.js rename to packages/ie11/src/thirdparty/Number.isInteger.js diff --git a/packages/compatibility/src/thirdparty/Number.isNaN.js b/packages/ie11/src/thirdparty/Number.isNaN.js similarity index 100% rename from packages/compatibility/src/thirdparty/Number.isNaN.js rename to packages/ie11/src/thirdparty/Number.isNaN.js diff --git a/packages/compatibility/src/thirdparty/Number.parseFloat.js b/packages/ie11/src/thirdparty/Number.parseFloat.js similarity index 100% rename from packages/compatibility/src/thirdparty/Number.parseFloat.js rename to packages/ie11/src/thirdparty/Number.parseFloat.js diff --git a/packages/compatibility/src/thirdparty/Number.parseInt.js b/packages/ie11/src/thirdparty/Number.parseInt.js similarity index 100% rename from packages/compatibility/src/thirdparty/Number.parseInt.js rename to packages/ie11/src/thirdparty/Number.parseInt.js diff --git a/packages/compatibility/src/thirdparty/Object.assign.js b/packages/ie11/src/thirdparty/Object.assign.js similarity index 100% rename from packages/compatibility/src/thirdparty/Object.assign.js rename to packages/ie11/src/thirdparty/Object.assign.js diff --git a/packages/compatibility/src/thirdparty/Object.entries.js b/packages/ie11/src/thirdparty/Object.entries.js similarity index 100% rename from packages/compatibility/src/thirdparty/Object.entries.js rename to packages/ie11/src/thirdparty/Object.entries.js diff --git a/packages/compatibility/src/thirdparty/Symbol.js b/packages/ie11/src/thirdparty/Symbol.js similarity index 100% rename from packages/compatibility/src/thirdparty/Symbol.js rename to packages/ie11/src/thirdparty/Symbol.js diff --git a/packages/compatibility/src/thirdparty/WeakSet.js b/packages/ie11/src/thirdparty/WeakSet.js similarity index 100% rename from packages/compatibility/src/thirdparty/WeakSet.js rename to packages/ie11/src/thirdparty/WeakSet.js diff --git a/packages/compatibility/src/thirdparty/es6-string-methods.js b/packages/ie11/src/thirdparty/es6-string-methods.js similarity index 100% rename from packages/compatibility/src/thirdparty/es6-string-methods.js rename to packages/ie11/src/thirdparty/es6-string-methods.js diff --git a/packages/compatibility/src/thirdparty/events-polyfills.js b/packages/ie11/src/thirdparty/events-polyfills.js similarity index 100% rename from packages/compatibility/src/thirdparty/events-polyfills.js rename to packages/ie11/src/thirdparty/events-polyfills.js diff --git a/packages/compatibility/src/thirdparty/fetch.js b/packages/ie11/src/thirdparty/fetch.js similarity index 100% rename from packages/compatibility/src/thirdparty/fetch.js rename to packages/ie11/src/thirdparty/fetch.js diff --git a/packages/compatibility/src/thirdparty/template.js b/packages/ie11/src/thirdparty/template.js similarity index 100% rename from packages/compatibility/src/thirdparty/template.js rename to packages/ie11/src/thirdparty/template.js diff --git a/packages/compatibility/src/thirdparty/webcomponents-sd-ce-pf.js b/packages/ie11/src/thirdparty/webcomponents-sd-ce-pf.js similarity index 100% rename from packages/compatibility/src/thirdparty/webcomponents-sd-ce-pf.js rename to packages/ie11/src/thirdparty/webcomponents-sd-ce-pf.js diff --git a/packages/compatibility/src/whenPolyfillLoaded.js b/packages/ie11/src/whenPolyfillLoaded.js similarity index 100% rename from packages/compatibility/src/whenPolyfillLoaded.js rename to packages/ie11/src/whenPolyfillLoaded.js diff --git a/packages/main/bundle.es5.js b/packages/main/bundle.es5.js index 2e6f837f5d34..3e9631ac0a03 100644 --- a/packages/main/bundle.es5.js +++ b/packages/main/bundle.es5.js @@ -1,5 +1,5 @@ // ES5 bundle targets IE11 only -import "@ui5/webcomponents-compatibility/dist/features/IE11.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11.js"; import testAssets from "./bundle.esm.js"; diff --git a/packages/main/package.json b/packages/main/package.json index 53d33e972886..ace0ebdf11e0 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@ui5/webcomponents-base": "0.28.0", - "@ui5/webcomponents-compatibility": "0.28.0", + "@ui5/webcomponents-ie11": "0.28.0", "@ui5/webcomponents-icons": "1.0.0-rc.11", "@ui5/webcomponents-localization": "0.28.0", "@ui5/webcomponents-theme-base": "1.0.0-rc.11" diff --git a/packages/tools/lib/init-package/resources/bundle.es5.js b/packages/tools/lib/init-package/resources/bundle.es5.js index cf9add11e587..0162b9b937af 100644 --- a/packages/tools/lib/init-package/resources/bundle.es5.js +++ b/packages/tools/lib/init-package/resources/bundle.es5.js @@ -1,5 +1,5 @@ // ES5 bundle targets IE11 only -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11.js"; import "./bundle.esm.js"; diff --git a/packages/tools/lib/init-package/resources/bundle.esm.js b/packages/tools/lib/init-package/resources/bundle.esm.js index 2c0aff7a773e..31e763be8c8f 100644 --- a/packages/tools/lib/init-package/resources/bundle.esm.js +++ b/packages/tools/lib/init-package/resources/bundle.esm.js @@ -1,6 +1,3 @@ -// ESM bundle targets Edge + browsers with native support -import "@ui5/webcomponents-base/dist/features/browsersupport/Edge.js"; - // used in test pages import RenderScheduler from "@ui5/webcomponents-base/dist/RenderScheduler.js"; From b0d3772b459149103648915c2b824e87b4ff184f Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Mon, 18 Jan 2021 12:14:10 +0200 Subject: [PATCH 09/19] rework DOMObserver & docs --- packages/base/src/DOMObserver.js | 43 +++++++++++----------- packages/base/src/LegacyBrowsersAdapter.js | 6 ++- packages/base/src/UI5Element.js | 13 +++++-- packages/ie11/README.md | 13 +++++++ packages/ie11/src/DOMObserver.js | 38 +++++++++---------- packages/ie11/src/LegacyInterface.js | 5 ++- 6 files changed, 67 insertions(+), 51 deletions(-) diff --git a/packages/base/src/DOMObserver.js b/packages/base/src/DOMObserver.js index b8be8c9ed0f0..457d7cee03d7 100644 --- a/packages/base/src/DOMObserver.js +++ b/packages/base/src/DOMObserver.js @@ -1,29 +1,28 @@ const observers = new WeakMap(); -class DOMObserver { - /** - * @param node - * @param callback - * @param options - */ - static observeDOMNode(node, callback, options) { - const observerObject = new MutationObserver(callback); - observerObject.observe(node, options); - observers.set(node, observerObject); - } - - /** - * @param node - */ - static unobserveDOMNode(node) { - const observerObject = observers.get(node); - if (!observerObject) { - return; - } +/** + * @param node + * @param callback + * @param options + */ +const observeDOMNode = (node, callback, options) => { + const observerObject = new MutationObserver(callback); + observerObject.observe(node, options); + observers.set(node, observerObject); +}; +/** + * @param node + */ +const unobserveDOMNode = node => { + const observerObject = observers.get(node); + if (observerObject) { observerObject.disconnect(); observers.delete(node); } -} +}; -export default DOMObserver; +export { + observeDOMNode, + unobserveDOMNode, +}; diff --git a/packages/base/src/LegacyBrowsersAdapter.js b/packages/base/src/LegacyBrowsersAdapter.js index e1102a35c1ef..7f19218601aa 100644 --- a/packages/base/src/LegacyBrowsersAdapter.js +++ b/packages/base/src/LegacyBrowsersAdapter.js @@ -6,15 +6,17 @@ const emptyFn = () => undefined; const falsyFn = () => false; const isLegacyBrowser = LegacyInterface ? LegacyInterface.isLegacyBrowser : falsyFn; -const LegacyDOMObserver = LegacyInterface ? LegacyInterface.DOMObserver : undefined; const onLegacyBoot = LegacyInterface ? LegacyInterface.onBoot : emptyFn; const onLegacyApplyTheme = LegacyInterface ? LegacyInterface.onApplyTheme : emptyFn; const onLegacyComponentRender = LegacyInterface ? LegacyInterface.onComponentRender : emptyFn; +const legacyObserveDOMNode = LegacyInterface ? LegacyInterface.observeDOMNode : undefined; +const legacyUnobserveDOMNode = LegacyInterface ? LegacyInterface.unobserveDOMNode : undefined; export { isLegacyBrowser, - LegacyDOMObserver, onLegacyBoot, onLegacyApplyTheme, onLegacyComponentRender, + legacyObserveDOMNode, + legacyUnobserveDOMNode, }; diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index 94a7fa3a1ae1..45866b96c646 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -6,7 +6,7 @@ import executeTemplate from "./renderer/executeTemplate.js"; import StaticAreaItem from "./StaticAreaItem.js"; import RenderScheduler from "./RenderScheduler.js"; import { registerTag, isTagRegistered, recordTagRegistrationFailure } from "./CustomElementsRegistry.js"; -import DOMObserver from "./DOMObserver.js"; +import { observeDOMNode, unobserveDOMNode } from "./DOMObserver.js"; import { skipOriginalEvent } from "./config/NoConflict.js"; import { getRTL } from "./config/RTL.js"; import getConstructableStyle from "./theming/getConstructableStyle.js"; @@ -18,7 +18,12 @@ import isValidPropertyName from "./util/isValidPropertyName.js"; import isSlot from "./util/isSlot.js"; import arraysAreEqual from "./util/arraysAreEqual.js"; import { markAsRtlAware } from "./locale/RTLAwareRegistry.js"; -import { isLegacyBrowser, LegacyDOMObserver, onLegacyComponentRender } from "./LegacyBrowsersAdapter.js"; +import { + isLegacyBrowser, + onLegacyComponentRender, + legacyObserveDOMNode, + legacyUnobserveDOMNode, +} from "./LegacyBrowsersAdapter.js"; let autoId = 0; @@ -195,14 +200,14 @@ class UI5Element extends HTMLElement { subtree: canSlotText, characterData: canSlotText, }; - (LegacyDOMObserver || DOMObserver).observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); + (legacyObserveDOMNode || observeDOMNode)(this, this._processChildren.bind(this), mutationObserverOptions); } /** * @private */ _stopObservingDOMChildren() { - (LegacyDOMObserver || DOMObserver).unobserveDOMNode(this); + (legacyUnobserveDOMNode || unobserveDOMNode)(this); } /** diff --git a/packages/ie11/README.md b/packages/ie11/README.md index 8d6580bbbbba..7672a6b78671 100644 --- a/packages/ie11/README.md +++ b/packages/ie11/README.md @@ -7,6 +7,19 @@ Contains polyfills and adapter code for Internet Explorer 11 +This package exposes an interface for seamlessly integrating Internet Explorer 11 support into the other packages. +It registers a feature called `LegacyInterface`. This features is transparently registered if the application imported one of: + - `import "@ui5/webcomponents-ie11/dist/features/IE11.js";` + - `import "@ui5/webcomponents-ie11/dist/features/IE11WithWebComponentsPolyfill.js";` + +The `LegacyInterface` feature provides an object with the following functions: + - `isLegacyBrowser`: tells if IE11 is the current runtime (if ShadyDOM is used) + - `onBoot`: (`async`) await for this hook once, when the framework boots + - `onApplyTheme`: call this hook once per theme change + - `onComponentRender`: call this hook once per component render + - `observeDOMNode`: call this function to track a DOM node for changes + - `unobserveDOMNode`: call this function to stop tracking a DOM node for changes + ## Resources - [UI5 Web Components - README.md](https://github.com/SAP/ui5-webcomponents/blob/master/README.md) - [UI5 Web Components - Home Page](https://sap.github.io/ui5-webcomponents) diff --git a/packages/ie11/src/DOMObserver.js b/packages/ie11/src/DOMObserver.js index 4ef8197376a4..17a0d9575e41 100644 --- a/packages/ie11/src/DOMObserver.js +++ b/packages/ie11/src/DOMObserver.js @@ -2,30 +2,26 @@ const observers = new WeakMap(); /** - * Implements universal DOM node observation methods. + * @param node + * @param callback */ -class DOMObserver { - /** - * @param node - * @param callback - */ - static observeDOMNode(node, callback) { - const observerObject = window.ShadyDOM.observeChildren(node, callback); - observers.set(node, observerObject); - } - - /** - * @param node - */ - static unobserveDOMNode(node) { - const observerObject = observers.get(node); - if (!observerObject) { - return; - } +const observeDOMNode = (node, callback) => { + const observerObject = window.ShadyDOM.observeChildren(node, callback); + observers.set(node, observerObject); +}; +/** + * @param node + */ +const unobserveDOMNode = node => { + const observerObject = observers.get(node); + if (observerObject) { window.ShadyDOM.unobserveChildren(observerObject); observers.delete(node); } -} +}; -export default DOMObserver; +export { + observeDOMNode, + unobserveDOMNode, +}; diff --git a/packages/ie11/src/LegacyInterface.js b/packages/ie11/src/LegacyInterface.js index 6486e6180d69..45e2eb47f588 100644 --- a/packages/ie11/src/LegacyInterface.js +++ b/packages/ie11/src/LegacyInterface.js @@ -1,6 +1,6 @@ import { registerFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; -import DOMObserver from "./DOMObserver.js"; +import { observeDOMNode, unobserveDOMNode } from "./DOMObserver.js"; import createComponentStyleTag from "./theming/createComponentStyleTag.js"; import { runPonyfill } from "./theming/CSSVarsPonyfill.js"; @@ -29,8 +29,9 @@ const onComponentRender = component => { registerFeature("LegacyInterface", { isLegacyBrowser, - DOMObserver, onBoot, onApplyTheme, onComponentRender, + observeDOMNode, + unobserveDOMNode, }); From 3c7755cf88c8742a3778445ce95f6a7c1f2ac745 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Mon, 18 Jan 2021 13:37:30 +0200 Subject: [PATCH 10/19] rename --- .../Creating UI5 Web Components Packages.md | 2 +- packages/main/src/Button.js | 4 ++-- packages/main/src/ToggleButton.js | 4 ++-- .../{Button.legacy.css => Button.ie11.css} | 0 packages/main/src/themes/ToggleButton.css | 22 ------------------- ...utton.legacy.css => ToggleButton.ie11.css} | 20 +++++++++++++++++ 6 files changed, 25 insertions(+), 27 deletions(-) rename packages/main/src/themes/{Button.legacy.css => Button.ie11.css} (100%) rename packages/main/src/themes/{ToggleButton.legacy.css => ToggleButton.ie11.css} (65%) diff --git a/docs/dev/Creating UI5 Web Components Packages.md b/docs/dev/Creating UI5 Web Components Packages.md index e54d44e0540e..f480bf689b91 100644 --- a/docs/dev/Creating UI5 Web Components Packages.md +++ b/docs/dev/Creating UI5 Web Components Packages.md @@ -20,7 +20,7 @@ The name that you give to your package will be used by the UI5 Web Components to ## Step 2 - add the UI5 Web Components packages as dependencies With `npm`: - - `npm i --save @ui5/webcomponents-base @ui5/webcomponents-theme-base @ui5/webcomponents-tools @ui5/webcomponents-ie11` + - `npm i --save @ui5/webcomponents-base @ui5/webcomponents-theme-base @ui5/webcomponents-tools` - `npm i --save-dev chromedriver` - (Optional) `npm i --save @ui5/webcomponents-ie11` diff --git a/packages/main/src/Button.js b/packages/main/src/Button.js index 028214b3eb21..160fbc4568e4 100644 --- a/packages/main/src/Button.js +++ b/packages/main/src/Button.js @@ -13,7 +13,7 @@ import { BUTTON_ARIA_TYPE_ACCEPT, BUTTON_ARIA_TYPE_REJECT, BUTTON_ARIA_TYPE_EMPH // Styles import buttonCss from "./generated/themes/Button.css.js"; -import buttonLegacyCss from "./generated/themes/Button.legacy.css.js"; +import buttonIECss from "./generated/themes/Button.ie11.css.js"; let isGlobalHandlerAttached = false; let activeButton = null; @@ -288,7 +288,7 @@ class Button extends UI5Element { } static get styles() { - return [buttonCss, isLegacyBrowser() ? buttonLegacyCss : undefined]; + return [buttonCss, isLegacyBrowser() ? buttonIECss : undefined]; } static get render() { diff --git a/packages/main/src/ToggleButton.js b/packages/main/src/ToggleButton.js index fd4b636cd698..43b148e3f923 100644 --- a/packages/main/src/ToggleButton.js +++ b/packages/main/src/ToggleButton.js @@ -4,7 +4,7 @@ import ToggleButtonTemplate from "./generated/templates/ToggleButtonTemplate.lit // Styles import toggleBtnCss from "./generated/themes/ToggleButton.css.js"; -import toggleBtnLegacyCss from "./generated/themes/ToggleButton.legacy.css.js"; +import toggleBtnIECss from "./generated/themes/ToggleButton.ie11.css.js"; /** * @public @@ -60,7 +60,7 @@ class ToggleButton extends Button { } static get styles() { - return [Button.styles, toggleBtnCss, isLegacyBrowser() ? toggleBtnLegacyCss : undefined]; + return [Button.styles, toggleBtnCss, isLegacyBrowser() ? toggleBtnIECss : undefined]; } _onclick() { diff --git a/packages/main/src/themes/Button.legacy.css b/packages/main/src/themes/Button.ie11.css similarity index 100% rename from packages/main/src/themes/Button.legacy.css rename to packages/main/src/themes/Button.ie11.css diff --git a/packages/main/src/themes/ToggleButton.css b/packages/main/src/themes/ToggleButton.css index 6d5121d84a94..0a1725064bbb 100644 --- a/packages/main/src/themes/ToggleButton.css +++ b/packages/main/src/themes/ToggleButton.css @@ -53,25 +53,3 @@ :host([pressed]:hover) { background: var(--sapButton_Selected_Hover_Background); } - -/* IE Specific CSS, duplicate it for ToggleButton */ - -[ui5-togglebutton][focused] { - outline: none; -} - -[ui5-togglebutton][focused] .ui5-button-root { - position: relative; -} - -[ui5-togglebutton][focused] .ui5-button-root::after { - content: ""; - position: absolute; - border-width: 1px; - border-style: dotted; - border-color: var(--_ui5_button_focus_color); - top: var(--_ui5_button_focus_offset); - bottom: var(--_ui5_button_focus_offset); - left: var(--_ui5_button_focus_offset); - right: var(--_ui5_button_focus_offset); -} diff --git a/packages/main/src/themes/ToggleButton.legacy.css b/packages/main/src/themes/ToggleButton.ie11.css similarity index 65% rename from packages/main/src/themes/ToggleButton.legacy.css rename to packages/main/src/themes/ToggleButton.ie11.css index 3bb26152fc70..8adfe5c9d819 100644 --- a/packages/main/src/themes/ToggleButton.legacy.css +++ b/packages/main/src/themes/ToggleButton.ie11.css @@ -1,3 +1,23 @@ +[ui5-togglebutton][focused] { + outline: none; +} + +[ui5-togglebutton][focused] .ui5-button-root { + position: relative; +} + +[ui5-togglebutton][focused] .ui5-button-root::after { + content: ""; + position: absolute; + border-width: 1px; + border-style: dotted; + border-color: var(--_ui5_button_focus_color); + top: var(--_ui5_button_focus_offset); + bottom: var(--_ui5_button_focus_offset); + left: var(--_ui5_button_focus_offset); + right: var(--_ui5_button_focus_offset); +} + [ui5-togglebutton][active] .ui5-button-root::after { border-color: var(--sapContent_ContrastFocusColor); } From d8deb4756aa2de9882aa097d1b40e6f136f5602d Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Mon, 18 Jan 2021 16:01:29 +0200 Subject: [PATCH 11/19] rework with publish/subscribe --- packages/base/src/{boot.js => Boot.js} | 30 +++++++++++++-- packages/base/src/DOMObserver.js | 37 ++++++++++++++++--- packages/base/src/LegacyBrowsersAdapter.js | 22 ----------- packages/base/src/RenderScheduler.js | 13 ++++++- packages/base/src/StaticAreaItem.js | 4 +- packages/base/src/UI5Element.js | 16 +++----- packages/base/src/hasNativeSupport.js | 5 +++ packages/base/src/theming/ThemeLoaded.js | 16 ++++++++ packages/base/src/theming/applyTheme.js | 5 +-- packages/ie11/README.md | 13 +------ packages/ie11/src/DOMObserver.js | 27 -------------- packages/ie11/src/LegacyInterface.js | 37 ------------------- packages/ie11/src/features/IE11.js | 4 +- packages/ie11/src/integrate.js | 22 +++++++++++ .../src/theming/createComponentStyleTag.js | 14 ++++--- packages/main/src/Button.js | 4 +- packages/main/src/Icon.js | 6 +-- packages/main/src/ToggleButton.js | 4 +- 18 files changed, 141 insertions(+), 138 deletions(-) rename packages/base/src/{boot.js => Boot.js} (54%) delete mode 100644 packages/base/src/LegacyBrowsersAdapter.js create mode 100644 packages/base/src/hasNativeSupport.js delete mode 100644 packages/ie11/src/DOMObserver.js delete mode 100644 packages/ie11/src/LegacyInterface.js create mode 100644 packages/ie11/src/integrate.js diff --git a/packages/base/src/boot.js b/packages/base/src/Boot.js similarity index 54% rename from packages/base/src/boot.js rename to packages/base/src/Boot.js index 94d3e8d1532c..d1cb1b15a6cd 100644 --- a/packages/base/src/boot.js +++ b/packages/base/src/Boot.js @@ -1,12 +1,32 @@ +import EventProvider from "./EventProvider.js"; import whenDOMReady from "./util/whenDOMReady.js"; import insertFontFace from "./FontFace.js"; import insertSystemCSSVars from "./SystemCSSVars.js"; import { getTheme } from "./config/Theme.js"; import applyTheme from "./theming/applyTheme.js"; import { getFeature } from "./FeaturesRegistry.js"; -import { onLegacyBoot } from "./LegacyBrowsersAdapter.js"; let bootPromise; +const eventProvider = new EventProvider(); + +/** + * Attach a callback that will be executed before the framework has booted + * @public + * @param listener + */ +const attachBeforeBoot = listener => { + eventProvider.attachEvent("beforeBoot", listener); +}; + +/** + * Detach a callback that was passed with "attachBeforeBoot" + * @public + * @param listener + */ +const detachBeforeBoot = listener => { + eventProvider.detachEvent("beforeBoot", listener); +}; + const boot = () => { if (bootPromise) { @@ -24,7 +44,7 @@ const boot = () => { OpenUI5Support && OpenUI5Support.attachListeners(); insertFontFace(); insertSystemCSSVars(); - await onLegacyBoot(); + await Promise.all(eventProvider.fireEvent("beforeBoot")); resolve(); }); @@ -32,4 +52,8 @@ const boot = () => { return bootPromise; }; -export default boot; +export { + boot, + attachBeforeBoot, + detachBeforeBoot, +}; diff --git a/packages/base/src/DOMObserver.js b/packages/base/src/DOMObserver.js index 457d7cee03d7..2e21e2866b92 100644 --- a/packages/base/src/DOMObserver.js +++ b/packages/base/src/DOMObserver.js @@ -1,28 +1,53 @@ const observers = new WeakMap(); +/** + * Default implementation with MutationObserver for browsers with native support + */ +let _createObserver = (node, callback, options) => { + const observer = new MutationObserver(callback); + observer.observe(node, options); + return observer; +}; + +/** + * Default implementation with MutationObserver for browsers with native support + */ +let _destroyObserver = observer => { + observer.disconnect(); +}; + +const setCreateObserverCallback = createFn => { + _createObserver = createFn; +}; + +const setDestroyObserverCallback = destroyFn => { + _destroyObserver = destroyFn; +}; + /** * @param node * @param callback * @param options */ const observeDOMNode = (node, callback, options) => { - const observerObject = new MutationObserver(callback); - observerObject.observe(node, options); - observers.set(node, observerObject); + const observer = _createObserver(node, callback, options); + observers.set(node, observer); }; /** * @param node */ const unobserveDOMNode = node => { - const observerObject = observers.get(node); - if (observerObject) { - observerObject.disconnect(); + const observer = observers.get(node); + if (observer) { + _destroyObserver(observer); observers.delete(node); } }; export { + setCreateObserverCallback, + setDestroyObserverCallback, observeDOMNode, unobserveDOMNode, }; diff --git a/packages/base/src/LegacyBrowsersAdapter.js b/packages/base/src/LegacyBrowsersAdapter.js deleted file mode 100644 index 7f19218601aa..000000000000 --- a/packages/base/src/LegacyBrowsersAdapter.js +++ /dev/null @@ -1,22 +0,0 @@ -import { getFeature } from "./FeaturesRegistry.js"; - -const LegacyInterface = getFeature("LegacyInterface"); - -const emptyFn = () => undefined; -const falsyFn = () => false; - -const isLegacyBrowser = LegacyInterface ? LegacyInterface.isLegacyBrowser : falsyFn; -const onLegacyBoot = LegacyInterface ? LegacyInterface.onBoot : emptyFn; -const onLegacyApplyTheme = LegacyInterface ? LegacyInterface.onApplyTheme : emptyFn; -const onLegacyComponentRender = LegacyInterface ? LegacyInterface.onComponentRender : emptyFn; -const legacyObserveDOMNode = LegacyInterface ? LegacyInterface.observeDOMNode : undefined; -const legacyUnobserveDOMNode = LegacyInterface ? LegacyInterface.unobserveDOMNode : undefined; - -export { - isLegacyBrowser, - onLegacyBoot, - onLegacyApplyTheme, - onLegacyComponentRender, - legacyObserveDOMNode, - legacyUnobserveDOMNode, -}; diff --git a/packages/base/src/RenderScheduler.js b/packages/base/src/RenderScheduler.js index d8b827e0c6e9..d111281273cb 100644 --- a/packages/base/src/RenderScheduler.js +++ b/packages/base/src/RenderScheduler.js @@ -1,8 +1,10 @@ +import EventProvider from "./EventProvider.js"; import RenderQueue from "./RenderQueue.js"; import { getAllRegisteredTags } from "./CustomElementsRegistry.js"; import { isRtlAware } from "./locale/RTLAwareRegistry.js"; const registeredElements = new Set(); +const eventProvider = new EventProvider(); // Queue for invalidated web components const invalidatedWebComponents = new RenderQueue(); @@ -43,6 +45,7 @@ class RenderScheduler { * @param webComponent */ static renderImmediately(webComponent) { + eventProvider.fireEvent("beforeComponentRender", webComponent); webComponent._render(); } @@ -65,7 +68,7 @@ class RenderScheduler { // Render all components in the queue // console.log(`--------------------RENDER TASK START------------------------------`); // eslint-disable-line - invalidatedWebComponents.process(component => component._render()); + invalidatedWebComponents.process(RenderScheduler.renderImmediately); // console.log(`--------------------RENDER TASK END------------------------------`); // eslint-disable-line // Resolve the promise so that callers of renderDeferred can continue @@ -164,6 +167,14 @@ class RenderScheduler { } }); } + + static attachBeforeComponentRender(listener) { + eventProvider.attachEvent("beforeComponentRender", listener); + } + + static detachBeforeComponentRender(listener) { + eventProvider.detachEvent("beforeComponentRender", listener); + } } export default RenderScheduler; diff --git a/packages/base/src/StaticAreaItem.js b/packages/base/src/StaticAreaItem.js index 8e0d9b501a29..03f18cf2c3fb 100644 --- a/packages/base/src/StaticAreaItem.js +++ b/packages/base/src/StaticAreaItem.js @@ -2,7 +2,7 @@ import { getStaticAreaInstance, removeStaticArea } from "./StaticArea.js"; import RenderScheduler from "./RenderScheduler.js"; import getEffectiveStyle from "./theming/getEffectiveStyle.js"; import executeTemplate from "./renderer/executeTemplate.js"; -import { isLegacyBrowser } from "./LegacyBrowsersAdapter.js"; +import hasNativeSupport from "./hasNativeSupport.js"; import getConstructableStyle from "./theming/getConstructableStyle.js"; /** @@ -47,7 +47,7 @@ class StaticAreaItem { if (document.adoptedStyleSheets) { // Chrome this.staticAreaItemDomRef.shadowRoot.adoptedStyleSheets = getConstructableStyle(this.ui5ElementContext.constructor, true); - } else if (!isLegacyBrowser()) { // FF, Safari + } else if (hasNativeSupport()) { // FF, Safari stylesToPrepend = getEffectiveStyle(this.ui5ElementContext.constructor, true); } diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index 45866b96c646..f7b6d74e0cab 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -1,5 +1,5 @@ import merge from "./thirdparty/merge.js"; -import boot from "./boot.js"; +import { boot } from "./Boot.js"; import UI5ElementMetadata from "./UI5ElementMetadata.js"; import EventProvider from "./EventProvider.js"; import executeTemplate from "./renderer/executeTemplate.js"; @@ -18,12 +18,7 @@ import isValidPropertyName from "./util/isValidPropertyName.js"; import isSlot from "./util/isSlot.js"; import arraysAreEqual from "./util/arraysAreEqual.js"; import { markAsRtlAware } from "./locale/RTLAwareRegistry.js"; -import { - isLegacyBrowser, - onLegacyComponentRender, - legacyObserveDOMNode, - legacyUnobserveDOMNode, -} from "./LegacyBrowsersAdapter.js"; +import hasNativeSupport from "./hasNativeSupport.js"; let autoId = 0; @@ -200,14 +195,14 @@ class UI5Element extends HTMLElement { subtree: canSlotText, characterData: canSlotText, }; - (legacyObserveDOMNode || observeDOMNode)(this, this._processChildren.bind(this), mutationObserverOptions); + observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions); } /** * @private */ _stopObservingDOMChildren() { - (legacyUnobserveDOMNode || unobserveDOMNode)(this); + unobserveDOMNode(this); } /** @@ -604,7 +599,6 @@ class UI5Element extends HTMLElement { this._changedState = []; // Update shadow root and static area item - onLegacyComponentRender(this); if (this.constructor._needsShadowDOM()) { this._updateShadowRoot(); } @@ -633,7 +627,7 @@ class UI5Element extends HTMLElement { if (document.adoptedStyleSheets) { // Chrome this.shadowRoot.adoptedStyleSheets = getConstructableStyle(this.constructor); - } else if (!isLegacyBrowser()) { // FF, Safari + } else if (hasNativeSupport()) { // FF, Safari styleToPrepend = getEffectiveStyle(this.constructor); } diff --git a/packages/base/src/hasNativeSupport.js b/packages/base/src/hasNativeSupport.js new file mode 100644 index 000000000000..d4253abad55c --- /dev/null +++ b/packages/base/src/hasNativeSupport.js @@ -0,0 +1,5 @@ +const hasNativeSupport = () => { + return !window.ShadyDOM; +}; + +export default hasNativeSupport; diff --git a/packages/base/src/theming/ThemeLoaded.js b/packages/base/src/theming/ThemeLoaded.js index 937ab3f72117..71c38f036a52 100644 --- a/packages/base/src/theming/ThemeLoaded.js +++ b/packages/base/src/theming/ThemeLoaded.js @@ -2,6 +2,7 @@ import EventProvider from "../EventProvider.js"; const eventProvider = new EventProvider(); const THEME_LOADED = "themeLoaded"; +const BEFORE_THEME_LOADED = "beforeThemeLoaded"; const attachThemeLoaded = listener => { eventProvider.attachEvent(THEME_LOADED, listener); @@ -15,8 +16,23 @@ const fireThemeLoaded = theme => { return eventProvider.fireEvent(THEME_LOADED, theme); }; +const attachBeforeThemeLoaded = listener => { + eventProvider.attachEvent(BEFORE_THEME_LOADED, listener); +}; + +const detachBeforeThemeLoaded = listener => { + eventProvider.detachEvent(BEFORE_THEME_LOADED, listener); +}; + +const fireBeforeThemeLoaded = theme => { + return eventProvider.fireEvent(BEFORE_THEME_LOADED, theme); +}; + export { attachThemeLoaded, detachThemeLoaded, fireThemeLoaded, + attachBeforeThemeLoaded, + detachBeforeThemeLoaded, + fireBeforeThemeLoaded, }; diff --git a/packages/base/src/theming/applyTheme.js b/packages/base/src/theming/applyTheme.js index ca65ef6ccb28..d200153dc46f 100644 --- a/packages/base/src/theming/applyTheme.js +++ b/packages/base/src/theming/applyTheme.js @@ -1,9 +1,8 @@ import { getThemeProperties, getRegisteredPackages, isThemeRegistered } from "../asset-registries/Themes.js"; import createThemePropertiesStyleTag from "./createThemePropertiesStyleTag.js"; import getThemeDesignerTheme from "./getThemeDesignerTheme.js"; -import { fireThemeLoaded } from "./ThemeLoaded.js"; +import { fireThemeLoaded, fireBeforeThemeLoaded } from "./ThemeLoaded.js"; import { getFeature } from "../FeaturesRegistry.js"; -import { onLegacyApplyTheme } from "../LegacyBrowsersAdapter.js"; const BASE_THEME_PACKAGE = "@ui5/webcomponents-theme-base"; @@ -73,7 +72,7 @@ const applyTheme = async theme => { const packagesTheme = isThemeRegistered(theme) ? theme : extTheme && extTheme.baseThemeName; await loadComponentPackages(packagesTheme); - onLegacyApplyTheme(); + fireBeforeThemeLoaded(theme); fireThemeLoaded(theme); }; diff --git a/packages/ie11/README.md b/packages/ie11/README.md index 7672a6b78671..7c5cc93fb4c2 100644 --- a/packages/ie11/README.md +++ b/packages/ie11/README.md @@ -7,19 +7,10 @@ Contains polyfills and adapter code for Internet Explorer 11 -This package exposes an interface for seamlessly integrating Internet Explorer 11 support into the other packages. -It registers a feature called `LegacyInterface`. This features is transparently registered if the application imported one of: +This package transparently integrates Internet Explorer 11 support whenever any of these features is imported: - `import "@ui5/webcomponents-ie11/dist/features/IE11.js";` - `import "@ui5/webcomponents-ie11/dist/features/IE11WithWebComponentsPolyfill.js";` - -The `LegacyInterface` feature provides an object with the following functions: - - `isLegacyBrowser`: tells if IE11 is the current runtime (if ShadyDOM is used) - - `onBoot`: (`async`) await for this hook once, when the framework boots - - `onApplyTheme`: call this hook once per theme change - - `onComponentRender`: call this hook once per component render - - `observeDOMNode`: call this function to track a DOM node for changes - - `unobserveDOMNode`: call this function to stop tracking a DOM node for changes - + ## Resources - [UI5 Web Components - README.md](https://github.com/SAP/ui5-webcomponents/blob/master/README.md) - [UI5 Web Components - Home Page](https://sap.github.io/ui5-webcomponents) diff --git a/packages/ie11/src/DOMObserver.js b/packages/ie11/src/DOMObserver.js deleted file mode 100644 index 17a0d9575e41..000000000000 --- a/packages/ie11/src/DOMObserver.js +++ /dev/null @@ -1,27 +0,0 @@ -// Map of observer objects per dom node -const observers = new WeakMap(); - -/** - * @param node - * @param callback - */ -const observeDOMNode = (node, callback) => { - const observerObject = window.ShadyDOM.observeChildren(node, callback); - observers.set(node, observerObject); -}; - -/** - * @param node - */ -const unobserveDOMNode = node => { - const observerObject = observers.get(node); - if (observerObject) { - window.ShadyDOM.unobserveChildren(observerObject); - observers.delete(node); - } -}; - -export { - observeDOMNode, - unobserveDOMNode, -}; diff --git a/packages/ie11/src/LegacyInterface.js b/packages/ie11/src/LegacyInterface.js deleted file mode 100644 index 45e2eb47f588..000000000000 --- a/packages/ie11/src/LegacyInterface.js +++ /dev/null @@ -1,37 +0,0 @@ -import { registerFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; -import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; -import { observeDOMNode, unobserveDOMNode } from "./DOMObserver.js"; -import createComponentStyleTag from "./theming/createComponentStyleTag.js"; -import { runPonyfill } from "./theming/CSSVarsPonyfill.js"; - -const isLegacyBrowser = () => !!window.ShadyDOM; - -// Executed once on boot -const onBoot = async () => { - await (isLegacyBrowser() ? whenPolyfillLoaded() : Promise.resolve()); -}; - -// Executed on each theme application -const onApplyTheme = () => { - isLegacyBrowser() && runPonyfill(); -}; - -// Executed on each component render -const onComponentRender = component => { - if (!isLegacyBrowser()) { - return; - } - - if (component.constructor._needsShadowDOM() || component.constructor._needsStaticArea()) { - createComponentStyleTag(component.constructor); - } -}; - -registerFeature("LegacyInterface", { - isLegacyBrowser, - onBoot, - onApplyTheme, - onComponentRender, - observeDOMNode, - unobserveDOMNode, -}); diff --git a/packages/ie11/src/features/IE11.js b/packages/ie11/src/features/IE11.js index 175bc9da2c51..ec329cacfd1e 100644 --- a/packages/ie11/src/features/IE11.js +++ b/packages/ie11/src/features/IE11.js @@ -41,8 +41,8 @@ import "url-search-params-polyfill/index.js"; // "pseudo mutation observer" fix for nodeValue import "../patchNodeValue.js"; -// Register the "LegacyInterface" feature -import "../LegacyInterface.js"; +// Hook with the framework +import "../integrate.js"; window.CSSVarsPonyfill = { diff --git a/packages/ie11/src/integrate.js b/packages/ie11/src/integrate.js new file mode 100644 index 000000000000..a5e3f6537f57 --- /dev/null +++ b/packages/ie11/src/integrate.js @@ -0,0 +1,22 @@ +import { attachBeforeBoot } from "@ui5/webcomponents-base/dist/Boot.js"; +import { attachBeforeThemeLoaded } from "@ui5/webcomponents-base/dist/theming/ThemeLoaded.js"; +import RenderScheduler from "@ui5/webcomponents-base/dist/RenderScheduler.js"; +import { setCreateObserverCallback, setDestroyObserverCallback } from "@ui5/webcomponents-base/dist/DOMObserver.js"; +import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; +import createComponentStyleTag from "./theming/createComponentStyleTag.js"; +import { runPonyfill } from "./theming/CSSVarsPonyfill.js"; + +// Execute once on boot +attachBeforeBoot(whenPolyfillLoaded); + +// Execute on each theme application +attachBeforeThemeLoaded(runPonyfill); + +// Execute on each component render +RenderScheduler.attachBeforeComponentRender(createComponentStyleTag); + +// Set the custom observer implementation for observe +setCreateObserverCallback(window.ShadyDOM.observeChildren); + +// Set the custom observer implementation for unobserve +setDestroyObserverCallback(window.ShadyDOM.unobserveChildren); diff --git a/packages/ie11/src/theming/createComponentStyleTag.js b/packages/ie11/src/theming/createComponentStyleTag.js index f650a24d84ce..74658bd547a3 100644 --- a/packages/ie11/src/theming/createComponentStyleTag.js +++ b/packages/ie11/src/theming/createComponentStyleTag.js @@ -19,12 +19,14 @@ const getStaticStyle = ElementClass => { return componentStaticStyles; }; -/** - * Creates the needed CSS for a web component class in the head tag - * Note: IE11, Edge - * @param ElementClass - */ -const createComponentStyleTag = ElementClass => { + +const createComponentStyleTag = component => { + const ElementClass = component.constructor; + + if (!ElementClass._needsShadowDOM() && !ElementClass._needsStaticArea()) { + return; + } + const tag = ElementClass.getMetadata().getTag(); const pureTag = ElementClass.getMetadata().getPureTag(); if (IEStyleSet.has(tag)) { diff --git a/packages/main/src/Button.js b/packages/main/src/Button.js index 160fbc4568e4..be5d07969048 100644 --- a/packages/main/src/Button.js +++ b/packages/main/src/Button.js @@ -4,7 +4,7 @@ import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; -import { isLegacyBrowser } from "@ui5/webcomponents-base/dist/LegacyBrowsersAdapter.js"; +import hasNativeSupport from "@ui5/webcomponents-base/dist/hasNativeSupport.js"; import ButtonDesign from "./types/ButtonDesign.js"; import ButtonTemplate from "./generated/templates/ButtonTemplate.lit.js"; import Icon from "./Icon.js"; @@ -288,7 +288,7 @@ class Button extends UI5Element { } static get styles() { - return [buttonCss, isLegacyBrowser() ? buttonIECss : undefined]; + return [buttonCss, hasNativeSupport() ? undefined : buttonIECss]; } static get render() { diff --git a/packages/main/src/Icon.js b/packages/main/src/Icon.js index 6c9511e4cc2a..9a6b1518d7fc 100644 --- a/packages/main/src/Icon.js +++ b/packages/main/src/Icon.js @@ -4,7 +4,7 @@ import { getIconData, getIconDataSync } from "@ui5/webcomponents-base/dist/SVGIc import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHead.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; -import { isLegacyBrowser } from "@ui5/webcomponents-base/dist/LegacyBrowsersAdapter.js"; +import hasNativeSupport from "@ui5/webcomponents-base/dist/hasNativeSupport.js"; import IconTemplate from "./generated/templates/IconTemplate.lit.js"; // Styles @@ -239,7 +239,7 @@ class Icon extends UI5Element { } static createGlobalStyle() { - if (!isLegacyBrowser()) { + if (hasNativeSupport()) { return; } const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); @@ -249,7 +249,7 @@ class Icon extends UI5Element { } static removeGlobalStyle() { - if (!isLegacyBrowser()) { + if (hasNativeSupport()) { return; } const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); diff --git a/packages/main/src/ToggleButton.js b/packages/main/src/ToggleButton.js index 43b148e3f923..4b436754c018 100644 --- a/packages/main/src/ToggleButton.js +++ b/packages/main/src/ToggleButton.js @@ -1,4 +1,4 @@ -import { isLegacyBrowser } from "@ui5/webcomponents-base/dist/LegacyBrowsersAdapter.js"; +import hasNativeSupport from "@ui5/webcomponents-base/dist/hasNativeSupport.js"; import Button from "./Button.js"; import ToggleButtonTemplate from "./generated/templates/ToggleButtonTemplate.lit.js"; @@ -60,7 +60,7 @@ class ToggleButton extends Button { } static get styles() { - return [Button.styles, toggleBtnCss, isLegacyBrowser() ? toggleBtnIECss : undefined]; + return [Button.styles, toggleBtnCss, hasNativeSupport() ? undefined : toggleBtnIECss]; } _onclick() { From c9675205ca73cd12c3c90415f4364fecd99a62b4 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Mon, 18 Jan 2021 16:22:03 +0200 Subject: [PATCH 12/19] method now unnecessary, removed --- packages/ie11/src/theming/CSSVarsPonyfill.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/ie11/src/theming/CSSVarsPonyfill.js b/packages/ie11/src/theming/CSSVarsPonyfill.js index d4d7c124202f..74cdb1e82f45 100644 --- a/packages/ie11/src/theming/CSSVarsPonyfill.js +++ b/packages/ie11/src/theming/CSSVarsPonyfill.js @@ -1,7 +1,5 @@ let ponyfillTimer; -const ponyfillNeeded = () => !!window.CSSVarsPonyfill; - /** * Removes the "data-cssvars-group" attribute for all element styles and their respective out nodes. * CSSVarsPonyfill has internal counters for "group" and "job" and running several instances of the ponyfill may lead to issues, since these counters are not shared @@ -22,20 +20,18 @@ const cleanPonyfillMetadata = (rootElement = document.head) => { }; const runPonyfill = () => { - if (ponyfillNeeded()) { - ponyfillTimer = undefined; + ponyfillTimer = undefined; - cleanPonyfillMetadata(); - window.CSSVarsPonyfill.cssVars({ - rootElement: document.head, - variables: isCompact() ? getCompactModeVars() : {}, - silent: true, - }); - } + cleanPonyfillMetadata(); + window.CSSVarsPonyfill.cssVars({ + rootElement: document.head, + variables: isCompact() ? getCompactModeVars() : {}, + silent: true, + }); }; const schedulePonyfill = () => { - if (!ponyfillTimer && ponyfillNeeded()) { + if (!ponyfillTimer) { ponyfillTimer = window.setTimeout(runPonyfill, 0); } }; From 1e3100cdc6bc55132cf6f2891af838eb8bf2f0ce Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Mon, 18 Jan 2021 16:44:27 +0200 Subject: [PATCH 13/19] remove before theme loaded --- packages/base/src/DOMObserver.js | 10 +++++++++- packages/base/src/theming/ThemeLoaded.js | 16 ---------------- packages/base/src/theming/applyTheme.js | 4 +--- packages/ie11/src/integrate.js | 4 ++-- 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/packages/base/src/DOMObserver.js b/packages/base/src/DOMObserver.js index 2e21e2866b92..da12ce4f72a4 100644 --- a/packages/base/src/DOMObserver.js +++ b/packages/base/src/DOMObserver.js @@ -1,4 +1,4 @@ -const observers = new WeakMap(); +const observers = new WeakMap(); // We want just one observer per node, store them here -> DOM nodes are keys /** * Default implementation with MutationObserver for browsers with native support @@ -16,10 +16,18 @@ let _destroyObserver = observer => { observer.disconnect(); }; +/** + * Allows to create an alternative DOM observer implementation + * @param createFn + */ const setCreateObserverCallback = createFn => { _createObserver = createFn; }; +/** + * Allows to create an alternative DOM observer implementation + * @param destroyFn + */ const setDestroyObserverCallback = destroyFn => { _destroyObserver = destroyFn; }; diff --git a/packages/base/src/theming/ThemeLoaded.js b/packages/base/src/theming/ThemeLoaded.js index 71c38f036a52..937ab3f72117 100644 --- a/packages/base/src/theming/ThemeLoaded.js +++ b/packages/base/src/theming/ThemeLoaded.js @@ -2,7 +2,6 @@ import EventProvider from "../EventProvider.js"; const eventProvider = new EventProvider(); const THEME_LOADED = "themeLoaded"; -const BEFORE_THEME_LOADED = "beforeThemeLoaded"; const attachThemeLoaded = listener => { eventProvider.attachEvent(THEME_LOADED, listener); @@ -16,23 +15,8 @@ const fireThemeLoaded = theme => { return eventProvider.fireEvent(THEME_LOADED, theme); }; -const attachBeforeThemeLoaded = listener => { - eventProvider.attachEvent(BEFORE_THEME_LOADED, listener); -}; - -const detachBeforeThemeLoaded = listener => { - eventProvider.detachEvent(BEFORE_THEME_LOADED, listener); -}; - -const fireBeforeThemeLoaded = theme => { - return eventProvider.fireEvent(BEFORE_THEME_LOADED, theme); -}; - export { attachThemeLoaded, detachThemeLoaded, fireThemeLoaded, - attachBeforeThemeLoaded, - detachBeforeThemeLoaded, - fireBeforeThemeLoaded, }; diff --git a/packages/base/src/theming/applyTheme.js b/packages/base/src/theming/applyTheme.js index d200153dc46f..503e5c4b1cd3 100644 --- a/packages/base/src/theming/applyTheme.js +++ b/packages/base/src/theming/applyTheme.js @@ -1,7 +1,7 @@ import { getThemeProperties, getRegisteredPackages, isThemeRegistered } from "../asset-registries/Themes.js"; import createThemePropertiesStyleTag from "./createThemePropertiesStyleTag.js"; import getThemeDesignerTheme from "./getThemeDesignerTheme.js"; -import { fireThemeLoaded, fireBeforeThemeLoaded } from "./ThemeLoaded.js"; +import { fireThemeLoaded } from "./ThemeLoaded.js"; import { getFeature } from "../FeaturesRegistry.js"; const BASE_THEME_PACKAGE = "@ui5/webcomponents-theme-base"; @@ -72,8 +72,6 @@ const applyTheme = async theme => { const packagesTheme = isThemeRegistered(theme) ? theme : extTheme && extTheme.baseThemeName; await loadComponentPackages(packagesTheme); - fireBeforeThemeLoaded(theme); - fireThemeLoaded(theme); }; diff --git a/packages/ie11/src/integrate.js b/packages/ie11/src/integrate.js index a5e3f6537f57..a0df3df02902 100644 --- a/packages/ie11/src/integrate.js +++ b/packages/ie11/src/integrate.js @@ -1,5 +1,5 @@ import { attachBeforeBoot } from "@ui5/webcomponents-base/dist/Boot.js"; -import { attachBeforeThemeLoaded } from "@ui5/webcomponents-base/dist/theming/ThemeLoaded.js"; +import { attachThemeLoaded } from "@ui5/webcomponents-base/dist/theming/ThemeLoaded.js"; import RenderScheduler from "@ui5/webcomponents-base/dist/RenderScheduler.js"; import { setCreateObserverCallback, setDestroyObserverCallback } from "@ui5/webcomponents-base/dist/DOMObserver.js"; import whenPolyfillLoaded from "./whenPolyfillLoaded.js"; @@ -10,7 +10,7 @@ import { runPonyfill } from "./theming/CSSVarsPonyfill.js"; attachBeforeBoot(whenPolyfillLoaded); // Execute on each theme application -attachBeforeThemeLoaded(runPonyfill); +attachThemeLoaded(runPonyfill); // Execute on each component render RenderScheduler.attachBeforeComponentRender(createComponentStyleTag); From 1783c61f6b69644690ede468265d6c7d294a3c2b Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Mon, 18 Jan 2021 17:11:07 +0200 Subject: [PATCH 14/19] new boot hook name --- packages/base/src/Boot.js | 21 +++++---------------- packages/ie11/src/integrate.js | 4 ++-- packages/main/bundle.es5.js | 2 +- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/packages/base/src/Boot.js b/packages/base/src/Boot.js index d1cb1b15a6cd..a9ba999a79f8 100644 --- a/packages/base/src/Boot.js +++ b/packages/base/src/Boot.js @@ -10,24 +10,14 @@ let bootPromise; const eventProvider = new EventProvider(); /** - * Attach a callback that will be executed before the framework has booted + * Attach a callback that will be executed on boot * @public * @param listener */ -const attachBeforeBoot = listener => { - eventProvider.attachEvent("beforeBoot", listener); +const attachBootTask = listener => { + eventProvider.attachEvent("boot", listener); }; -/** - * Detach a callback that was passed with "attachBeforeBoot" - * @public - * @param listener - */ -const detachBeforeBoot = listener => { - eventProvider.detachEvent("beforeBoot", listener); -}; - - const boot = () => { if (bootPromise) { return bootPromise; @@ -44,7 +34,7 @@ const boot = () => { OpenUI5Support && OpenUI5Support.attachListeners(); insertFontFace(); insertSystemCSSVars(); - await Promise.all(eventProvider.fireEvent("beforeBoot")); + await Promise.all(eventProvider.fireEvent("boot")); resolve(); }); @@ -54,6 +44,5 @@ const boot = () => { export { boot, - attachBeforeBoot, - detachBeforeBoot, + attachBootTask, }; diff --git a/packages/ie11/src/integrate.js b/packages/ie11/src/integrate.js index a0df3df02902..6dca0ee68394 100644 --- a/packages/ie11/src/integrate.js +++ b/packages/ie11/src/integrate.js @@ -1,4 +1,4 @@ -import { attachBeforeBoot } from "@ui5/webcomponents-base/dist/Boot.js"; +import { attachBootTask } from "@ui5/webcomponents-base/dist/Boot.js"; import { attachThemeLoaded } from "@ui5/webcomponents-base/dist/theming/ThemeLoaded.js"; import RenderScheduler from "@ui5/webcomponents-base/dist/RenderScheduler.js"; import { setCreateObserverCallback, setDestroyObserverCallback } from "@ui5/webcomponents-base/dist/DOMObserver.js"; @@ -7,7 +7,7 @@ import createComponentStyleTag from "./theming/createComponentStyleTag.js"; import { runPonyfill } from "./theming/CSSVarsPonyfill.js"; // Execute once on boot -attachBeforeBoot(whenPolyfillLoaded); +attachBootTask(whenPolyfillLoaded); // Execute on each theme application attachThemeLoaded(runPonyfill); diff --git a/packages/main/bundle.es5.js b/packages/main/bundle.es5.js index 3e9631ac0a03..2f89e867d025 100644 --- a/packages/main/bundle.es5.js +++ b/packages/main/bundle.es5.js @@ -1,4 +1,4 @@ -// ES5 bundle targets IE11 only +// ES5 bundle targets IE11 and legacy Edge import "@ui5/webcomponents-ie11/dist/features/IE11.js"; import testAssets from "./bundle.esm.js"; From 186311814852645d81fa29f6dc20a2b7c712eb68 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Tue, 19 Jan 2021 08:32:48 +0200 Subject: [PATCH 15/19] reuse code --- packages/ie11/src/theming/createComponentStyleTag.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/ie11/src/theming/createComponentStyleTag.js b/packages/ie11/src/theming/createComponentStyleTag.js index 74658bd547a3..e29ab34cf85e 100644 --- a/packages/ie11/src/theming/createComponentStyleTag.js +++ b/packages/ie11/src/theming/createComponentStyleTag.js @@ -10,16 +10,6 @@ attachCustomCSSChange(tag => { IEStyleSet.delete(tag); }); -const getStaticStyle = ElementClass => { - let componentStaticStyles = ElementClass.staticAreaStyles; - if (Array.isArray(componentStaticStyles)) { - componentStaticStyles = componentStaticStyles.join(" "); - } - - return componentStaticStyles; -}; - - const createComponentStyleTag = component => { const ElementClass = component.constructor; @@ -37,7 +27,7 @@ const createComponentStyleTag = component => { cssContent = adaptCSSForIE(cssContent, tag, pureTag); // Append static CSS, if any, for IE - let staticCssContent = getStaticStyle(ElementClass); + let staticCssContent = getEffectiveStyle(ElementClass, true); if (staticCssContent) { staticCssContent = adaptCSSForIE(staticCssContent, "ui5-static-area-item"); cssContent = `${cssContent} ${staticCssContent}`; From ec9152152f81775060de9dabe40c87626cd700f5 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Tue, 19 Jan 2021 09:10:13 +0200 Subject: [PATCH 16/19] rename --- packages/base/src/Boot.js | 4 ++-- packages/ie11/src/integrate.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/base/src/Boot.js b/packages/base/src/Boot.js index a9ba999a79f8..d53b7ff3d2b7 100644 --- a/packages/base/src/Boot.js +++ b/packages/base/src/Boot.js @@ -14,7 +14,7 @@ const eventProvider = new EventProvider(); * @public * @param listener */ -const attachBootTask = listener => { +const attachBoot = listener => { eventProvider.attachEvent("boot", listener); }; @@ -44,5 +44,5 @@ const boot = () => { export { boot, - attachBootTask, + attachBoot, }; diff --git a/packages/ie11/src/integrate.js b/packages/ie11/src/integrate.js index 6dca0ee68394..691889b9d032 100644 --- a/packages/ie11/src/integrate.js +++ b/packages/ie11/src/integrate.js @@ -1,4 +1,4 @@ -import { attachBootTask } from "@ui5/webcomponents-base/dist/Boot.js"; +import { attachBoot } from "@ui5/webcomponents-base/dist/Boot.js"; import { attachThemeLoaded } from "@ui5/webcomponents-base/dist/theming/ThemeLoaded.js"; import RenderScheduler from "@ui5/webcomponents-base/dist/RenderScheduler.js"; import { setCreateObserverCallback, setDestroyObserverCallback } from "@ui5/webcomponents-base/dist/DOMObserver.js"; @@ -7,7 +7,7 @@ import createComponentStyleTag from "./theming/createComponentStyleTag.js"; import { runPonyfill } from "./theming/CSSVarsPonyfill.js"; // Execute once on boot -attachBootTask(whenPolyfillLoaded); +attachBoot(whenPolyfillLoaded); // Execute on each theme application attachThemeLoaded(runPonyfill); From 4586140b74ef32ed8c89100984de97bdef82c733 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Tue, 19 Jan 2021 12:17:43 +0200 Subject: [PATCH 17/19] fireAsync --- packages/base/src/Boot.js | 2 +- packages/base/src/EventProvider.js | 12 +++++++++++- packages/base/src/config/Language.js | 3 +-- packages/base/src/locale/languageChange.js | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/base/src/Boot.js b/packages/base/src/Boot.js index d53b7ff3d2b7..f43cc54d1247 100644 --- a/packages/base/src/Boot.js +++ b/packages/base/src/Boot.js @@ -34,7 +34,7 @@ const boot = () => { OpenUI5Support && OpenUI5Support.attachListeners(); insertFontFace(); insertSystemCSSVars(); - await Promise.all(eventProvider.fireEvent("boot")); + await eventProvider.fireEventAsync("boot"); resolve(); }); diff --git a/packages/base/src/EventProvider.js b/packages/base/src/EventProvider.js index e9c16eb818cf..d3fc1cac32a0 100644 --- a/packages/base/src/EventProvider.js +++ b/packages/base/src/EventProvider.js @@ -36,7 +36,6 @@ class EventProvider { /** * Fires an event and returns the results of all event listeners as an array. - * Example: If listeners return promises, you can: await fireEvent("myEvent") to know when all listeners have finished. * * @param eventName the event to fire * @param data optional data to pass to each event listener @@ -55,6 +54,17 @@ class EventProvider { }); } + /** + * Fires an event, awaits for all listeners' results to have resolved, and returns the results as an array. + * + * @param eventName the event to fire + * @param data optional data to pass to each event listener + * @returns {Array} an array with the results of all event listeners + */ + async fireEventAsync(eventName, data) { + return await Promise.all(this.fireEvent(eventName, data)); + } + isHandlerAttached(eventName, fnFunction) { const eventRegistry = this._eventRegistry; const eventListeners = eventRegistry[eventName]; diff --git a/packages/base/src/config/Language.js b/packages/base/src/config/Language.js index bdac7b219a75..9486402ba18b 100644 --- a/packages/base/src/config/Language.js +++ b/packages/base/src/config/Language.js @@ -33,8 +33,7 @@ const setLanguage = async newLanguage => { language = newLanguage; - const listenersResults = fireLanguageChange(newLanguage); - await Promise.all(listenersResults); + await fireLanguageChange(newLanguage); RenderScheduler.reRenderAllUI5Elements({ languageAware: true }); return RenderScheduler.whenFinished(); }; diff --git a/packages/base/src/locale/languageChange.js b/packages/base/src/locale/languageChange.js index 02863b12a92e..ef6a61a3a6d7 100644 --- a/packages/base/src/locale/languageChange.js +++ b/packages/base/src/locale/languageChange.js @@ -12,7 +12,7 @@ const detachLanguageChange = listener => { }; const fireLanguageChange = lang => { - return eventProvider.fireEvent(LANG_CHANGE, lang); + return eventProvider.fireEventAsync(LANG_CHANGE, lang); }; export { From 8f1e4f645f1c3bd2bc31ff9e311281f167e31363 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Tue, 19 Jan 2021 13:05:56 +0200 Subject: [PATCH 18/19] also fix help --- docs/Angular-tutorial.md | 7 ++++++- packages/base/src/EventProvider.js | 4 ++-- packages/fiori/bundle.scoped.es5.js | 2 +- packages/main/bundle.scoped.es5.js | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/Angular-tutorial.md b/docs/Angular-tutorial.md index 6586bea4f926..3c421bd884aa 100644 --- a/docs/Angular-tutorial.md +++ b/docs/Angular-tutorial.md @@ -136,6 +136,11 @@ If you need your application to run on Internet Explorer 11, there are some addi *Note* These steps have been tested with Angular 7. For other versions of Angular, there might be some differences. 1. Install all needed dependencies: + +```bash +npm install @ui5/webcomponents-ie11 --save +``` + ```bash npm install --save @angular-builders/custom-webpack@7.5 @angular-builders/dev-server@7.3 @babel/core @babel/preset-env babel-loader ``` @@ -205,7 +210,7 @@ module.exports = { 4. Add the following import ```to app.module.ts``` file: ```js -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11WithWebComponentsPolyfill.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11WithWebComponentsPolyfill.js"; ``` *Note*: The ```IE11WithWebComponentsPolyfill.js``` file includes the official webcomponents polyfill, so you don’t have to import it by yourself. (This file was released in our latest @next version. It will be shipped with our next stable release rc.6, so until then it would be available only with the @next tag) diff --git a/packages/base/src/EventProvider.js b/packages/base/src/EventProvider.js index d3fc1cac32a0..1361f169b92a 100644 --- a/packages/base/src/EventProvider.js +++ b/packages/base/src/EventProvider.js @@ -61,8 +61,8 @@ class EventProvider { * @param data optional data to pass to each event listener * @returns {Array} an array with the results of all event listeners */ - async fireEventAsync(eventName, data) { - return await Promise.all(this.fireEvent(eventName, data)); + fireEventAsync(eventName, data) { + return Promise.all(this.fireEvent(eventName, data)); } isHandlerAttached(eventName, fnFunction) { diff --git a/packages/fiori/bundle.scoped.es5.js b/packages/fiori/bundle.scoped.es5.js index 8f60488d88a6..1a366a5eaf6c 100644 --- a/packages/fiori/bundle.scoped.es5.js +++ b/packages/fiori/bundle.scoped.es5.js @@ -1,5 +1,5 @@ // ES5 bundle targets IE11 only -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11.js"; import testAssets from "./bundle.scoped.esm.js"; diff --git a/packages/main/bundle.scoped.es5.js b/packages/main/bundle.scoped.es5.js index 8f60488d88a6..1a366a5eaf6c 100644 --- a/packages/main/bundle.scoped.es5.js +++ b/packages/main/bundle.scoped.es5.js @@ -1,5 +1,5 @@ // ES5 bundle targets IE11 only -import "@ui5/webcomponents-base/dist/features/browsersupport/IE11.js"; +import "@ui5/webcomponents-ie11/dist/features/IE11.js"; import testAssets from "./bundle.scoped.esm.js"; From 3bb47dd99195287516c36c02d60bbeeb359ec452 Mon Sep 17 00:00:00 2001 From: Vladislav Tasev Date: Wed, 20 Jan 2021 13:40:40 +0200 Subject: [PATCH 19/19] comments --- packages/base/src/EventProvider.js | 4 ++-- packages/base/src/StaticAreaItem.js | 4 ++-- packages/base/src/UI5Element.js | 4 ++-- packages/base/src/hasNativeSupport.js | 5 ---- packages/base/src/isLegacyBrowser.js | 3 +++ packages/base/src/theming/getStylesString.js | 2 +- packages/main/src/Button.js | 4 ++-- packages/main/src/Icon.js | 24 +++++++++----------- packages/main/src/ToggleButton.js | 4 ++-- 9 files changed, 25 insertions(+), 29 deletions(-) delete mode 100644 packages/base/src/hasNativeSupport.js create mode 100644 packages/base/src/isLegacyBrowser.js diff --git a/packages/base/src/EventProvider.js b/packages/base/src/EventProvider.js index 1361f169b92a..69e42ebe8b8c 100644 --- a/packages/base/src/EventProvider.js +++ b/packages/base/src/EventProvider.js @@ -55,11 +55,11 @@ class EventProvider { } /** - * Fires an event, awaits for all listeners' results to have resolved, and returns the results as an array. + * Fires an event and returns a promise that will resolve once all listeners have resolved. * * @param eventName the event to fire * @param data optional data to pass to each event listener - * @returns {Array} an array with the results of all event listeners + * @returns {Promise} a promise that will resolve when all listeners have resolved */ fireEventAsync(eventName, data) { return Promise.all(this.fireEvent(eventName, data)); diff --git a/packages/base/src/StaticAreaItem.js b/packages/base/src/StaticAreaItem.js index 03f18cf2c3fb..6da2f565d3b7 100644 --- a/packages/base/src/StaticAreaItem.js +++ b/packages/base/src/StaticAreaItem.js @@ -2,7 +2,7 @@ import { getStaticAreaInstance, removeStaticArea } from "./StaticArea.js"; import RenderScheduler from "./RenderScheduler.js"; import getEffectiveStyle from "./theming/getEffectiveStyle.js"; import executeTemplate from "./renderer/executeTemplate.js"; -import hasNativeSupport from "./hasNativeSupport.js"; +import isLegacyBrowser from "./isLegacyBrowser.js"; import getConstructableStyle from "./theming/getConstructableStyle.js"; /** @@ -47,7 +47,7 @@ class StaticAreaItem { if (document.adoptedStyleSheets) { // Chrome this.staticAreaItemDomRef.shadowRoot.adoptedStyleSheets = getConstructableStyle(this.ui5ElementContext.constructor, true); - } else if (hasNativeSupport()) { // FF, Safari + } else if (!isLegacyBrowser()) { // FF, Safari stylesToPrepend = getEffectiveStyle(this.ui5ElementContext.constructor, true); } diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index f7b6d74e0cab..f2a6ad3b063e 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -18,7 +18,7 @@ import isValidPropertyName from "./util/isValidPropertyName.js"; import isSlot from "./util/isSlot.js"; import arraysAreEqual from "./util/arraysAreEqual.js"; import { markAsRtlAware } from "./locale/RTLAwareRegistry.js"; -import hasNativeSupport from "./hasNativeSupport.js"; +import isLegacyBrowser from "./isLegacyBrowser.js"; let autoId = 0; @@ -627,7 +627,7 @@ class UI5Element extends HTMLElement { if (document.adoptedStyleSheets) { // Chrome this.shadowRoot.adoptedStyleSheets = getConstructableStyle(this.constructor); - } else if (hasNativeSupport()) { // FF, Safari + } else if (!isLegacyBrowser()) { // FF, Safari styleToPrepend = getEffectiveStyle(this.constructor); } diff --git a/packages/base/src/hasNativeSupport.js b/packages/base/src/hasNativeSupport.js deleted file mode 100644 index d4253abad55c..000000000000 --- a/packages/base/src/hasNativeSupport.js +++ /dev/null @@ -1,5 +0,0 @@ -const hasNativeSupport = () => { - return !window.ShadyDOM; -}; - -export default hasNativeSupport; diff --git a/packages/base/src/isLegacyBrowser.js b/packages/base/src/isLegacyBrowser.js new file mode 100644 index 000000000000..11d7bedef891 --- /dev/null +++ b/packages/base/src/isLegacyBrowser.js @@ -0,0 +1,3 @@ +const isLegacyBrowser = () => !!window.ShadyDOM; + +export default isLegacyBrowser; diff --git a/packages/base/src/theming/getStylesString.js b/packages/base/src/theming/getStylesString.js index 2da560e7002b..4a5477604edf 100644 --- a/packages/base/src/theming/getStylesString.js +++ b/packages/base/src/theming/getStylesString.js @@ -1,6 +1,6 @@ const getStylesString = styles => { if (Array.isArray(styles)) { - return flatten(styles).join(" "); + return flatten(styles.filter(style => !!style)).join(" "); } return styles; diff --git a/packages/main/src/Button.js b/packages/main/src/Button.js index be5d07969048..b7e95ff3679d 100644 --- a/packages/main/src/Button.js +++ b/packages/main/src/Button.js @@ -4,7 +4,7 @@ import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; -import hasNativeSupport from "@ui5/webcomponents-base/dist/hasNativeSupport.js"; +import isLegacyBrowser from "@ui5/webcomponents-base/dist/isLegacyBrowser.js"; import ButtonDesign from "./types/ButtonDesign.js"; import ButtonTemplate from "./generated/templates/ButtonTemplate.lit.js"; import Icon from "./Icon.js"; @@ -288,7 +288,7 @@ class Button extends UI5Element { } static get styles() { - return [buttonCss, hasNativeSupport() ? undefined : buttonIECss]; + return [buttonCss, isLegacyBrowser() && buttonIECss]; } static get render() { diff --git a/packages/main/src/Icon.js b/packages/main/src/Icon.js index 9a6b1518d7fc..1b22ad85bf8a 100644 --- a/packages/main/src/Icon.js +++ b/packages/main/src/Icon.js @@ -4,7 +4,7 @@ import { getIconData, getIconDataSync } from "@ui5/webcomponents-base/dist/SVGIc import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHead.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; -import hasNativeSupport from "@ui5/webcomponents-base/dist/hasNativeSupport.js"; +import isLegacyBrowser from "@ui5/webcomponents-base/dist/isLegacyBrowser.js"; import IconTemplate from "./generated/templates/IconTemplate.lit.js"; // Styles @@ -239,22 +239,20 @@ class Icon extends UI5Element { } static createGlobalStyle() { - if (hasNativeSupport()) { - return; - } - const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); - if (!styleElement) { - createStyleInHead(`ui5-icon { display: none !important; }`, { "data-ui5-icon-global": "" }); + if (isLegacyBrowser()) { + const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); + if (!styleElement) { + createStyleInHead(`ui5-icon { display: none !important; }`, { "data-ui5-icon-global": "" }); + } } } static removeGlobalStyle() { - if (hasNativeSupport()) { - return; - } - const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); - if (styleElement) { - document.head.removeChild(styleElement); + if (isLegacyBrowser()) { + const styleElement = document.head.querySelector(`style[data-ui5-icon-global]`); + if (styleElement) { + document.head.removeChild(styleElement); + } } } diff --git a/packages/main/src/ToggleButton.js b/packages/main/src/ToggleButton.js index 4b436754c018..4e52b9b0d39b 100644 --- a/packages/main/src/ToggleButton.js +++ b/packages/main/src/ToggleButton.js @@ -1,4 +1,4 @@ -import hasNativeSupport from "@ui5/webcomponents-base/dist/hasNativeSupport.js"; +import isLegacyBrowser from "@ui5/webcomponents-base/dist/isLegacyBrowser.js"; import Button from "./Button.js"; import ToggleButtonTemplate from "./generated/templates/ToggleButtonTemplate.lit.js"; @@ -60,7 +60,7 @@ class ToggleButton extends Button { } static get styles() { - return [Button.styles, toggleBtnCss, hasNativeSupport() ? undefined : toggleBtnIECss]; + return [Button.styles, toggleBtnCss, isLegacyBrowser() && toggleBtnIECss]; } _onclick() {