@ui5/webcomponents-base 0.0.0-934b4df24 → 0.0.0-b053ad005
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +3 -0
- package/CHANGELOG.md +137 -0
- package/README.md +26 -2
- package/bundle.esm.js +16 -7
- package/dist/AssetRegistry.js +8 -7
- package/dist/Boot.js +43 -0
- package/dist/CSP.js +59 -0
- package/dist/CustomElementsRegistry.js +24 -8
- package/dist/CustomElementsScope.js +108 -0
- package/dist/DOMObserver.js +65 -0
- package/dist/Device.js +62 -778
- package/dist/EventProvider.js +38 -26
- package/dist/FontFace.js +19 -62
- package/dist/InitialConfiguration.js +43 -8
- package/dist/Keys.js +89 -2
- package/dist/ManagedStyles.js +83 -0
- package/dist/MediaRange.js +109 -0
- package/dist/PropertiesFileFormat.js +95 -0
- package/dist/Render.js +175 -0
- package/dist/RenderQueue.js +41 -17
- package/dist/RenderScheduler.js +24 -126
- package/dist/StaticArea.js +1 -39
- package/dist/StaticAreaItem.js +56 -63
- package/dist/SystemCSSVars.js +10 -0
- package/dist/Theming.js +2 -1
- package/dist/UI5Element.js +411 -319
- package/dist/UI5ElementMetadata.js +165 -17
- package/dist/asset-registries/Icons.js +129 -14
- package/dist/asset-registries/Illustrations.js +30 -0
- package/dist/asset-registries/LocaleData.js +99 -65
- package/dist/asset-registries/Themes.js +23 -32
- package/dist/asset-registries/i18n.js +72 -30
- package/dist/assets-meta/IconCollectionsAlias.js +18 -0
- package/dist/config/AnimationMode.js +11 -1
- package/dist/config/Language.js +58 -2
- package/dist/config/Theme.js +14 -0
- package/dist/css/FontFace.css +45 -0
- package/dist/css/OverrideFontFace.css +32 -0
- package/dist/css/SystemCSSVars.css +17 -0
- package/dist/delegate/ItemNavigation.js +244 -171
- package/dist/delegate/ResizeHandler.js +78 -38
- package/dist/delegate/ScrollEnablement.js +49 -20
- package/dist/features/OpenUI5Support.js +42 -7
- package/dist/generated/AssetParameters.js +1 -1
- package/dist/generated/css/FontFace.css.js +5 -0
- package/dist/generated/css/OverrideFontFace.css.js +5 -0
- package/dist/generated/css/SystemCSSVars.css.js +5 -0
- package/dist/getSharedResource.js +30 -0
- package/dist/i18nBundle.js +58 -5
- package/dist/isLegacyBrowser.js +3 -0
- package/dist/locale/RTLAwareRegistry.js +14 -0
- package/dist/locale/applyDirection.js +17 -0
- package/dist/locale/directionChange.js +32 -0
- package/dist/locale/getEffectiveDir.js +28 -0
- package/dist/locale/getLocale.js +12 -2
- package/dist/locale/languageChange.js +22 -0
- package/dist/renderer/LitRenderer.js +26 -7
- package/dist/renderer/directives/style-map.js +72 -0
- package/dist/renderer/executeTemplate.js +17 -0
- package/dist/resources/bundle.esm.js +17 -109
- package/dist/resources/bundle.esm.js.map +1 -1
- package/dist/sap/base/Log.js +241 -0
- package/dist/sap/base/assert.js +8 -0
- package/dist/sap/base/security/URLListValidator.js +148 -0
- package/dist/sap/base/security/sanitizeHTML.js +16 -0
- package/dist/sap/base/util/now.js +7 -0
- package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +3585 -0
- package/dist/test-resources/assets/Themes.js +10 -6
- package/dist/test-resources/elements/Parent.js +6 -2
- package/dist/test-resources/elements/WithStaticArea.js +2 -1
- package/dist/test-resources/pages/AllTestElements.html +3 -3
- package/dist/test-resources/pages/Configuration.html +0 -2
- package/dist/test-resources/pages/ConfigurationScript.html +1 -3
- package/dist/test-resources/pages/assets/messagebundle_de.properties +1 -0
- package/dist/test-resources/pages/assets/messagebundle_en.properties +1 -0
- package/dist/test-resources/pages/assets/messagebundle_es.properties +1 -0
- package/dist/test-resources/pages/assets/messagebundle_fr.properties +1 -0
- package/dist/test-resources/pages/i18n.html +33 -0
- package/dist/test-resources/specs/ConfigurationChange.spec.js +11 -9
- package/dist/test-resources/specs/ConfigurationScript.spec.js +25 -23
- package/dist/test-resources/specs/ConfigurationURL.spec.js +65 -17
- package/dist/test-resources/specs/CustomTheme.spec.js +9 -7
- package/dist/test-resources/specs/EventProvider.spec.js +63 -0
- package/dist/test-resources/specs/StaticArea.spec.js +56 -12
- package/dist/test-resources/specs/Theming.spec.js +12 -10
- package/dist/test-resources/specs/UI5ElementInvalidation.js +54 -70
- package/dist/test-resources/specs/UI5ElementLifecycle.js +19 -14
- package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +25 -51
- package/dist/test-resources/specs/UI5ElementMetadataExt.js +9 -7
- package/dist/test-resources/specs/UI5ElementPropertyValidation.js +7 -5
- package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +37 -35
- package/dist/test-resources/specs/UI5ElementShadowDOM.js +10 -8
- package/dist/test-resources/specs/UI5ElementSlots.js +10 -8
- package/dist/theming/CustomStyle.js +28 -7
- package/dist/theming/ThemeLoaded.js +22 -0
- package/dist/theming/applyTheme.js +7 -13
- package/dist/theming/getConstructableStyle.js +15 -10
- package/dist/theming/getEffectiveLinksHrefs.js +20 -0
- package/dist/theming/getEffectiveStyle.js +23 -8
- package/dist/theming/getStylesString.js +15 -0
- package/dist/theming/getThemeDesignerTheme.js +2 -1
- package/dist/theming/preloadLinks.js +23 -0
- package/dist/types/CSSColor.js +9 -0
- package/dist/types/CalendarType.js +1 -1
- package/dist/types/DataType.js +13 -1
- package/dist/types/Float.js +14 -0
- package/dist/types/Integer.js +4 -0
- package/dist/types/InvisibleMessageMode.js +30 -0
- package/dist/types/ItemNavigationBehavior.js +2 -7
- package/dist/types/NavigationMode.js +1 -0
- package/dist/types/PopupState.js +1 -1
- package/dist/types/ValueState.js +1 -1
- package/dist/updateShadowRoot.js +30 -0
- package/dist/util/AriaLabelHelper.js +41 -0
- package/dist/util/Caret.js +45 -0
- package/dist/util/ColorConversion.js +370 -0
- package/dist/util/FocusableElements.js +25 -8
- package/dist/util/HTMLSanitizer.js +7 -0
- package/dist/util/InvisibleMessage.js +58 -0
- package/dist/util/PopupUtils.js +93 -0
- package/dist/util/SlotsHelper.js +43 -0
- package/dist/util/TabbableElements.js +1 -1
- package/dist/util/arraysAreEqual.js +15 -0
- package/dist/util/clamp.js +12 -0
- package/dist/util/createLinkInHead.js +19 -0
- package/dist/util/debounce.js +17 -0
- package/dist/util/encodeCSS.js +24 -0
- package/dist/util/getActiveElement.js +11 -0
- package/dist/util/getClassCopy.js +10 -0
- package/dist/util/getEffectiveContentDensity.js +5 -0
- package/dist/util/getSingletonElementInstance.js +13 -0
- package/dist/util/isElementInView.js +15 -0
- package/dist/util/isNodeHidden.js +1 -5
- package/dist/util/isNodeTabbable.js +4 -4
- package/dist/util/isValidPropertyName.js +9 -3
- package/dist/util/setToArray.js +10 -0
- package/hash.txt +1 -0
- package/index.js +1 -1
- package/lib/generate-asset-parameters/index.js +0 -1
- package/lib/generate-styles/index.js +18 -0
- package/package-scripts.js +37 -19
- package/package.json +19 -13
- package/src/AssetRegistry.js +8 -7
- package/src/Boot.js +43 -0
- package/src/CSP.js +59 -0
- package/src/CustomElementsRegistry.js +24 -8
- package/src/CustomElementsScope.js +108 -0
- package/src/DOMObserver.js +65 -0
- package/src/Device.js +62 -778
- package/src/EventProvider.js +38 -26
- package/src/FontFace.js +19 -62
- package/src/InitialConfiguration.js +43 -8
- package/src/Keys.js +89 -2
- package/src/ManagedStyles.js +83 -0
- package/src/MediaRange.js +109 -0
- package/src/PropertiesFileFormat.js +95 -0
- package/src/Render.js +175 -0
- package/src/RenderQueue.js +41 -17
- package/src/RenderScheduler.js +24 -126
- package/src/StaticArea.js +1 -39
- package/src/StaticAreaItem.js +56 -63
- package/src/SystemCSSVars.js +10 -0
- package/src/Theming.js +2 -1
- package/src/UI5Element.js +411 -319
- package/src/UI5ElementMetadata.js +165 -17
- package/src/asset-registries/Icons.js +129 -14
- package/src/asset-registries/Illustrations.js +30 -0
- package/src/asset-registries/LocaleData.js +99 -65
- package/src/asset-registries/Themes.js +23 -32
- package/src/asset-registries/i18n.js +72 -30
- package/src/assets-meta/IconCollectionsAlias.js +18 -0
- package/src/config/AnimationMode.js +11 -1
- package/src/config/Language.js +58 -2
- package/src/config/Theme.js +14 -0
- package/src/css/FontFace.css +45 -0
- package/src/css/OverrideFontFace.css +32 -0
- package/src/css/SystemCSSVars.css +17 -0
- package/src/delegate/ItemNavigation.js +244 -171
- package/src/delegate/ResizeHandler.js +78 -38
- package/src/delegate/ScrollEnablement.js +49 -20
- package/src/features/OpenUI5Support.js +42 -7
- package/src/getSharedResource.js +30 -0
- package/src/i18nBundle.js +58 -5
- package/src/isLegacyBrowser.js +3 -0
- package/src/locale/RTLAwareRegistry.js +14 -0
- package/src/locale/applyDirection.js +17 -0
- package/src/locale/directionChange.js +32 -0
- package/src/locale/getEffectiveDir.js +28 -0
- package/src/locale/getLocale.js +12 -2
- package/src/locale/languageChange.js +22 -0
- package/src/renderer/LitRenderer.js +26 -7
- package/src/renderer/directives/style-map.js +72 -0
- package/src/renderer/executeTemplate.js +17 -0
- package/src/theming/CustomStyle.js +28 -7
- package/src/theming/ThemeLoaded.js +22 -0
- package/src/theming/applyTheme.js +7 -13
- package/src/theming/getConstructableStyle.js +15 -10
- package/src/theming/getEffectiveLinksHrefs.js +20 -0
- package/src/theming/getEffectiveStyle.js +23 -8
- package/src/theming/getStylesString.js +15 -0
- package/src/theming/getThemeDesignerTheme.js +2 -1
- package/src/theming/preloadLinks.js +23 -0
- package/src/types/CSSColor.js +9 -0
- package/src/types/CalendarType.js +1 -1
- package/src/types/DataType.js +13 -1
- package/src/types/Float.js +14 -0
- package/src/types/Integer.js +4 -0
- package/src/types/InvisibleMessageMode.js +30 -0
- package/src/types/ItemNavigationBehavior.js +2 -7
- package/src/types/NavigationMode.js +1 -0
- package/src/types/PopupState.js +1 -1
- package/src/types/ValueState.js +1 -1
- package/src/updateShadowRoot.js +30 -0
- package/src/util/AriaLabelHelper.js +41 -0
- package/src/util/Caret.js +45 -0
- package/src/util/ColorConversion.js +370 -0
- package/src/util/FocusableElements.js +25 -8
- package/src/util/HTMLSanitizer.js +7 -0
- package/src/util/InvisibleMessage.js +58 -0
- package/src/util/PopupUtils.js +93 -0
- package/src/util/SlotsHelper.js +43 -0
- package/src/util/TabbableElements.js +1 -1
- package/src/util/arraysAreEqual.js +15 -0
- package/src/util/clamp.js +12 -0
- package/src/util/createLinkInHead.js +19 -0
- package/src/util/debounce.js +17 -0
- package/src/util/encodeCSS.js +24 -0
- package/src/util/getActiveElement.js +11 -0
- package/src/util/getClassCopy.js +10 -0
- package/src/util/getEffectiveContentDensity.js +5 -0
- package/src/util/getSingletonElementInstance.js +13 -0
- package/src/util/isElementInView.js +15 -0
- package/src/util/isNodeHidden.js +1 -5
- package/src/util/isNodeTabbable.js +4 -4
- package/src/util/isValidPropertyName.js +9 -3
- package/src/util/setToArray.js +10 -0
- package/used-modules.txt +7 -0
- package/bundle.es5.js +0 -28
- package/dist/SVGIconRegistry.js +0 -60
- package/dist/boot.js +0 -32
- package/dist/compatibility/DOMObserver.js +0 -62
- package/dist/compatibility/patchNodeValue.js +0 -24
- package/dist/compatibility/whenPolyfillLoaded.js +0 -26
- package/dist/delegate/CustomResize.js +0 -78
- package/dist/delegate/NativeResize.js +0 -44
- package/dist/features/browsersupport/Edge.js +0 -6
- package/dist/features/browsersupport/IE11.js +0 -41
- package/dist/features/browsersupport/IE11WithWebComponentsPolyfill.js +0 -5
- package/dist/renderer/ifDefined.js +0 -21
- package/dist/resources/bundle.es5.js +0 -212
- package/dist/resources/bundle.es5.js.map +0 -1
- package/dist/theming/CSSVarsPonyfill.js +0 -24
- package/dist/theming/adaptCSSForIE.js +0 -90
- package/dist/theming/createComponentStyleTag.js +0 -49
- package/dist/theming/createThemePropertiesStyleTag.js +0 -20
- package/dist/thirdparty/Array.from.js +0 -16
- package/dist/thirdparty/Array.prototype.fill.js +0 -44
- package/dist/thirdparty/Array.prototype.find.js +0 -46
- package/dist/thirdparty/Array.prototype.includes.js +0 -51
- package/dist/thirdparty/Element.prototype.closest.js +0 -11
- package/dist/thirdparty/Element.prototype.matches.js +0 -6
- package/dist/thirdparty/Map.prototype.keys.js +0 -9
- package/dist/thirdparty/Number.isInteger.js +0 -5
- package/dist/thirdparty/Number.isNaN.js +0 -1
- package/dist/thirdparty/Number.parseInt.js +0 -1
- package/dist/thirdparty/Object.assign.js +0 -31
- package/dist/thirdparty/Object.entries.js +0 -11
- package/dist/thirdparty/Symbol.js +0 -2
- package/dist/thirdparty/WeakSet.js +0 -27
- package/dist/thirdparty/es6-string-methods.js +0 -182
- package/dist/thirdparty/events-polyfills.js +0 -89
- package/dist/thirdparty/fetch.js +0 -1
- package/dist/thirdparty/template.js +0 -600
- package/dist/thirdparty/webcomponents-sd-ce-pf.js +0 -318
- package/dist/util/isSlot.js +0 -3
- package/dist/webcomponentsjs/LICENSE.md +0 -19
- package/dist/webcomponentsjs/README.md +0 -229
- package/dist/webcomponentsjs/bundles/webcomponents-ce.js +0 -63
- package/dist/webcomponentsjs/bundles/webcomponents-ce.js.map +0 -1
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js +0 -297
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js.map +0 -1
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce.js +0 -208
- package/dist/webcomponentsjs/bundles/webcomponents-sd-ce.js.map +0 -1
- package/dist/webcomponentsjs/bundles/webcomponents-sd.js +0 -166
- package/dist/webcomponentsjs/bundles/webcomponents-sd.js.map +0 -1
- package/dist/webcomponentsjs/custom-elements-es5-adapter.js +0 -15
- package/dist/webcomponentsjs/package.json +0 -46
- package/dist/webcomponentsjs/src/entrypoints/custom-elements-es5-adapter-index.js +0 -16
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-bundle-index.js +0 -53
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-ce-index.js +0 -17
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-index.js +0 -19
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-pf-index.js +0 -28
- package/dist/webcomponentsjs/src/entrypoints/webcomponents-sd-index.js +0 -18
- package/dist/webcomponentsjs/webcomponents-bundle.js +0 -298
- package/dist/webcomponentsjs/webcomponents-bundle.js.map +0 -1
- package/dist/webcomponentsjs/webcomponents-loader.js +0 -185
- package/src/SVGIconRegistry.js +0 -60
- package/src/boot.js +0 -32
- package/src/compatibility/DOMObserver.js +0 -62
- package/src/compatibility/patchNodeValue.js +0 -24
- package/src/compatibility/whenPolyfillLoaded.js +0 -26
- package/src/delegate/CustomResize.js +0 -78
- package/src/delegate/NativeResize.js +0 -44
- package/src/features/browsersupport/Edge.js +0 -6
- package/src/features/browsersupport/IE11.js +0 -41
- package/src/features/browsersupport/IE11WithWebComponentsPolyfill.js +0 -5
- package/src/renderer/ifDefined.js +0 -21
- package/src/theming/CSSVarsPonyfill.js +0 -24
- package/src/theming/adaptCSSForIE.js +0 -90
- package/src/theming/createComponentStyleTag.js +0 -49
- package/src/theming/createThemePropertiesStyleTag.js +0 -20
- package/src/thirdparty/Array.from.js +0 -16
- package/src/thirdparty/Array.prototype.fill.js +0 -44
- package/src/thirdparty/Array.prototype.find.js +0 -46
- package/src/thirdparty/Array.prototype.includes.js +0 -51
- package/src/thirdparty/Element.prototype.closest.js +0 -11
- package/src/thirdparty/Element.prototype.matches.js +0 -6
- package/src/thirdparty/Map.prototype.keys.js +0 -9
- package/src/thirdparty/Number.isInteger.js +0 -5
- package/src/thirdparty/Number.isNaN.js +0 -1
- package/src/thirdparty/Number.parseInt.js +0 -1
- package/src/thirdparty/Object.assign.js +0 -31
- package/src/thirdparty/Object.entries.js +0 -11
- package/src/thirdparty/Symbol.js +0 -2
- package/src/thirdparty/WeakSet.js +0 -27
- package/src/thirdparty/es6-string-methods.js +0 -182
- package/src/thirdparty/events-polyfills.js +0 -89
- package/src/thirdparty/fetch.js +0 -1
- package/src/thirdparty/template.js +0 -600
- package/src/thirdparty/webcomponents-sd-ce-pf.js +0 -318
- package/src/util/isSlot.js +0 -3
package/dist/UI5Element.js
CHANGED
|
@@ -1,30 +1,51 @@
|
|
|
1
1
|
import merge from "./thirdparty/merge.js";
|
|
2
|
-
import boot from "./
|
|
2
|
+
import { boot } from "./Boot.js";
|
|
3
3
|
import UI5ElementMetadata from "./UI5ElementMetadata.js";
|
|
4
|
+
import EventProvider from "./EventProvider.js";
|
|
5
|
+
import getSingletonElementInstance from "./util/getSingletonElementInstance.js";
|
|
4
6
|
import StaticAreaItem from "./StaticAreaItem.js";
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
7
|
+
import updateShadowRoot from "./updateShadowRoot.js";
|
|
8
|
+
import { renderDeferred, renderImmediately, cancelRender } from "./Render.js";
|
|
9
|
+
import { registerTag, isTagRegistered, recordTagRegistrationFailure } from "./CustomElementsRegistry.js";
|
|
10
|
+
import { observeDOMNode, unobserveDOMNode } from "./DOMObserver.js";
|
|
8
11
|
import { skipOriginalEvent } from "./config/NoConflict.js";
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import getEffectiveStyle from "./theming/getEffectiveStyle.js";
|
|
12
|
-
import Integer from "./types/Integer.js";
|
|
12
|
+
import getEffectiveDir from "./locale/getEffectiveDir.js";
|
|
13
|
+
import DataType from "./types/DataType.js";
|
|
13
14
|
import { kebabToCamelCase, camelToKebabCase } from "./util/StringHelper.js";
|
|
14
15
|
import isValidPropertyName from "./util/isValidPropertyName.js";
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
};
|
|
16
|
+
import isDescendantOf from "./util/isDescendantOf.js";
|
|
17
|
+
import { isSlot, getSlotName, getSlottedElementsList } from "./util/SlotsHelper.js";
|
|
18
|
+
import arraysAreEqual from "./util/arraysAreEqual.js";
|
|
19
|
+
import getClassCopy from "./util/getClassCopy.js";
|
|
20
|
+
import { markAsRtlAware } from "./locale/RTLAwareRegistry.js";
|
|
21
|
+
import preloadLinks from "./theming/preloadLinks.js";
|
|
22
22
|
|
|
23
23
|
let autoId = 0;
|
|
24
24
|
|
|
25
25
|
const elementTimeouts = new Map();
|
|
26
|
+
const uniqueDependenciesCache = new Map();
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Triggers re-rendering of a UI5Element instance due to state change.
|
|
30
|
+
*
|
|
31
|
+
* @param changeInfo An object with information about the change that caused invalidation.
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
function _invalidate(changeInfo) {
|
|
35
|
+
// Invalidation should be suppressed: 1) before the component is rendered for the first time 2) and during the execution of onBeforeRendering
|
|
36
|
+
// This is necessary not only as an optimization, but also to avoid infinite loops on invalidation between children and parents (when invalidateOnChildChange is used)
|
|
37
|
+
if (this._suppressInvalidation) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Call the onInvalidation hook
|
|
42
|
+
this.onInvalidation(changeInfo);
|
|
43
|
+
|
|
44
|
+
this._changedState.push(changeInfo);
|
|
45
|
+
renderDeferred(this);
|
|
46
|
+
this._eventProvider.fireEvent("invalidate", { ...changeInfo, target: this });
|
|
47
|
+
}
|
|
26
48
|
|
|
27
|
-
const GLOBAL_CONTENT_DENSITY_CSS_VAR = "--_ui5_content_density";
|
|
28
49
|
/**
|
|
29
50
|
* Base class for all UI5 Web Components
|
|
30
51
|
*
|
|
@@ -38,56 +59,40 @@ const GLOBAL_CONTENT_DENSITY_CSS_VAR = "--_ui5_content_density";
|
|
|
38
59
|
class UI5Element extends HTMLElement {
|
|
39
60
|
constructor() {
|
|
40
61
|
super();
|
|
41
|
-
this._generateId();
|
|
42
|
-
this._initializeState();
|
|
43
|
-
this._upgradeAllProperties();
|
|
44
|
-
this._initializeContainers();
|
|
45
|
-
this._upToDate = false;
|
|
46
62
|
|
|
63
|
+
this._changedState = []; // Filled on each invalidation, cleared on re-render (used for debugging)
|
|
64
|
+
this._suppressInvalidation = true; // A flag telling whether all invalidations should be ignored. Initialized with "true" because a UI5Element can not be invalidated until it is rendered for the first time
|
|
65
|
+
this._inDOM = false; // A flag telling whether the UI5Element is currently in the DOM tree of the document or not
|
|
66
|
+
this._fullyConnected = false; // A flag telling whether the UI5Element's onEnterDOM hook was called (since it's possible to have the element removed from DOM before that)
|
|
67
|
+
this._childChangeListeners = new Map(); // used to store lazy listeners per slot for the child change event of every child inside that slot
|
|
68
|
+
this._slotChangeListeners = new Map(); // used to store lazy listeners per slot for the slotchange event of all slot children inside that slot
|
|
69
|
+
this._eventProvider = new EventProvider(); // used by parent components for listening to changes to child components
|
|
47
70
|
let deferredResolve;
|
|
48
71
|
this._domRefReadyPromise = new Promise(resolve => {
|
|
49
72
|
deferredResolve = resolve;
|
|
50
73
|
});
|
|
51
74
|
this._domRefReadyPromise._deferredResolve = deferredResolve;
|
|
52
75
|
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
55
|
-
}
|
|
76
|
+
this._initializeState();
|
|
77
|
+
this._upgradeAllProperties();
|
|
56
78
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
_generateId() {
|
|
61
|
-
this._id = `ui5wc_${++autoId}`;
|
|
79
|
+
if (this.constructor._needsShadowDOM()) {
|
|
80
|
+
this.attachShadow({ mode: "open" });
|
|
81
|
+
}
|
|
62
82
|
}
|
|
63
83
|
|
|
64
84
|
/**
|
|
65
|
-
*
|
|
85
|
+
* Returns a unique ID for this UI5 Element
|
|
86
|
+
*
|
|
87
|
+
* @deprecated - This property is not guaranteed in future releases
|
|
88
|
+
* @protected
|
|
66
89
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// Init Shadow Root
|
|
72
|
-
if (needsShadowDOM) {
|
|
73
|
-
this.attachShadow({ mode: "open" });
|
|
74
|
-
|
|
75
|
-
// IE11, Edge
|
|
76
|
-
if (window.ShadyDOM) {
|
|
77
|
-
createComponentStyleTag(this.constructor);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Chrome
|
|
81
|
-
if (document.adoptedStyleSheets) {
|
|
82
|
-
const style = getConstructableStyle(this.constructor);
|
|
83
|
-
this.shadowRoot.adoptedStyleSheets = [style];
|
|
84
|
-
}
|
|
90
|
+
get _id() {
|
|
91
|
+
if (!this.__id) {
|
|
92
|
+
this.__id = `ui5wc_${++autoId}`;
|
|
85
93
|
}
|
|
86
94
|
|
|
87
|
-
|
|
88
|
-
if (needsStaticArea) {
|
|
89
|
-
this.staticAreaItem = new StaticAreaItem(this);
|
|
90
|
-
}
|
|
95
|
+
return this.__id;
|
|
91
96
|
}
|
|
92
97
|
|
|
93
98
|
/**
|
|
@@ -95,26 +100,27 @@ class UI5Element extends HTMLElement {
|
|
|
95
100
|
* @private
|
|
96
101
|
*/
|
|
97
102
|
async connectedCallback() {
|
|
98
|
-
|
|
103
|
+
this.setAttribute(this.constructor.getMetadata().getPureTag(), "");
|
|
104
|
+
|
|
99
105
|
const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
|
|
100
106
|
|
|
101
|
-
|
|
102
|
-
if (needsShadowDOM) {
|
|
103
|
-
if (slotsAreManaged) {
|
|
104
|
-
// always register the observer before yielding control to the main thread (await)
|
|
105
|
-
this._startObservingDOMChildren();
|
|
106
|
-
await this._processChildren();
|
|
107
|
-
}
|
|
107
|
+
this._inDOM = true;
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
if (slotsAreManaged) {
|
|
110
|
+
// always register the observer before yielding control to the main thread (await)
|
|
111
|
+
this._startObservingDOMChildren();
|
|
112
|
+
await this._processChildren();
|
|
113
|
+
}
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
if (!this._inDOM) { // Component removed from DOM while _processChildren was running
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
renderImmediately(this);
|
|
120
|
+
this._domRefReadyPromise._deferredResolve();
|
|
121
|
+
this._fullyConnected = true;
|
|
122
|
+
if (typeof this.onEnterDOM === "function") {
|
|
123
|
+
this.onEnterDOM();
|
|
118
124
|
}
|
|
119
125
|
}
|
|
120
126
|
|
|
@@ -123,23 +129,26 @@ class UI5Element extends HTMLElement {
|
|
|
123
129
|
* @private
|
|
124
130
|
*/
|
|
125
131
|
disconnectedCallback() {
|
|
126
|
-
const needsShadowDOM = this.constructor._needsShadowDOM();
|
|
127
|
-
const needsStaticArea = this.constructor._needsStaticArea();
|
|
128
132
|
const slotsAreManaged = this.constructor.getMetadata().slotsAreManaged();
|
|
129
133
|
|
|
130
|
-
|
|
131
|
-
if (slotsAreManaged) {
|
|
132
|
-
this._stopObservingDOMChildren();
|
|
133
|
-
}
|
|
134
|
+
this._inDOM = false;
|
|
134
135
|
|
|
136
|
+
if (slotsAreManaged) {
|
|
137
|
+
this._stopObservingDOMChildren();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (this._fullyConnected) {
|
|
135
141
|
if (typeof this.onExitDOM === "function") {
|
|
136
142
|
this.onExitDOM();
|
|
137
143
|
}
|
|
144
|
+
this._fullyConnected = false;
|
|
138
145
|
}
|
|
139
146
|
|
|
140
|
-
if (
|
|
141
|
-
this.staticAreaItem.
|
|
147
|
+
if (this.staticAreaItem && this.staticAreaItem.parentElement) {
|
|
148
|
+
this.staticAreaItem.parentElement.removeChild(this.staticAreaItem);
|
|
142
149
|
}
|
|
150
|
+
|
|
151
|
+
cancelRender(this);
|
|
143
152
|
}
|
|
144
153
|
|
|
145
154
|
/**
|
|
@@ -155,16 +164,16 @@ class UI5Element extends HTMLElement {
|
|
|
155
164
|
const mutationObserverOptions = {
|
|
156
165
|
childList: true,
|
|
157
166
|
subtree: canSlotText,
|
|
158
|
-
characterData:
|
|
167
|
+
characterData: canSlotText,
|
|
159
168
|
};
|
|
160
|
-
|
|
169
|
+
observeDOMNode(this, this._processChildren.bind(this), mutationObserverOptions);
|
|
161
170
|
}
|
|
162
171
|
|
|
163
172
|
/**
|
|
164
173
|
* @private
|
|
165
174
|
*/
|
|
166
175
|
_stopObservingDOMChildren() {
|
|
167
|
-
|
|
176
|
+
unobserveDOMNode(this);
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
/**
|
|
@@ -186,8 +195,14 @@ class UI5Element extends HTMLElement {
|
|
|
186
195
|
const canSlotText = this.constructor.getMetadata().canSlotText();
|
|
187
196
|
const domChildren = Array.from(canSlotText ? this.childNodes : this.children);
|
|
188
197
|
|
|
189
|
-
//
|
|
198
|
+
const slotsCachedContentMap = new Map(); // Store here the content of each slot before the mutation occurred
|
|
199
|
+
const propertyNameToSlotMap = new Map(); // Used for reverse lookup to determine to which slot the property name corresponds
|
|
200
|
+
|
|
201
|
+
// Init the _state object based on the supported slots and store the previous values
|
|
190
202
|
for (const [slotName, slotData] of Object.entries(slotsMap)) { // eslint-disable-line
|
|
203
|
+
const propertyName = slotData.propertyName || slotName;
|
|
204
|
+
propertyNameToSlotMap.set(propertyName, slotName);
|
|
205
|
+
slotsCachedContentMap.set(propertyName, [...this._state[propertyName]]);
|
|
191
206
|
this._clearSlot(slotName, slotData);
|
|
192
207
|
}
|
|
193
208
|
|
|
@@ -196,7 +211,7 @@ class UI5Element extends HTMLElement {
|
|
|
196
211
|
|
|
197
212
|
const allChildrenUpgraded = domChildren.map(async (child, idx) => {
|
|
198
213
|
// Determine the type of the child (mainly by the slot attribute)
|
|
199
|
-
const slotName =
|
|
214
|
+
const slotName = getSlotName(child);
|
|
200
215
|
const slotData = slotsMap[slotName];
|
|
201
216
|
|
|
202
217
|
// Check if the slotName is supported
|
|
@@ -234,12 +249,14 @@ class UI5Element extends HTMLElement {
|
|
|
234
249
|
|
|
235
250
|
child = this.constructor.getMetadata().constructor.validateSlotValue(child, slotData);
|
|
236
251
|
|
|
237
|
-
if (
|
|
238
|
-
|
|
252
|
+
// Listen for any invalidation on the child if invalidateOnChildChange is true or an object (ignore when false or not set)
|
|
253
|
+
if (child.isUI5Element && slotData.invalidateOnChildChange) {
|
|
254
|
+
child.attachInvalidate(this._getChildChangeListener(slotName));
|
|
239
255
|
}
|
|
240
256
|
|
|
257
|
+
// Listen for the slotchange event if the child is a slot itself
|
|
241
258
|
if (isSlot(child)) {
|
|
242
|
-
this._attachSlotChange(child);
|
|
259
|
+
this._attachSlotChange(child, slotName);
|
|
243
260
|
}
|
|
244
261
|
|
|
245
262
|
const propertyName = slotData.propertyName || slotName;
|
|
@@ -255,10 +272,33 @@ class UI5Element extends HTMLElement {
|
|
|
255
272
|
|
|
256
273
|
// Distribute the child in the _state object, keeping the Light DOM order,
|
|
257
274
|
// not the order elements are defined.
|
|
258
|
-
slottedChildrenMap.forEach((children,
|
|
259
|
-
this._state[
|
|
275
|
+
slottedChildrenMap.forEach((children, propertyName) => {
|
|
276
|
+
this._state[propertyName] = children.sort((a, b) => a.idx - b.idx).map(_ => _.child);
|
|
260
277
|
});
|
|
261
|
-
|
|
278
|
+
|
|
279
|
+
// Compare the content of each slot with the cached values and invalidate for the ones that changed
|
|
280
|
+
let invalidated = false;
|
|
281
|
+
for (const [slotName, slotData] of Object.entries(slotsMap)) { // eslint-disable-line
|
|
282
|
+
const propertyName = slotData.propertyName || slotName;
|
|
283
|
+
if (!arraysAreEqual(slotsCachedContentMap.get(propertyName), this._state[propertyName])) {
|
|
284
|
+
_invalidate.call(this, {
|
|
285
|
+
type: "slot",
|
|
286
|
+
name: propertyNameToSlotMap.get(propertyName),
|
|
287
|
+
reason: "children",
|
|
288
|
+
});
|
|
289
|
+
invalidated = true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// If none of the slots had an invalidation due to changes to immediate children,
|
|
294
|
+
// the change is considered to be text content of the default slot
|
|
295
|
+
if (!invalidated) {
|
|
296
|
+
_invalidate.call(this, {
|
|
297
|
+
type: "slot",
|
|
298
|
+
name: "default",
|
|
299
|
+
reason: "textcontent",
|
|
300
|
+
});
|
|
301
|
+
}
|
|
262
302
|
}
|
|
263
303
|
|
|
264
304
|
/**
|
|
@@ -267,24 +307,61 @@ class UI5Element extends HTMLElement {
|
|
|
267
307
|
*/
|
|
268
308
|
_clearSlot(slotName, slotData) {
|
|
269
309
|
const propertyName = slotData.propertyName || slotName;
|
|
270
|
-
|
|
271
|
-
let children = this._state[propertyName];
|
|
272
|
-
if (!Array.isArray(children)) {
|
|
273
|
-
children = [children];
|
|
274
|
-
}
|
|
310
|
+
const children = this._state[propertyName];
|
|
275
311
|
|
|
276
312
|
children.forEach(child => {
|
|
277
313
|
if (child && child.isUI5Element) {
|
|
278
|
-
this.
|
|
314
|
+
child.detachInvalidate(this._getChildChangeListener(slotName));
|
|
279
315
|
}
|
|
280
316
|
|
|
281
317
|
if (isSlot(child)) {
|
|
282
|
-
this._detachSlotChange(child);
|
|
318
|
+
this._detachSlotChange(child, slotName);
|
|
283
319
|
}
|
|
284
320
|
});
|
|
285
321
|
|
|
286
322
|
this._state[propertyName] = [];
|
|
287
|
-
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Attach a callback that will be executed whenever the component is invalidated
|
|
327
|
+
*
|
|
328
|
+
* @param callback
|
|
329
|
+
* @public
|
|
330
|
+
*/
|
|
331
|
+
attachInvalidate(callback) {
|
|
332
|
+
this._eventProvider.attachEvent("invalidate", callback);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Detach the callback that is executed whenever the component is invalidated
|
|
337
|
+
*
|
|
338
|
+
* @param callback
|
|
339
|
+
* @public
|
|
340
|
+
*/
|
|
341
|
+
detachInvalidate(callback) {
|
|
342
|
+
this._eventProvider.detachEvent("invalidate", callback);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Callback that is executed whenever a monitored child changes its state
|
|
347
|
+
*
|
|
348
|
+
* @param slotName the slot in which a child was invalidated
|
|
349
|
+
* @param childChangeInfo the changeInfo object for the child in the given slot
|
|
350
|
+
* @private
|
|
351
|
+
*/
|
|
352
|
+
_onChildChange(slotName, childChangeInfo) {
|
|
353
|
+
if (!this.constructor.getMetadata().shouldInvalidateOnChildChange(slotName, childChangeInfo.type, childChangeInfo.name)) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// The component should be invalidated as this type of change on the child is listened for
|
|
358
|
+
// However, no matter what changed on the child (property/slot), the invalidation is registered as "type=slot" for the component itself
|
|
359
|
+
_invalidate.call(this, {
|
|
360
|
+
type: "slot",
|
|
361
|
+
name: slotName,
|
|
362
|
+
reason: "childchange",
|
|
363
|
+
child: childChangeInfo.target,
|
|
364
|
+
});
|
|
288
365
|
}
|
|
289
366
|
|
|
290
367
|
/**
|
|
@@ -299,9 +376,8 @@ class UI5Element extends HTMLElement {
|
|
|
299
376
|
const propertyTypeClass = properties[nameInCamelCase].type;
|
|
300
377
|
if (propertyTypeClass === Boolean) {
|
|
301
378
|
newValue = newValue !== null;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
newValue = parseInt(newValue);
|
|
379
|
+
} else if (isDescendantOf(propertyTypeClass, DataType)) {
|
|
380
|
+
newValue = propertyTypeClass.attributeToProperty(newValue);
|
|
305
381
|
}
|
|
306
382
|
this[nameInCamelCase] = newValue;
|
|
307
383
|
}
|
|
@@ -314,22 +390,24 @@ class UI5Element extends HTMLElement {
|
|
|
314
390
|
if (!this.constructor.getMetadata().hasAttribute(name)) {
|
|
315
391
|
return;
|
|
316
392
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
|
|
393
|
+
const properties = this.constructor.getMetadata().getProperties();
|
|
394
|
+
const propertyTypeClass = properties[name].type;
|
|
322
395
|
const attrName = camelToKebabCase(name);
|
|
323
396
|
const attrValue = this.getAttribute(attrName);
|
|
324
|
-
|
|
397
|
+
|
|
398
|
+
if (propertyTypeClass === Boolean) {
|
|
325
399
|
if (newValue === true && attrValue === null) {
|
|
326
400
|
this.setAttribute(attrName, "");
|
|
327
401
|
} else if (newValue === false && attrValue !== null) {
|
|
328
402
|
this.removeAttribute(attrName);
|
|
329
403
|
}
|
|
330
|
-
} else if (
|
|
331
|
-
this.setAttribute(attrName, newValue);
|
|
332
|
-
}
|
|
404
|
+
} else if (isDescendantOf(propertyTypeClass, DataType)) {
|
|
405
|
+
this.setAttribute(attrName, propertyTypeClass.propertyToAttribute(newValue));
|
|
406
|
+
} else if (typeof newValue !== "object") {
|
|
407
|
+
if (attrValue !== newValue) {
|
|
408
|
+
this.setAttribute(attrName, newValue);
|
|
409
|
+
}
|
|
410
|
+
} // else { return; } // old object handling
|
|
333
411
|
}
|
|
334
412
|
|
|
335
413
|
/**
|
|
@@ -355,120 +433,96 @@ class UI5Element extends HTMLElement {
|
|
|
355
433
|
* @private
|
|
356
434
|
*/
|
|
357
435
|
_initializeState() {
|
|
358
|
-
|
|
359
|
-
this._state = Object.assign({}, defaultState);
|
|
436
|
+
this._state = { ...this.constructor.getMetadata().getInitialState() };
|
|
360
437
|
}
|
|
361
438
|
|
|
362
439
|
/**
|
|
440
|
+
* Returns a singleton event listener for the "change" event of a child in a given slot
|
|
441
|
+
*
|
|
442
|
+
* @param slotName the name of the slot, where the child is
|
|
443
|
+
* @returns {any}
|
|
363
444
|
* @private
|
|
364
445
|
*/
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
slotName
|
|
368
|
-
childProperties = childMetadata.getProperties();
|
|
369
|
-
|
|
370
|
-
let observedProps = [],
|
|
371
|
-
notObservedProps = [];
|
|
372
|
-
|
|
373
|
-
if (Array.isArray(listenFor)) {
|
|
374
|
-
observedProps = listenFor;
|
|
375
|
-
} else {
|
|
376
|
-
observedProps = Array.isArray(listenFor.props) ? listenFor.props : Object.keys(childProperties);
|
|
377
|
-
notObservedProps = Array.isArray(listenFor.exclude) ? listenFor.exclude : [];
|
|
446
|
+
_getChildChangeListener(slotName) {
|
|
447
|
+
if (!this._childChangeListeners.has(slotName)) {
|
|
448
|
+
this._childChangeListeners.set(slotName, this._onChildChange.bind(this, slotName));
|
|
378
449
|
}
|
|
379
|
-
|
|
380
|
-
if (!this._monitoredChildProps.has(slotName)) {
|
|
381
|
-
this._monitoredChildProps.set(slotName, { observedProps, notObservedProps });
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
child.addEventListener("_propertyChange", this._invalidateParentOnPropertyUpdate);
|
|
385
|
-
child._firePropertyChange = true;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* @private
|
|
390
|
-
*/
|
|
391
|
-
_detachChildPropertyUpdated(child) {
|
|
392
|
-
child.removeEventListener("_propertyChange", this._invalidateParentOnPropertyUpdate);
|
|
393
|
-
child._firePropertyChange = false;
|
|
450
|
+
return this._childChangeListeners.get(slotName);
|
|
394
451
|
}
|
|
395
452
|
|
|
396
453
|
/**
|
|
454
|
+
* Returns a singleton slotchange event listener that invalidates the component due to changes in the given slot
|
|
455
|
+
*
|
|
456
|
+
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is
|
|
457
|
+
* @returns {any}
|
|
397
458
|
* @private
|
|
398
459
|
*/
|
|
399
|
-
|
|
400
|
-
this.
|
|
401
|
-
|
|
402
|
-
if (this._firePropertyChange) {
|
|
403
|
-
this.dispatchEvent(new CustomEvent("_propertyChange", {
|
|
404
|
-
detail: { name, newValue: value },
|
|
405
|
-
composed: false,
|
|
406
|
-
bubbles: true,
|
|
407
|
-
}));
|
|
460
|
+
_getSlotChangeListener(slotName) {
|
|
461
|
+
if (!this._slotChangeListeners.has(slotName)) {
|
|
462
|
+
this._slotChangeListeners.set(slotName, this._onSlotChange.bind(this, slotName));
|
|
408
463
|
}
|
|
464
|
+
return this._slotChangeListeners.get(slotName);
|
|
409
465
|
}
|
|
410
466
|
|
|
411
467
|
/**
|
|
412
468
|
* @private
|
|
413
469
|
*/
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const parentNode = this.parentNode;
|
|
417
|
-
if (!parentNode) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
const slotName = parentNode.constructor._getSlotName(this);
|
|
422
|
-
const propsMetadata = parentNode._monitoredChildProps.get(slotName);
|
|
423
|
-
|
|
424
|
-
if (!propsMetadata) {
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
const { observedProps, notObservedProps } = propsMetadata;
|
|
428
|
-
|
|
429
|
-
if (observedProps.includes(prop.detail.name) && !notObservedProps.includes(prop.detail.name)) {
|
|
430
|
-
parentNode._invalidate("_parent_", this);
|
|
431
|
-
}
|
|
470
|
+
_attachSlotChange(child, slotName) {
|
|
471
|
+
child.addEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
432
472
|
}
|
|
433
473
|
|
|
434
474
|
/**
|
|
435
475
|
* @private
|
|
436
476
|
*/
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
this._invalidateOnSlotChange = () => {
|
|
440
|
-
this._invalidate("slotchange");
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
child.addEventListener("slotchange", this._invalidateOnSlotChange);
|
|
477
|
+
_detachSlotChange(child, slotName) {
|
|
478
|
+
child.removeEventListener("slotchange", this._getSlotChangeListener(slotName));
|
|
444
479
|
}
|
|
445
480
|
|
|
446
481
|
/**
|
|
482
|
+
* Whenever a slot element is slotted inside a UI5 Web Component, its slotchange event invalidates the component
|
|
483
|
+
*
|
|
484
|
+
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is
|
|
447
485
|
* @private
|
|
448
486
|
*/
|
|
449
|
-
|
|
450
|
-
|
|
487
|
+
_onSlotChange(slotName) {
|
|
488
|
+
_invalidate.call(this, {
|
|
489
|
+
type: "slot",
|
|
490
|
+
name: slotName,
|
|
491
|
+
reason: "slotchange",
|
|
492
|
+
});
|
|
451
493
|
}
|
|
452
494
|
|
|
453
495
|
/**
|
|
454
|
-
*
|
|
455
|
-
*
|
|
496
|
+
* A callback that is executed each time an already rendered component is invalidated (scheduled for re-rendering)
|
|
497
|
+
*
|
|
498
|
+
* @param changeInfo An object with information about the change that caused invalidation.
|
|
499
|
+
* The object can have the following properties:
|
|
500
|
+
* - type: (property|slot) tells what caused the invalidation
|
|
501
|
+
* 1) property: a property value was changed either directly or as a result of changing the corresponding attribute
|
|
502
|
+
* 2) slot: a slotted node(nodes) changed in one of several ways (see "reason")
|
|
503
|
+
*
|
|
504
|
+
* - name: the name of the property or slot that caused the invalidation
|
|
505
|
+
*
|
|
506
|
+
* - reason: (children|textcontent|childchange|slotchange) relevant only for type="slot" only and tells exactly what changed in the slot
|
|
507
|
+
* 1) children: immediate children (HTML elements or text nodes) were added, removed or reordered in the slot
|
|
508
|
+
* 2) textcontent: text nodes in the slot changed value (or nested text nodes were added or changed value). Can only trigger for slots of "type: Node"
|
|
509
|
+
* 3) slotchange: a slot element, slotted inside that slot had its "slotchange" event listener called. This practically means that transitively slotted children changed.
|
|
510
|
+
* Can only trigger if the child of a slot is a slot element itself.
|
|
511
|
+
* 4) childchange: indicates that a UI5Element child in that slot was invalidated and in turn invalidated the component.
|
|
512
|
+
* Can only trigger for slots with "invalidateOnChildChange" metadata descriptor
|
|
513
|
+
*
|
|
514
|
+
* - newValue: the new value of the property (for type="property" only)
|
|
515
|
+
*
|
|
516
|
+
* - oldValue: the old value of the property (for type="property" only)
|
|
517
|
+
*
|
|
518
|
+
* - child the child that was changed (for type="slot" and reason="childchange" only)
|
|
519
|
+
*
|
|
520
|
+
* @public
|
|
456
521
|
*/
|
|
457
|
-
|
|
458
|
-
if (!this._upToDate) {
|
|
459
|
-
// console.log("already invalidated", this, ...arguments);
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
if (this.getDomRef() && !this._suppressInvalidation) {
|
|
464
|
-
this._upToDate = false;
|
|
465
|
-
// console.log("INVAL", this, ...arguments);
|
|
466
|
-
RenderScheduler.renderDeferred(this);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
522
|
+
onInvalidation(changeInfo) {}
|
|
469
523
|
|
|
470
524
|
/**
|
|
471
|
-
* Do not call this method directly, only intended to be called by
|
|
525
|
+
* Do not call this method directly, only intended to be called by js
|
|
472
526
|
* @protected
|
|
473
527
|
*/
|
|
474
528
|
_render() {
|
|
@@ -487,15 +541,37 @@ class UI5Element extends HTMLElement {
|
|
|
487
541
|
}
|
|
488
542
|
|
|
489
543
|
// resume normal invalidation handling
|
|
490
|
-
|
|
544
|
+
this._suppressInvalidation = false;
|
|
491
545
|
|
|
492
546
|
// Update the shadow root with the render result
|
|
493
|
-
|
|
494
|
-
this.
|
|
495
|
-
|
|
547
|
+
/*
|
|
548
|
+
if (this._changedState.length) {
|
|
549
|
+
let element = this.localName;
|
|
550
|
+
if (this.id) {
|
|
551
|
+
element = `${element}#${this.id}`;
|
|
552
|
+
}
|
|
553
|
+
console.log("Re-rendering:", element, this._changedState.map(x => { // eslint-disable-line
|
|
554
|
+
let res = `${x.type}`;
|
|
555
|
+
if (x.reason) {
|
|
556
|
+
res = `${res}(${x.reason})`;
|
|
557
|
+
}
|
|
558
|
+
res = `${res}: ${x.name}`;
|
|
559
|
+
if (x.type === "property") {
|
|
560
|
+
res = `${res} ${x.oldValue} => ${x.newValue}`;
|
|
561
|
+
}
|
|
496
562
|
|
|
497
|
-
|
|
498
|
-
|
|
563
|
+
return res;
|
|
564
|
+
}));
|
|
565
|
+
}
|
|
566
|
+
*/
|
|
567
|
+
this._changedState = [];
|
|
568
|
+
|
|
569
|
+
// Update shadow root and static area item
|
|
570
|
+
if (this.constructor._needsShadowDOM()) {
|
|
571
|
+
updateShadowRoot(this);
|
|
572
|
+
}
|
|
573
|
+
if (this.staticAreaItem) {
|
|
574
|
+
this.staticAreaItem.update();
|
|
499
575
|
}
|
|
500
576
|
|
|
501
577
|
// Safari requires that children get the slot attribute only after the slot tags have been rendered in the shadow DOM
|
|
@@ -509,23 +585,6 @@ class UI5Element extends HTMLElement {
|
|
|
509
585
|
}
|
|
510
586
|
}
|
|
511
587
|
|
|
512
|
-
/**
|
|
513
|
-
* @private
|
|
514
|
-
*/
|
|
515
|
-
_updateShadowRoot() {
|
|
516
|
-
if (!this.constructor._needsShadowDOM()) {
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
let styleToPrepend;
|
|
521
|
-
const renderResult = this.constructor.template(this);
|
|
522
|
-
|
|
523
|
-
if (!document.adoptedStyleSheets && !window.ShadyDOM) {
|
|
524
|
-
styleToPrepend = getEffectiveStyle(this.constructor);
|
|
525
|
-
}
|
|
526
|
-
this.constructor.render(renderResult, this.shadowRoot, styleToPrepend, { eventContext: this });
|
|
527
|
-
}
|
|
528
|
-
|
|
529
588
|
/**
|
|
530
589
|
* @private
|
|
531
590
|
*/
|
|
@@ -548,16 +607,27 @@ class UI5Element extends HTMLElement {
|
|
|
548
607
|
|
|
549
608
|
/**
|
|
550
609
|
* Returns the DOM Element inside the Shadow Root that corresponds to the opening tag in the UI5 Web Component's template
|
|
610
|
+
* *Note:* For logical (abstract) elements (items, options, etc...), returns the part of the parent's DOM that represents this option
|
|
551
611
|
* Use this method instead of "this.shadowRoot" to read the Shadow DOM, if ever necessary
|
|
612
|
+
*
|
|
552
613
|
* @public
|
|
553
614
|
*/
|
|
554
615
|
getDomRef() {
|
|
616
|
+
// If a component set _getRealDomRef to its children, use the return value of this function
|
|
617
|
+
if (typeof this._getRealDomRef === "function") {
|
|
618
|
+
return this._getRealDomRef();
|
|
619
|
+
}
|
|
620
|
+
|
|
555
621
|
if (!this.shadowRoot || this.shadowRoot.children.length === 0) {
|
|
556
622
|
return;
|
|
557
623
|
}
|
|
558
624
|
|
|
559
|
-
|
|
560
|
-
|
|
625
|
+
const children = [...this.shadowRoot.children].filter(child => !["link", "style"].includes(child.localName));
|
|
626
|
+
if (children.length !== 1) {
|
|
627
|
+
console.warn(`The shadow DOM for ${this.constructor.getMetadata().getTag()} does not have a top level element, the getDomRef() method might not work as expected`); // eslint-disable-line
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
return children[0];
|
|
561
631
|
}
|
|
562
632
|
|
|
563
633
|
/**
|
|
@@ -573,6 +643,16 @@ class UI5Element extends HTMLElement {
|
|
|
573
643
|
}
|
|
574
644
|
}
|
|
575
645
|
|
|
646
|
+
/**
|
|
647
|
+
* Waits for dom ref and then returns the DOM Element marked with "data-sap-focus-ref" inside the template.
|
|
648
|
+
* This is the element that will receive the focus by default.
|
|
649
|
+
* @public
|
|
650
|
+
*/
|
|
651
|
+
async getFocusDomRefAsync() {
|
|
652
|
+
await this._waitForDomRef();
|
|
653
|
+
return this.getFocusDomRef();
|
|
654
|
+
}
|
|
655
|
+
|
|
576
656
|
/**
|
|
577
657
|
* Set the focus to the element, returned by "getFocusDomRef()" (marked by "data-sap-focus-ref")
|
|
578
658
|
* @public
|
|
@@ -593,37 +673,47 @@ class UI5Element extends HTMLElement {
|
|
|
593
673
|
* @param name - name of the event
|
|
594
674
|
* @param data - additional data for the event
|
|
595
675
|
* @param cancelable - true, if the user can call preventDefault on the event object
|
|
676
|
+
* @param bubbles - true, if the event bubbles
|
|
596
677
|
* @returns {boolean} false, if the event was cancelled (preventDefault called), true otherwise
|
|
597
678
|
*/
|
|
598
|
-
fireEvent(name, data, cancelable) {
|
|
599
|
-
|
|
679
|
+
fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
680
|
+
const eventResult = this._fireEvent(name, data, cancelable, bubbles);
|
|
681
|
+
const camelCaseEventName = kebabToCamelCase(name);
|
|
600
682
|
|
|
683
|
+
if (camelCaseEventName !== name) {
|
|
684
|
+
return eventResult && this._fireEvent(camelCaseEventName, data, cancelable);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
return eventResult;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
_fireEvent(name, data, cancelable = false, bubbles = true) {
|
|
601
691
|
const noConflictEvent = new CustomEvent(`ui5-${name}`, {
|
|
602
692
|
detail: data,
|
|
603
693
|
composed: false,
|
|
604
|
-
bubbles
|
|
694
|
+
bubbles,
|
|
605
695
|
cancelable,
|
|
606
696
|
});
|
|
607
697
|
|
|
608
|
-
// This will be false if the
|
|
609
|
-
|
|
698
|
+
// This will be false if the no-conflict event is prevented
|
|
699
|
+
const noConflictEventResult = this.dispatchEvent(noConflictEvent);
|
|
610
700
|
|
|
611
701
|
if (skipOriginalEvent(name)) {
|
|
612
|
-
return
|
|
702
|
+
return noConflictEventResult;
|
|
613
703
|
}
|
|
614
704
|
|
|
615
|
-
const
|
|
705
|
+
const normalEvent = new CustomEvent(name, {
|
|
616
706
|
detail: data,
|
|
617
707
|
composed: false,
|
|
618
|
-
bubbles
|
|
708
|
+
bubbles,
|
|
619
709
|
cancelable,
|
|
620
710
|
});
|
|
621
711
|
|
|
622
712
|
// This will be false if the normal event is prevented
|
|
623
|
-
const normalEventResult = this.dispatchEvent(
|
|
713
|
+
const normalEventResult = this.dispatchEvent(normalEvent);
|
|
624
714
|
|
|
625
715
|
// Return false if any of the two events was prevented (its result was false).
|
|
626
|
-
return normalEventResult &&
|
|
716
|
+
return normalEventResult && noConflictEventResult;
|
|
627
717
|
}
|
|
628
718
|
|
|
629
719
|
/**
|
|
@@ -632,24 +722,19 @@ class UI5Element extends HTMLElement {
|
|
|
632
722
|
* @public
|
|
633
723
|
*/
|
|
634
724
|
getSlottedNodes(slotName) {
|
|
635
|
-
|
|
636
|
-
if (!isSlot(curr)) {
|
|
637
|
-
return acc.concat([curr]);
|
|
638
|
-
}
|
|
639
|
-
return acc.concat(curr.assignedNodes({ flatten: true }).filter(item => item instanceof HTMLElement));
|
|
640
|
-
};
|
|
641
|
-
|
|
642
|
-
return this[slotName].reduce(reducer, []);
|
|
725
|
+
return getSlottedElementsList(this[slotName]);
|
|
643
726
|
}
|
|
644
727
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
728
|
+
/**
|
|
729
|
+
* Determines whether the component should be rendered in RTL mode or not.
|
|
730
|
+
* Returns: "rtl", "ltr" or undefined
|
|
731
|
+
*
|
|
732
|
+
* @public
|
|
733
|
+
* @returns {String|undefined}
|
|
734
|
+
*/
|
|
735
|
+
get effectiveDir() {
|
|
736
|
+
markAsRtlAware(this.constructor); // if a UI5 Element calls this method, it's considered to be rtl-aware
|
|
737
|
+
return getEffectiveDir(this);
|
|
653
738
|
}
|
|
654
739
|
|
|
655
740
|
/**
|
|
@@ -669,26 +754,6 @@ class UI5Element extends HTMLElement {
|
|
|
669
754
|
return this.getMetadata().getAttributesList();
|
|
670
755
|
}
|
|
671
756
|
|
|
672
|
-
/**
|
|
673
|
-
* @private
|
|
674
|
-
*/
|
|
675
|
-
static _getSlotName(child) {
|
|
676
|
-
// Text nodes can only go to the default slot
|
|
677
|
-
if (!(child instanceof HTMLElement)) {
|
|
678
|
-
return "default";
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// Discover the slot based on the real slot name (f.e. footer => footer, or content-32 => content)
|
|
682
|
-
const slot = child.getAttribute("slot");
|
|
683
|
-
if (slot) {
|
|
684
|
-
const match = slot.match(/^(.+?)-\d+$/);
|
|
685
|
-
return match ? match[1] : slot;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
// Use default slot as a fallback
|
|
689
|
-
return "default";
|
|
690
|
-
}
|
|
691
|
-
|
|
692
757
|
/**
|
|
693
758
|
* @private
|
|
694
759
|
*/
|
|
@@ -696,70 +761,30 @@ class UI5Element extends HTMLElement {
|
|
|
696
761
|
return !!this.template;
|
|
697
762
|
}
|
|
698
763
|
|
|
699
|
-
_shouldUpdateFragment() {
|
|
700
|
-
return this.constructor._needsStaticArea() && this.staticAreaItem.isRendered();
|
|
701
|
-
}
|
|
702
|
-
|
|
703
764
|
/**
|
|
704
765
|
* @private
|
|
705
766
|
*/
|
|
706
767
|
static _needsStaticArea() {
|
|
707
|
-
return
|
|
768
|
+
return !!this.staticAreaTemplate;
|
|
708
769
|
}
|
|
709
770
|
|
|
710
771
|
/**
|
|
711
772
|
* @public
|
|
712
773
|
*/
|
|
713
774
|
getStaticAreaItemDomRef() {
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
/**
|
|
718
|
-
* @private
|
|
719
|
-
*/
|
|
720
|
-
static _getDefaultState() {
|
|
721
|
-
if (this._defaultState) {
|
|
722
|
-
return this._defaultState;
|
|
775
|
+
if (!this.constructor._needsStaticArea()) {
|
|
776
|
+
throw new Error("This component does not use the static area");
|
|
723
777
|
}
|
|
724
778
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
// Initialize properties
|
|
730
|
-
const props = MetadataClass.getProperties();
|
|
731
|
-
for (const propName in props) { // eslint-disable-line
|
|
732
|
-
const propType = props[propName].type;
|
|
733
|
-
const propDefaultValue = props[propName].defaultValue;
|
|
734
|
-
|
|
735
|
-
if (propType === Boolean) {
|
|
736
|
-
defaultState[propName] = false;
|
|
737
|
-
|
|
738
|
-
if (propDefaultValue !== undefined) {
|
|
739
|
-
console.warn("The 'defaultValue' metadata key is ignored for all booleans properties, they would be initialized with 'false' by default"); // eslint-disable-line
|
|
740
|
-
}
|
|
741
|
-
} else if (props[propName].multiple) {
|
|
742
|
-
defaultState[propName] = [];
|
|
743
|
-
} else if (propType === Object) {
|
|
744
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : {};
|
|
745
|
-
} else if (propType === String) {
|
|
746
|
-
defaultState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : "";
|
|
747
|
-
} else {
|
|
748
|
-
defaultState[propName] = propDefaultValue;
|
|
749
|
-
}
|
|
779
|
+
if (!this.staticAreaItem) {
|
|
780
|
+
this.staticAreaItem = StaticAreaItem.createInstance();
|
|
781
|
+
this.staticAreaItem.setOwnerElement(this);
|
|
750
782
|
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
if (slotsAreManaged) {
|
|
754
|
-
const slots = MetadataClass.getSlots();
|
|
755
|
-
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
756
|
-
const propertyName = slotData.propertyName || slotName;
|
|
757
|
-
defaultState[propertyName] = [];
|
|
758
|
-
}
|
|
783
|
+
if (!this.staticAreaItem.parentElement) {
|
|
784
|
+
getSingletonElementInstance("ui5-static-area").appendChild(this.staticAreaItem);
|
|
759
785
|
}
|
|
760
786
|
|
|
761
|
-
this.
|
|
762
|
-
return defaultState;
|
|
787
|
+
return this.staticAreaItem.getDomRef();
|
|
763
788
|
}
|
|
764
789
|
|
|
765
790
|
/**
|
|
@@ -773,7 +798,7 @@ class UI5Element extends HTMLElement {
|
|
|
773
798
|
const properties = this.getMetadata().getProperties();
|
|
774
799
|
for (const [prop, propData] of Object.entries(properties)) { // eslint-disable-line
|
|
775
800
|
if (!isValidPropertyName(prop)) {
|
|
776
|
-
|
|
801
|
+
console.warn(`"${prop}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
777
802
|
}
|
|
778
803
|
|
|
779
804
|
if (propData.type === Boolean && propData.defaultValue) {
|
|
@@ -811,14 +836,27 @@ class UI5Element extends HTMLElement {
|
|
|
811
836
|
}
|
|
812
837
|
},
|
|
813
838
|
set(value) {
|
|
839
|
+
let isDifferent;
|
|
814
840
|
value = this.constructor.getMetadata().constructor.validatePropertyValue(value, propData);
|
|
815
841
|
|
|
816
842
|
const oldState = this._state[prop];
|
|
843
|
+
if (propData.multiple && propData.compareValues) {
|
|
844
|
+
isDifferent = !arraysAreEqual(oldState, value);
|
|
845
|
+
} else if (isDescendantOf(propData.type, DataType)) {
|
|
846
|
+
isDifferent = !propData.type.valuesAreEqual(oldState, value);
|
|
847
|
+
} else {
|
|
848
|
+
isDifferent = oldState !== value;
|
|
849
|
+
}
|
|
817
850
|
|
|
818
|
-
if (
|
|
851
|
+
if (isDifferent) {
|
|
819
852
|
this._state[prop] = value;
|
|
820
|
-
|
|
821
|
-
|
|
853
|
+
_invalidate.call(this, {
|
|
854
|
+
type: "property",
|
|
855
|
+
name: prop,
|
|
856
|
+
newValue: value,
|
|
857
|
+
oldValue: oldState,
|
|
858
|
+
});
|
|
859
|
+
this._updateAttribute(prop, value);
|
|
822
860
|
}
|
|
823
861
|
},
|
|
824
862
|
});
|
|
@@ -829,7 +867,7 @@ class UI5Element extends HTMLElement {
|
|
|
829
867
|
const slots = this.getMetadata().getSlots();
|
|
830
868
|
for (const [slotName, slotData] of Object.entries(slots)) { // eslint-disable-line
|
|
831
869
|
if (!isValidPropertyName(slotName)) {
|
|
832
|
-
|
|
870
|
+
console.warn(`"${slotName}" is not a valid property name. Use a name that does not collide with DOM APIs`); /* eslint-disable-line */
|
|
833
871
|
}
|
|
834
872
|
|
|
835
873
|
const propertyName = slotData.propertyName || slotName;
|
|
@@ -841,7 +879,7 @@ class UI5Element extends HTMLElement {
|
|
|
841
879
|
return [];
|
|
842
880
|
},
|
|
843
881
|
set() {
|
|
844
|
-
throw new Error("Cannot set
|
|
882
|
+
throw new Error("Cannot set slot content directly, use the DOM APIs (appendChild, removeChild, etc...)");
|
|
845
883
|
},
|
|
846
884
|
});
|
|
847
885
|
}
|
|
@@ -853,7 +891,7 @@ class UI5Element extends HTMLElement {
|
|
|
853
891
|
* @protected
|
|
854
892
|
*/
|
|
855
893
|
static get metadata() {
|
|
856
|
-
return
|
|
894
|
+
return {};
|
|
857
895
|
}
|
|
858
896
|
|
|
859
897
|
/**
|
|
@@ -872,6 +910,50 @@ class UI5Element extends HTMLElement {
|
|
|
872
910
|
return "";
|
|
873
911
|
}
|
|
874
912
|
|
|
913
|
+
/**
|
|
914
|
+
* Returns an array with the dependencies for this UI5 Web Component, which could be:
|
|
915
|
+
* - composed components (used in its shadow root or static area item)
|
|
916
|
+
* - slotted components that the component may need to communicate with
|
|
917
|
+
*
|
|
918
|
+
* @protected
|
|
919
|
+
*/
|
|
920
|
+
static get dependencies() {
|
|
921
|
+
return [];
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Returns a list of the unique dependencies for this UI5 Web Component
|
|
926
|
+
*
|
|
927
|
+
* @public
|
|
928
|
+
*/
|
|
929
|
+
static getUniqueDependencies() {
|
|
930
|
+
if (!uniqueDependenciesCache.has(this)) {
|
|
931
|
+
const filtered = this.dependencies.filter((dep, index, deps) => deps.indexOf(dep) === index);
|
|
932
|
+
uniqueDependenciesCache.set(this, filtered);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return uniqueDependenciesCache.get(this);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Returns a promise that resolves whenever all dependencies for this UI5 Web Component have resolved
|
|
940
|
+
*
|
|
941
|
+
* @returns {Promise<any[]>}
|
|
942
|
+
*/
|
|
943
|
+
static whenDependenciesDefined() {
|
|
944
|
+
return Promise.all(this.getUniqueDependencies().map(dep => dep.define()));
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Hook that will be called upon custom element definition
|
|
949
|
+
*
|
|
950
|
+
* @protected
|
|
951
|
+
* @returns {Promise<void>}
|
|
952
|
+
*/
|
|
953
|
+
static async onDefine() {
|
|
954
|
+
return Promise.resolve();
|
|
955
|
+
}
|
|
956
|
+
|
|
875
957
|
/**
|
|
876
958
|
* Registers a UI5 Web Component in the browser window object
|
|
877
959
|
* @public
|
|
@@ -880,21 +962,31 @@ class UI5Element extends HTMLElement {
|
|
|
880
962
|
static async define() {
|
|
881
963
|
await boot();
|
|
882
964
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
965
|
+
await Promise.all([
|
|
966
|
+
this.whenDependenciesDefined(),
|
|
967
|
+
this.onDefine(),
|
|
968
|
+
]);
|
|
886
969
|
|
|
887
970
|
const tag = this.getMetadata().getTag();
|
|
971
|
+
const altTag = this.getMetadata().getAltTag();
|
|
888
972
|
|
|
889
973
|
const definedLocally = isTagRegistered(tag);
|
|
890
974
|
const definedGlobally = customElements.get(tag);
|
|
891
975
|
|
|
892
976
|
if (definedGlobally && !definedLocally) {
|
|
893
|
-
|
|
977
|
+
recordTagRegistrationFailure(tag);
|
|
894
978
|
} else if (!definedGlobally) {
|
|
895
979
|
this._generateAccessors();
|
|
896
980
|
registerTag(tag);
|
|
897
981
|
window.customElements.define(tag, this);
|
|
982
|
+
preloadLinks(this);
|
|
983
|
+
|
|
984
|
+
if (altTag && !customElements.get(altTag)) {
|
|
985
|
+
registerTag(altTag);
|
|
986
|
+
window.customElements.define(altTag, getClassCopy(this, () => {
|
|
987
|
+
console.log(`The ${altTag} tag is deprecated and will be removed in the next release, please use ${tag} instead.`); // eslint-disable-line
|
|
988
|
+
}));
|
|
989
|
+
}
|
|
898
990
|
}
|
|
899
991
|
return this;
|
|
900
992
|
}
|