@ui5/webcomponents-base
Advanced tools
Comparing version 0.0.0-7d5f73b20 to 0.0.0-7d8c57f70
@@ -8,2 +8,3 @@ import { registerThemePropertiesLoader } from "./dist/AssetRegistry.js"; | ||
// Test components | ||
import "./test/elements/Accessor.js"; | ||
import "./test/elements/Generic.js"; | ||
@@ -35,7 +36,9 @@ import "./test/elements/NoShadowDOM.js"; | ||
import { getTheme, setTheme } from "./dist/config/Theme.js"; | ||
import { getThemeRoot, setThemeRoot } from "./dist/config/ThemeRoot.js"; | ||
import { getNoConflict, setNoConflict } from "./dist/config/NoConflict.js"; | ||
import { getRTL } from "./dist/config/RTL.js"; | ||
import { getFirstDayOfWeek } from "./dist/config/FormatSettings.js"; | ||
import { getFirstDayOfWeek, getLegacyDateCalendarCustomizing } from "./dist/config/FormatSettings.js"; | ||
import { _getRegisteredNames as getIconNames } from "./dist/asset-registries/Icons.js" | ||
import applyDirection from "./dist/locale/applyDirection.js"; | ||
import { getCurrentRuntimeIndex } from "./dist/Runtimes.js"; | ||
import LegacyDateFormats from "./dist/features/LegacyDateFormats.js"; | ||
@@ -48,2 +51,4 @@ window["sap-ui-webcomponents-bundle"] = { | ||
getTheme, | ||
getThemeRoot, | ||
setThemeRoot, | ||
setTheme, | ||
@@ -53,5 +58,6 @@ getNoConflict, | ||
getCalendarType, | ||
getRTL, | ||
getFirstDayOfWeek, | ||
getLegacyDateCalendarCustomizing, | ||
}, | ||
getCurrentRuntimeIndex, | ||
getIconNames, | ||
@@ -58,0 +64,0 @@ parseProperties, |
@@ -17,4 +17,4 @@ type I18nLoader = (localeId: string) => Promise<I18nData>; | ||
* It should be fully finished before the i18nBundle class is created in the webcomponents. | ||
* This method uses the bundle URLs that are populated by the <code>registerI18nBundle</code> method. | ||
* To simplify the usage, the synchronization of both methods happens internally for the same <code>bundleId</code> | ||
* This method uses the bundle URLs that are populated by the `registerI18nBundle` method. | ||
* To simplify the usage, the synchronization of both methods happens internally for the same `bundleId` | ||
* @param {packageName} packageName the NPM package name | ||
@@ -21,0 +21,0 @@ * @public |
@@ -51,2 +51,5 @@ import getLocale from "../locale/getLocale.js"; | ||
}; | ||
const useFallbackBundle = (packageName, localeId) => { | ||
return localeId !== DEFAULT_LANGUAGE && !_hasLoader(packageName, localeId); | ||
}; | ||
/** | ||
@@ -56,4 +59,4 @@ * This method preforms the asynchronous task of fetching the actual text resources. It will fetch | ||
* It should be fully finished before the i18nBundle class is created in the webcomponents. | ||
* This method uses the bundle URLs that are populated by the <code>registerI18nBundle</code> method. | ||
* To simplify the usage, the synchronization of both methods happens internally for the same <code>bundleId</code> | ||
* This method uses the bundle URLs that are populated by the `registerI18nBundle` method. | ||
* To simplify the usage, the synchronization of both methods happens internally for the same `bundleId` | ||
* @param {packageName} packageName the NPM package name | ||
@@ -65,5 +68,9 @@ * @public | ||
const region = getLocale().getRegion(); | ||
let localeId = normalizeLocale(language + (region ? `-${region}` : ``)); | ||
while (localeId !== DEFAULT_LANGUAGE && !_hasLoader(packageName, localeId)) { | ||
localeId = nextFallbackLocale(localeId); | ||
const variant = getLocale().getVariant(); | ||
let localeId = language + (region ? `-${region}` : ``) + (variant ? `-${variant}` : ``); | ||
if (useFallbackBundle(packageName, localeId)) { | ||
localeId = normalizeLocale(localeId); | ||
while (useFallbackBundle(packageName, localeId)) { | ||
localeId = nextFallbackLocale(localeId); | ||
} | ||
} | ||
@@ -70,0 +77,0 @@ // use default language unless configured to always fetch it from the network |
@@ -1,21 +0,22 @@ | ||
import { I18nText } from "../i18nBundle.js"; | ||
import { TemplateFunction } from "../renderer/executeTemplate.js"; | ||
type IconLoader = (collectionName: string) => Promise<CollectionData>; | ||
import type { I18nText } from "../i18nBundle.js"; | ||
import type { TemplateFunction } from "../renderer/executeTemplate.js"; | ||
type IconLoader = (collectionName: string) => Promise<CollectionData | Array<CollectionData>>; | ||
type CollectionData = { | ||
collection: string; | ||
packageName: string; | ||
themeFamily?: "legacy" | "sap_horizon"; | ||
version?: string; | ||
data: Record<string, { | ||
path: string; | ||
paths: Array<string>; | ||
ltr: boolean; | ||
acc: I18nText; | ||
path?: string; | ||
paths?: Array<string>; | ||
ltr?: boolean; | ||
acc?: I18nText; | ||
}>; | ||
}; | ||
type IconData = { | ||
collection?: string; | ||
collection: string; | ||
packageName: string; | ||
pathData: string | Array<string>; | ||
ltr: boolean; | ||
accData: I18nText; | ||
ltr?: boolean; | ||
accData?: I18nText; | ||
customTemplate?: TemplateFunction; | ||
@@ -26,6 +27,14 @@ viewBox?: string; | ||
declare const registerIcon: (name: string, iconData: IconData) => void; | ||
declare const getIconDataSync: (name: string) => IconData | undefined; | ||
declare const getIconData: (name: string) => Promise<IconData | "ICON_NOT_FOUND" | undefined>; | ||
declare const getIconDataSync: (iconName: string) => IconData | undefined; | ||
declare const getIconData: (iconName: string) => Promise<IconData | "ICON_NOT_FOUND" | undefined>; | ||
/** | ||
* Returns the accessible name for the given icon, | ||
* or undefined if accessible name is not present. | ||
* | ||
* @param { string } name | ||
* @return { Promise } | ||
*/ | ||
declare const getIconAccessibleName: (name: string) => Promise<string | undefined>; | ||
declare const _getRegisteredNames: () => Promise<string[]>; | ||
export { registerIconLoader, getIconData, getIconDataSync, registerIcon, _getRegisteredNames, }; | ||
export { registerIconLoader, getIconData, getIconDataSync, getIconAccessibleName, registerIcon, _getRegisteredNames, }; | ||
export type { IconData, CollectionData, }; |
import getSharedResource from "../getSharedResource.js"; | ||
import IconCollectionsAlias from "../assets-meta/IconCollectionsAlias.js"; | ||
import { getEffectiveDefaultIconCollection } from "../config/Icons.js"; | ||
import { getIconCollectionByAlias } from "./util/IconCollectionsAlias.js"; | ||
import { registerIconCollectionForTheme } from "./util/IconCollectionsByTheme.js"; | ||
import getEffectiveIconCollection from "./util/getIconCollectionByTheme.js"; | ||
import { getI18nBundle } from "../i18nBundle.js"; | ||
const DEFAULT_THEME_FAMILY = "legacy"; // includes sap_belize_* and sap_fiori_* | ||
const loaders = new Map(); | ||
@@ -25,3 +28,3 @@ const registry = getSharedResource("SVGIcons.registry", new Map()); | ||
registerIcon(iconName, { | ||
pathData: iconData.path || iconData.paths, | ||
pathData: (iconData.path || iconData.paths), | ||
ltr: iconData.ltr, | ||
@@ -36,5 +39,2 @@ accData: iconData.acc, | ||
const registerIcon = (name, iconData) => { | ||
if (!iconData.collection) { | ||
iconData.collection = getEffectiveDefaultIconCollection(); | ||
} | ||
const key = `${iconData.collection}/${name}`; | ||
@@ -48,5 +48,14 @@ registry.set(key, { | ||
viewBox: iconData.viewBox, | ||
collection: iconData.collection, | ||
}); | ||
}; | ||
const _parseName = (name) => { | ||
/** | ||
* Processes the full icon name and splits it into - "name", "collection". | ||
* - removes legacy protocol ("sap-icon://") | ||
* - resolves aliases (f.e "SAP-icons-TNT/actor" => "tnt/actor") | ||
* | ||
* @param { string } name | ||
* @return { object } | ||
*/ | ||
const processName = (name) => { | ||
// silently support ui5-compatible URIs | ||
@@ -58,22 +67,17 @@ if (name.startsWith("sap-icon://")) { | ||
[name, collection] = name.split("/").reverse(); | ||
collection = collection || getEffectiveDefaultIconCollection(); | ||
// Normalize collection name. | ||
// - resolve `SAP-icons-TNT` to `tnt`. | ||
// - resolve `BusinessSuiteInAppSymbols` to `business-suite`. | ||
// - resolve `horizon` to `SAP-icons-v5`, | ||
// Note: aliases can be made as a feature, if more collections need it or more aliases are needed. | ||
collection = _normalizeCollection(collection); | ||
name = name.replace("icon-", ""); | ||
const registryKey = `${collection}/${name}`; | ||
return { name, collection, registryKey }; | ||
if (collection) { | ||
collection = getIconCollectionByAlias(collection); | ||
} | ||
return { name, collection }; | ||
}; | ||
const getIconDataSync = (name) => { | ||
const { registryKey } = _parseName(name); | ||
return registry.get(registryKey); | ||
const getIconDataSync = (iconName) => { | ||
const { name, collection } = processName(iconName); | ||
return getRegisteredIconData(collection, name); | ||
}; | ||
const getIconData = async (name) => { | ||
const { collection, registryKey } = _parseName(name); | ||
const getIconData = async (iconName) => { | ||
const { name, collection } = processName(iconName); | ||
let iconData = ICON_NOT_FOUND; | ||
try { | ||
iconData = (await _loadIconCollectionOnce(collection)); | ||
iconData = (await _loadIconCollectionOnce(getEffectiveIconCollection(collection))); | ||
} | ||
@@ -87,8 +91,42 @@ catch (error) { | ||
} | ||
if (!registry.has(registryKey)) { | ||
// not filled by another await. many getters will await on the same loader, but fill only once | ||
const registeredIconData = getRegisteredIconData(collection, name); | ||
if (registeredIconData) { | ||
return registeredIconData; | ||
} | ||
// not filled by another await. many getters will await on the same loader, but fill only once | ||
if (Array.isArray(iconData)) { | ||
iconData.forEach(data => { | ||
_fillRegistry(data); | ||
registerIconCollectionForTheme(collection, { [data.themeFamily || DEFAULT_THEME_FAMILY]: data.collection }); | ||
}); | ||
} | ||
else { | ||
_fillRegistry(iconData); | ||
} | ||
return getRegisteredIconData(collection, name); | ||
}; | ||
const getRegisteredIconData = (collection, name) => { | ||
const registryKey = `${getEffectiveIconCollection(collection)}/${name}`; | ||
return registry.get(registryKey); | ||
}; | ||
/** | ||
* Returns the accessible name for the given icon, | ||
* or undefined if accessible name is not present. | ||
* | ||
* @param { string } name | ||
* @return { Promise } | ||
*/ | ||
const getIconAccessibleName = async (name) => { | ||
if (!name) { | ||
return; | ||
} | ||
let iconData = getIconDataSync(name); | ||
if (!iconData) { | ||
iconData = await getIconData(name); | ||
} | ||
if (iconData && iconData !== ICON_NOT_FOUND && iconData.accData) { | ||
const i18nBundle = await getI18nBundle(iconData.packageName); | ||
return i18nBundle.getText(iconData.accData); | ||
} | ||
}; | ||
// test page usage only | ||
@@ -102,9 +140,3 @@ const _getRegisteredNames = async () => { | ||
}; | ||
const _normalizeCollection = (collectionName) => { | ||
if (IconCollectionsAlias[collectionName]) { | ||
return IconCollectionsAlias[collectionName]; | ||
} | ||
return collectionName; | ||
}; | ||
export { registerIconLoader, getIconData, getIconDataSync, registerIcon, _getRegisteredNames, }; | ||
export { registerIconLoader, getIconData, getIconDataSync, getIconAccessibleName, registerIcon, _getRegisteredNames, }; | ||
//# sourceMappingURL=Icons.js.map |
@@ -1,2 +0,2 @@ | ||
import { I18nText } from "../i18nBundle.js"; | ||
import type { I18nText } from "../i18nBundle.js"; | ||
type IllustrationLoader = (illustrationName: string) => Promise<IllustrationData>; | ||
@@ -7,2 +7,3 @@ type IllustrationProperties = { | ||
spotSvg: string; | ||
dotSvg: string; | ||
title: I18nText; | ||
@@ -13,2 +14,3 @@ subtitle: I18nText; | ||
set: string; | ||
collection: string; | ||
}; | ||
@@ -15,0 +17,0 @@ declare const registerIllustration: (name: string, data: IllustrationData) => void; |
import getSharedResource from "../getSharedResource.js"; | ||
import { getTheme } from "../config/Theme.js"; | ||
const IllustrationCollections = new Map([ | ||
["sap_horizon", "V5"], | ||
["sap_horizon_dark", "V5"], | ||
["sap_horizon_hcb", "V5/HC"], | ||
["sap_horizon_hcw", "V5/HC"], | ||
]); | ||
const FALLBACK_COLLECTION = "V4"; | ||
const loaders = new Map(); | ||
const registry = getSharedResource("SVGIllustration.registry", new Map()); | ||
const illustrationPromises = getSharedResource("SVGIllustration.promises", new Map()); | ||
const getCollection = () => { | ||
const theme = getTheme(); | ||
if (IllustrationCollections.has(theme)) { | ||
return IllustrationCollections.get(theme); | ||
} | ||
return FALLBACK_COLLECTION; | ||
}; | ||
/** | ||
* Processes the name of the illustration | ||
* The name is used to generate the registry key and the loader key | ||
* The registry key is used to store and get the illustration data from the registry | ||
* The loader key is used to store and get the illustration loader from the loaders map | ||
* The function generates the correct registry key and loader key based on whether an loader exists for the illustration | ||
* If there is no loader registered for the collection, it falls back to the default collection | ||
*/ | ||
const processName = (name) => { | ||
let collection = getCollection(); | ||
const [set, illustrationName] = name.split("/"); | ||
let registryKey = `${set}/${collection}/${illustrationName}`; | ||
if (!loaders.has(registryKey) && collection !== FALLBACK_COLLECTION) { | ||
collection = FALLBACK_COLLECTION; | ||
registryKey = `${set}/${collection}/${illustrationName}`; | ||
} | ||
return { | ||
registryKey, | ||
collection, | ||
}; | ||
}; | ||
const registerIllustration = (name, data) => { | ||
registry.set(`${data.set}/${name}`, { | ||
const collection = data.collection || FALLBACK_COLLECTION; | ||
registry.set(`${data.set}/${collection}/${name}`, { | ||
dialogSvg: data.dialogSvg, | ||
sceneSvg: data.sceneSvg, | ||
spotSvg: data.spotSvg, | ||
dotSvg: data.dotSvg, | ||
title: data.title, | ||
@@ -17,31 +55,24 @@ subtitle: data.subtitle, | ||
}; | ||
const _loadIllustrationOnce = async (illustrationName) => { | ||
if (!illustrationPromises.has(illustrationName)) { | ||
if (!loaders.has(illustrationName)) { | ||
const illustrationPath = illustrationName.startsWith("Tnt") ? `tnt/${illustrationName.replace(/^Tnt/, "")}` : illustrationName; | ||
const _loadIllustrationOnce = (illustrationName) => { | ||
const { registryKey } = processName(illustrationName); | ||
if (!illustrationPromises.has(registryKey)) { | ||
if (!loaders.has(registryKey)) { | ||
const illustrationPath = illustrationName.startsWith("fiori/") ? illustrationName.replace("fiori/", "") : illustrationName; | ||
throw new Error(`No loader registered for the ${illustrationName} illustration. Probably you forgot to import the "@ui5/webcomponents-fiori/dist/illustrations/${illustrationPath}.js" module. Or you can import the "@ui5/webcomponents-fiori/dist/illustrations/AllIllustrations.js" module that will make all illustrations available, but fetch only the ones used.`); | ||
} | ||
const loadIllustrations = loaders.get(illustrationName); | ||
illustrationPromises.set(illustrationName, loadIllustrations(illustrationName)); | ||
const loadIllustrations = loaders.get(registryKey); | ||
illustrationPromises.set(registryKey, loadIllustrations(registryKey)); | ||
} | ||
return illustrationPromises.get(illustrationName); | ||
return illustrationPromises.get(registryKey); | ||
}; | ||
const getIllustrationDataSync = (illustrationName) => { | ||
let set = "fiori"; | ||
if (illustrationName.startsWith("Tnt")) { | ||
set = "tnt"; | ||
illustrationName = illustrationName.replace(/^Tnt/, ""); | ||
} | ||
return registry.get(`${set}/${illustrationName}`); | ||
const { registryKey } = processName(illustrationName); | ||
return registry.get(registryKey); | ||
}; | ||
const getIllustrationData = async (illustrationName) => { | ||
let set = "fiori"; | ||
const { registryKey } = processName(illustrationName); | ||
await _loadIllustrationOnce(illustrationName); | ||
if (illustrationName.startsWith("Tnt")) { | ||
set = "tnt"; | ||
illustrationName = illustrationName.replace(/^Tnt/, ""); | ||
} | ||
return registry.get(`${set}/${illustrationName}`); | ||
return registry.get(registryKey); | ||
}; | ||
export { getIllustrationDataSync, registerIllustration, registerIllustrationLoader, getIllustrationData, }; | ||
//# sourceMappingURL=Illustrations.js.map |
@@ -126,3 +126,3 @@ import { attachLanguageChange } from "../locale/languageChange.js"; | ||
registerLocaleDataLoader("en", async () => { | ||
const cldrContent = await fetch(`https://sdk.openui5.org/1.103.0/resources/sap/ui/core/cldr/en.json`); | ||
const cldrContent = await fetch(`https://sdk.openui5.org/1.120.5/resources/sap/ui/core/cldr/en.json`); | ||
return cldrContent.json(); | ||
@@ -129,0 +129,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
import { StyleData, StyleDataCSP } from "../types.js"; | ||
import type { StyleData, StyleDataCSP } from "../ManagedStyles.js"; | ||
type ThemeData = { | ||
@@ -7,5 +7,7 @@ _: StyleDataCSP; | ||
declare const registerThemePropertiesLoader: (packageName: string, themeName: string, loader: ThemeLoader) => void; | ||
declare const getThemeProperties: (packageName: string, themeName: string) => Promise<StyleData | undefined>; | ||
declare const registerCustomThemePropertiesLoader: (packageName: string, themeName: string, loader: ThemeLoader) => void; | ||
declare const getThemeProperties: (packageName: string, themeName: string, externalThemeName?: string) => Promise<StyleData | undefined>; | ||
declare const getRegisteredPackages: () => Set<string>; | ||
declare const isThemeRegistered: (theme: string) => boolean; | ||
export { registerThemePropertiesLoader, getThemeProperties, getRegisteredPackages, isThemeRegistered, }; | ||
export { registerThemePropertiesLoader, registerCustomThemePropertiesLoader, getThemeProperties, getRegisteredPackages, isThemeRegistered, }; | ||
export type { ThemeData, ThemeLoader, }; |
import { DEFAULT_THEME } from "../generated/AssetParameters.js"; | ||
import { mergeStyles } from "../ManagedStyles.js"; | ||
import { fireThemeRegistered } from "../theming/ThemeRegistered.js"; | ||
const themeStyles = new Map(); | ||
const loaders = new Map(); | ||
const customLoaders = new Map(); | ||
const registeredPackages = new Set(); | ||
@@ -10,7 +13,12 @@ const registeredThemes = new Set(); | ||
registeredThemes.add(themeName); | ||
fireThemeRegistered(themeName); | ||
}; | ||
const getThemeProperties = async (packageName, themeName) => { | ||
const style = themeStyles.get(`${packageName}_${themeName}`); | ||
if (style !== undefined) { // it's valid for style to be an empty string | ||
return style; | ||
const registerCustomThemePropertiesLoader = (packageName, themeName, loader) => { | ||
customLoaders.set(`${packageName}/${themeName}`, loader); | ||
}; | ||
const getThemeProperties = async (packageName, themeName, externalThemeName) => { | ||
const cacheKey = `${packageName}_${themeName}_${externalThemeName || ""}`; | ||
const cachedStyleData = themeStyles.get(cacheKey); | ||
if (cachedStyleData !== undefined) { // it's valid for style to be an empty string | ||
return cachedStyleData; | ||
} | ||
@@ -22,9 +30,20 @@ if (!registeredThemes.has(themeName)) { | ||
} | ||
return _getThemeProperties(packageName, themeName); | ||
const [style, customStyle] = await Promise.all([ | ||
_getThemeProperties(packageName, themeName), | ||
externalThemeName ? _getThemeProperties(packageName, externalThemeName, true) : undefined, | ||
]); | ||
const styleData = mergeStyles(style, customStyle); | ||
if (styleData) { | ||
themeStyles.set(cacheKey, styleData); | ||
} | ||
return styleData; | ||
}; | ||
const _getThemeProperties = async (packageName, themeName) => { | ||
const loader = loaders.get(`${packageName}/${themeName}`); | ||
const _getThemeProperties = async (packageName, themeName, forCustomTheme = false) => { | ||
const loadersMap = forCustomTheme ? customLoaders : loaders; | ||
const loader = loadersMap.get(`${packageName}/${themeName}`); | ||
if (!loader) { | ||
// no themes for package | ||
console.error(`Theme [${themeName}] not registered for package [${packageName}]`); /* eslint-disable-line */ | ||
if (!forCustomTheme) { | ||
console.error(`Theme [${themeName}] not registered for package [${packageName}]`); /* eslint-disable-line */ | ||
} | ||
return; | ||
@@ -42,3 +61,2 @@ } | ||
const themeProps = data._ || data; // Refactor: remove _ everywhere | ||
themeStyles.set(`${packageName}_${themeName}`, themeProps); | ||
return themeProps; | ||
@@ -52,3 +70,3 @@ }; | ||
}; | ||
export { registerThemePropertiesLoader, getThemeProperties, getRegisteredPackages, isThemeRegistered, }; | ||
export { registerThemePropertiesLoader, registerCustomThemePropertiesLoader, getThemeProperties, getRegisteredPackages, isThemeRegistered, }; | ||
//# sourceMappingURL=Themes.js.map |
import { registerI18nLoader } from "./asset-registries/i18n.js"; | ||
import { registerLocaleDataLoader } from "./asset-registries/LocaleData.js"; | ||
import { registerThemePropertiesLoader } from "./asset-registries/Themes.js"; | ||
import { registerThemePropertiesLoader, registerCustomThemePropertiesLoader } from "./asset-registries/Themes.js"; | ||
import { registerIconLoader } from "./asset-registries/Icons.js"; | ||
export { registerI18nLoader, registerLocaleDataLoader, registerThemePropertiesLoader, registerIconLoader, }; | ||
export { registerI18nLoader, registerLocaleDataLoader, registerThemePropertiesLoader, registerCustomThemePropertiesLoader, registerIconLoader, }; |
import { registerI18nLoader } from "./asset-registries/i18n.js"; | ||
import { registerLocaleDataLoader } from "./asset-registries/LocaleData.js"; | ||
import { registerThemePropertiesLoader } from "./asset-registries/Themes.js"; | ||
import { registerThemePropertiesLoader, registerCustomThemePropertiesLoader } from "./asset-registries/Themes.js"; | ||
import { registerIconLoader } from "./asset-registries/Icons.js"; | ||
export { registerI18nLoader, registerLocaleDataLoader, registerThemePropertiesLoader, registerIconLoader, }; | ||
export { registerI18nLoader, registerLocaleDataLoader, registerThemePropertiesLoader, registerCustomThemePropertiesLoader, registerIconLoader, }; | ||
//# sourceMappingURL=AssetRegistry.js.map |
@@ -0,8 +1,10 @@ | ||
declare const isBooted: () => boolean; | ||
/** | ||
* Attach a callback that will be executed on boot | ||
* Attaches a callback that will be executed after boot finishes. | ||
* **Note:** If the framework already booted, the callback will be immediately executed. | ||
* @public | ||
* @param listener | ||
* @param { Function } listener | ||
*/ | ||
declare const attachBoot: (listener: () => void) => Promise<void>; | ||
declare const attachBoot: (listener: () => void) => void; | ||
declare const boot: () => Promise<void>; | ||
export { boot, attachBoot, }; | ||
export { boot, attachBoot, isBooted, }; |
import whenDOMReady from "./util/whenDOMReady.js"; | ||
import EventProvider from "./EventProvider.js"; | ||
import insertFontFace from "./FontFace.js"; | ||
@@ -8,10 +9,20 @@ import insertSystemCSSVars from "./SystemCSSVars.js"; | ||
import { getFeature } from "./FeaturesRegistry.js"; | ||
import { attachThemeRegistered } from "./theming/ThemeRegistered.js"; | ||
let booted = false; | ||
let bootPromise; | ||
const eventProvider = new EventProvider(); | ||
const isBooted = () => { | ||
return booted; | ||
}; | ||
/** | ||
* Attach a callback that will be executed on boot | ||
* Attaches a callback that will be executed after boot finishes. | ||
* **Note:** If the framework already booted, the callback will be immediately executed. | ||
* @public | ||
* @param listener | ||
* @param { Function } listener | ||
*/ | ||
const attachBoot = async (listener) => { | ||
await boot(); | ||
const attachBoot = (listener) => { | ||
if (!booted) { | ||
eventProvider.attachEvent("boot", listener); | ||
return; | ||
} | ||
listener(); | ||
@@ -25,4 +36,9 @@ }; | ||
registerCurrentRuntime(); | ||
if (typeof document === "undefined") { | ||
resolve(); | ||
return; | ||
} | ||
attachThemeRegistered(onThemeRegistered); | ||
const openUI5Support = getFeature("OpenUI5Support"); | ||
const isOpenUI5Loaded = openUI5Support ? openUI5Support.isLoaded() : false; | ||
const isOpenUI5Loaded = openUI5Support ? openUI5Support.isOpenUI5Detected() : false; | ||
const f6Navigation = getFeature("F6Navigation"); | ||
@@ -41,2 +57,4 @@ if (openUI5Support) { | ||
resolve(); | ||
booted = true; | ||
await eventProvider.fireEventAsync("boot"); | ||
}; | ||
@@ -46,3 +64,15 @@ bootPromise = new Promise(bootExecutor); | ||
}; | ||
export { boot, attachBoot, }; | ||
/** | ||
* Callback, executed after theme properties registration | ||
* to apply the newly registered theme. | ||
* @private | ||
* @param { string } theme | ||
*/ | ||
const onThemeRegistered = (theme) => { | ||
const currentTheme = getTheme(); | ||
if (booted && theme === currentTheme) { | ||
applyTheme(currentTheme); | ||
} | ||
}; | ||
export { boot, attachBoot, isBooted, }; | ||
//# sourceMappingURL=Boot.js.map |
@@ -7,3 +7,3 @@ import AnimationMode from "../types/AnimationMode.js"; | ||
*/ | ||
declare const getAnimationMode: () => AnimationMode; | ||
declare const getAnimationMode: () => `${AnimationMode}`; | ||
/** | ||
@@ -14,3 +14,3 @@ * Sets the animation mode - "full", "basic", "minimal" or "none". | ||
*/ | ||
declare const setAnimationMode: (animationMode: AnimationMode) => void; | ||
declare const setAnimationMode: (animationMode: `${AnimationMode}`) => void; | ||
export { getAnimationMode, setAnimationMode, }; |
@@ -21,3 +21,3 @@ import { getAnimationMode as getConfiguredAnimationMode } from "../InitialConfiguration.js"; | ||
const setAnimationMode = (animationMode) => { | ||
if (Object.values(AnimationMode).includes(animationMode)) { | ||
if (animationMode in AnimationMode) { | ||
curAnimationMode = animationMode; | ||
@@ -24,0 +24,0 @@ } |
@@ -8,2 +8,9 @@ import CalendarType from "../types/CalendarType.js"; | ||
declare const getCalendarType: () => CalendarType; | ||
export { getCalendarType }; | ||
/** | ||
* Returns the configured secondary calendar type. | ||
* @public | ||
* @returns { CalendarType | undefined } the effective calendar type | ||
* @since 1.18.0 | ||
*/ | ||
declare const getSecondaryCalendarType: () => CalendarType | undefined; | ||
export { getCalendarType, getSecondaryCalendarType, }; |
import CalendarType from "../types/CalendarType.js"; | ||
import { getCalendarType as getConfiguredCalendarType } from "../InitialConfiguration.js"; | ||
import { getCalendarType as getConfiguredCalendarType, getSecondaryCalendarType as getConfiguredSecondaryCalendarType, } from "../InitialConfiguration.js"; | ||
let calendarType; | ||
let secondaryCalendarType; | ||
/** | ||
@@ -18,3 +19,18 @@ * Returns the configured or default calendar type. | ||
}; | ||
export { getCalendarType }; // eslint-disable-line | ||
/** | ||
* Returns the configured secondary calendar type. | ||
* @public | ||
* @returns { CalendarType | undefined } the effective calendar type | ||
* @since 1.18.0 | ||
*/ | ||
const getSecondaryCalendarType = () => { | ||
if (secondaryCalendarType === undefined) { | ||
secondaryCalendarType = getConfiguredSecondaryCalendarType(); | ||
} | ||
if (secondaryCalendarType && secondaryCalendarType in CalendarType) { | ||
return secondaryCalendarType; | ||
} | ||
return secondaryCalendarType; | ||
}; | ||
export { getCalendarType, getSecondaryCalendarType, }; | ||
//# sourceMappingURL=CalendarType.js.map |
@@ -0,3 +1,6 @@ | ||
import LegacyDateFormats from "../features/LegacyDateFormats.js"; | ||
import type { LegacyDateCalendarCustomizing } from "../features/LegacyDateFormats.js"; | ||
type FormatSettings = { | ||
firstDayOfWeek?: number; | ||
legacyDateCalendarCustomizing?: LegacyDateCalendarCustomizing; | ||
}; | ||
@@ -10,3 +13,4 @@ /** | ||
declare const getFirstDayOfWeek: () => number | undefined; | ||
export { getFirstDayOfWeek }; | ||
declare const getLegacyDateCalendarCustomizing: typeof LegacyDateFormats.getLegacyDateCalendarCustomizing; | ||
export { getFirstDayOfWeek, getLegacyDateCalendarCustomizing, }; | ||
export type { FormatSettings }; |
@@ -0,2 +1,4 @@ | ||
import LegacyDateFormats from "../features/LegacyDateFormats.js"; | ||
import { getFormatSettings } from "../InitialConfiguration.js"; | ||
import { getFeature } from "../FeaturesRegistry.js"; | ||
let formatSettings; | ||
@@ -14,3 +16,5 @@ /** | ||
}; | ||
export { getFirstDayOfWeek }; // eslint-disable-line | ||
const legacyDateFormats = getFeature("LegacyDateFormats"); | ||
const getLegacyDateCalendarCustomizing = legacyDateFormats ? LegacyDateFormats.getLegacyDateCalendarCustomizing : () => { return []; }; | ||
export { getFirstDayOfWeek, getLegacyDateCalendarCustomizing, }; | ||
//# sourceMappingURL=FormatSettings.js.map |
@@ -1,30 +0,40 @@ | ||
declare enum IconCollection { | ||
v4 = "SAP-icons", | ||
v5 = "SAP-icons-v5" | ||
} | ||
type IconCollection = string; | ||
/** | ||
* Sets the default icon collection (SAP-icons font v4 or SAP-icons font v5) per theme, | ||
* which will be applied in case icon collection is not specified. | ||
* Sets the default icon collection for a given theme. | ||
* | ||
* Note: by default SAP-icons-v5 is used in all SAP Horizon variants and SAP-icons-v4 for all the rest. | ||
* SAP Icons is the default icon collection (that resolves to SAP-icons version 5.x in Horizon theme family and SAP-icons version 4.x in all other themes) | ||
* and to display icons from other collections, you have to specify the icon collection in addition to the icon name, for example: "tnt/actor", "business-suite/1x2-grid-layout", etc. | ||
* This method allows setting another (built-in or custom) icon collection as default per theme. | ||
* | ||
* **Usage** | ||
* **For example**, to make "SAP-icons version 5.x" the default icon collection in "sap_fiori_3": | ||
* | ||
* ``` | ||
* setDefaultIconCollection("sap_fiori_3", "SAP-icons-v5"); | ||
* | ||
* <ui5-icon name="home"></ui5-icon> | ||
* ``` | ||
* | ||
* **For example**, to make a custom icon collection (with name "my-custom-collection") the default icon collection in "sap_fiori_3": | ||
* | ||
* ``` | ||
* setDefaultIconCollection("sap_fiori_3", "my-custom-collection"); | ||
* | ||
* <ui5-icon name="custom-icon-name"></ui5-icon> | ||
* ``` | ||
* | ||
* @public | ||
* @param {string} theme | ||
* @param {IconCollection} collectionName | ||
* @param { string } theme | ||
* @param { string } collectionName | ||
*/ | ||
declare const setDefaultIconCollection: (theme: string, collectionName: "horizon" | IconCollection) => void; | ||
declare const setDefaultIconCollection: (theme: string, collectionName: IconCollection) => void; | ||
/** | ||
* Returns the default icon collection (v4 or v5) for given theme, | ||
* that is configured. | ||
* Returns the configured default icon collection for a given theme. | ||
* | ||
* @param {string} theme | ||
* @param { string } theme | ||
* @public | ||
* @returns {string | undefined} | ||
* @returns { string | undefined } | ||
*/ | ||
declare const getDefaultIconCollection: (theme: string) => string | undefined; | ||
/** | ||
* Returns the effective icon collection that will be applied for icon web components | ||
* whenever namespace is not specified. | ||
* @returns {string} | ||
*/ | ||
declare const getEffectiveDefaultIconCollection: () => string; | ||
export { setDefaultIconCollection, getDefaultIconCollection, getEffectiveDefaultIconCollection, }; | ||
export { setDefaultIconCollection, getDefaultIconCollection, }; | ||
export type { IconCollection, }; |
@@ -1,30 +0,39 @@ | ||
import { getTheme, isThemeFamily } from "./Theme.js"; | ||
const IconCollectionConfiguration = new Map(); | ||
var IconCollection; | ||
(function (IconCollection) { | ||
IconCollection["v4"] = "SAP-icons"; | ||
IconCollection["v5"] = "SAP-icons-v5"; | ||
})(IconCollection || (IconCollection = {})); | ||
/** | ||
* Sets the default icon collection (SAP-icons font v4 or SAP-icons font v5) per theme, | ||
* which will be applied in case icon collection is not specified. | ||
* Sets the default icon collection for a given theme. | ||
* | ||
* Note: by default SAP-icons-v5 is used in all SAP Horizon variants and SAP-icons-v4 for all the rest. | ||
* SAP Icons is the default icon collection (that resolves to SAP-icons version 5.x in Horizon theme family and SAP-icons version 4.x in all other themes) | ||
* and to display icons from other collections, you have to specify the icon collection in addition to the icon name, for example: "tnt/actor", "business-suite/1x2-grid-layout", etc. | ||
* This method allows setting another (built-in or custom) icon collection as default per theme. | ||
* | ||
* **Usage** | ||
* **For example**, to make "SAP-icons version 5.x" the default icon collection in "sap_fiori_3": | ||
* | ||
* ``` | ||
* setDefaultIconCollection("sap_fiori_3", "SAP-icons-v5"); | ||
* | ||
* <ui5-icon name="home"></ui5-icon> | ||
* ``` | ||
* | ||
* **For example**, to make a custom icon collection (with name "my-custom-collection") the default icon collection in "sap_fiori_3": | ||
* | ||
* ``` | ||
* setDefaultIconCollection("sap_fiori_3", "my-custom-collection"); | ||
* | ||
* <ui5-icon name="custom-icon-name"></ui5-icon> | ||
* ``` | ||
* | ||
* @public | ||
* @param {string} theme | ||
* @param {IconCollection} collectionName | ||
* @param { string } theme | ||
* @param { string } collectionName | ||
*/ | ||
const setDefaultIconCollection = (theme, collectionName) => { | ||
if (collectionName === "horizon") { | ||
collectionName = IconCollection.v5; | ||
} | ||
IconCollectionConfiguration.set(theme, collectionName); | ||
}; | ||
/** | ||
* Returns the default icon collection (v4 or v5) for given theme, | ||
* that is configured. | ||
* Returns the configured default icon collection for a given theme. | ||
* | ||
* @param {string} theme | ||
* @param { string } theme | ||
* @public | ||
* @returns {string | undefined} | ||
* @returns { string | undefined } | ||
*/ | ||
@@ -34,16 +43,3 @@ const getDefaultIconCollection = (theme) => { | ||
}; | ||
/** | ||
* Returns the effective icon collection that will be applied for icon web components | ||
* whenever namespace is not specified. | ||
* @returns {string} | ||
*/ | ||
const getEffectiveDefaultIconCollection = () => { | ||
const currentTheme = getTheme(); | ||
const currentThemeConfiguration = IconCollectionConfiguration.get(currentTheme); | ||
if (currentThemeConfiguration) { | ||
return currentThemeConfiguration; | ||
} | ||
return isThemeFamily("sap_horizon") ? IconCollection.v5 : IconCollection.v4; | ||
}; | ||
export { setDefaultIconCollection, getDefaultIconCollection, getEffectiveDefaultIconCollection, }; | ||
export { setDefaultIconCollection, getDefaultIconCollection, }; | ||
//# sourceMappingURL=Icons.js.map |
@@ -17,5 +17,14 @@ /** | ||
/** | ||
* Returns the default languague. | ||
* | ||
* Note: Default language might be different than the configurated one. | ||
* | ||
* @public | ||
* @returns {string} | ||
*/ | ||
declare const getDefaultLanguage: () => string; | ||
/** | ||
* Defines if the default language, that is inlined, should be | ||
* fetched over the network instead of using the inlined one. | ||
* <b>Note:</b> By default the language will not be fetched. | ||
* **Note:** By default the language will not be fetched. | ||
* | ||
@@ -32,2 +41,2 @@ * @public | ||
declare const getFetchDefaultLanguage: () => boolean; | ||
export { getLanguage, setLanguage, setFetchDefaultLanguage, getFetchDefaultLanguage, }; | ||
export { getLanguage, setLanguage, getDefaultLanguage, setFetchDefaultLanguage, getFetchDefaultLanguage, }; |
import { getLanguage as getConfiguredLanguage, getFetchDefaultLanguage as getConfiguredFetchDefaultLanguage, } from "../InitialConfiguration.js"; | ||
import { fireLanguageChange } from "../locale/languageChange.js"; | ||
import { reRenderAllUI5Elements } from "../Render.js"; | ||
import { DEFAULT_LANGUAGE } from "../generated/AssetParameters.js"; | ||
import { isBooted } from "../Boot.js"; | ||
let curLanguage; | ||
@@ -30,9 +32,22 @@ let fetchDefaultLanguage; | ||
curLanguage = language; | ||
await fireLanguageChange(language); | ||
await reRenderAllUI5Elements({ languageAware: true }); | ||
if (isBooted()) { | ||
await fireLanguageChange(language); | ||
await reRenderAllUI5Elements({ languageAware: true }); | ||
} | ||
}; | ||
/** | ||
* Returns the default languague. | ||
* | ||
* Note: Default language might be different than the configurated one. | ||
* | ||
* @public | ||
* @returns {string} | ||
*/ | ||
const getDefaultLanguage = () => { | ||
return DEFAULT_LANGUAGE; | ||
}; | ||
/** | ||
* Defines if the default language, that is inlined, should be | ||
* fetched over the network instead of using the inlined one. | ||
* <b>Note:</b> By default the language will not be fetched. | ||
* **Note:** By default the language will not be fetched. | ||
* | ||
@@ -56,3 +71,3 @@ * @public | ||
}; | ||
export { getLanguage, setLanguage, setFetchDefaultLanguage, getFetchDefaultLanguage, }; | ||
export { getLanguage, setLanguage, getDefaultLanguage, setFetchDefaultLanguage, getFetchDefaultLanguage, }; | ||
//# sourceMappingURL=Language.js.map |
@@ -5,2 +5,3 @@ import { getNoConflict as getConfiguredNoConflict } from "../InitialConfiguration.js"; | ||
"value-changed", | ||
"click", | ||
]; | ||
@@ -7,0 +8,0 @@ let noConflict; |
@@ -15,2 +15,11 @@ /** | ||
/** | ||
* Returns the default theme. | ||
* | ||
* Note: Default theme might be different than the configurated one. | ||
* | ||
* @public | ||
* @returns {string} | ||
*/ | ||
declare const getDefaultTheme: () => string; | ||
/** | ||
* Returns if the given theme name is the one currently applied. | ||
@@ -23,8 +32,9 @@ * @private | ||
/** | ||
* Returns if the current theme is part of given theme family. | ||
* Returns if the currently set theme is part of legacy theme families ("sap_belize" or "sap_fiori_3"). | ||
* **Note**: in addition, the method checks the base theme of a custom theme, built via the ThemeDesigner. | ||
* | ||
* @private | ||
* @param {string} theme the theme family | ||
* @returns {boolean} | ||
* @returns { boolean } | ||
*/ | ||
declare const isThemeFamily: (theme: string) => boolean; | ||
export { getTheme, setTheme, isTheme, isThemeFamily, }; | ||
declare const isLegacyThemeFamily: () => boolean; | ||
export { getTheme, setTheme, isTheme, isLegacyThemeFamily, getDefaultTheme, }; |
import { getTheme as getConfiguredTheme } from "../InitialConfiguration.js"; | ||
import { reRenderAllUI5Elements } from "../Render.js"; | ||
import applyTheme from "../theming/applyTheme.js"; | ||
import getThemeDesignerTheme from "../theming/getThemeDesignerTheme.js"; | ||
import { DEFAULT_THEME, SUPPORTED_THEMES } from "../generated/AssetParameters.js"; | ||
import { isBooted } from "../Boot.js"; | ||
let curTheme; | ||
@@ -27,7 +30,20 @@ /** | ||
curTheme = theme; | ||
// Update CSS Custom Properties | ||
await applyTheme(curTheme); | ||
await reRenderAllUI5Elements({ themeAware: true }); | ||
if (isBooted()) { | ||
// Update CSS Custom Properties | ||
await applyTheme(curTheme); | ||
await reRenderAllUI5Elements({ themeAware: true }); | ||
} | ||
}; | ||
/** | ||
* Returns the default theme. | ||
* | ||
* Note: Default theme might be different than the configurated one. | ||
* | ||
* @public | ||
* @returns {string} | ||
*/ | ||
const getDefaultTheme = () => { | ||
return DEFAULT_THEME; | ||
}; | ||
/** | ||
* Returns if the given theme name is the one currently applied. | ||
@@ -43,11 +59,17 @@ * @private | ||
/** | ||
* Returns if the current theme is part of given theme family. | ||
* Returns if the currently set theme is part of legacy theme families ("sap_belize" or "sap_fiori_3"). | ||
* **Note**: in addition, the method checks the base theme of a custom theme, built via the ThemeDesigner. | ||
* | ||
* @private | ||
* @param {string} theme the theme family | ||
* @returns {boolean} | ||
* @returns { boolean } | ||
*/ | ||
const isThemeFamily = (theme) => { | ||
return getTheme().startsWith(theme); | ||
const isLegacyThemeFamily = () => { | ||
const currentTheme = getTheme(); | ||
if (!isKnownTheme(currentTheme)) { | ||
return !getThemeDesignerTheme()?.baseThemeName?.startsWith("sap_horizon"); | ||
} | ||
return !currentTheme.startsWith("sap_horizon"); | ||
}; | ||
export { getTheme, setTheme, isTheme, isThemeFamily, }; | ||
const isKnownTheme = (theme) => SUPPORTED_THEMES.includes(theme); | ||
export { getTheme, setTheme, isTheme, isLegacyThemeFamily, getDefaultTheme, }; | ||
//# sourceMappingURL=Theme.js.map |
@@ -11,6 +11,8 @@ /** | ||
/** | ||
* Call this function to enable or disable the usage of <link> tags instead of <style> tags to achieve CSP compliance | ||
* Example: "setUseLinks(true)" will unconditionally use <link> tags for all browsers; | ||
* Example: "setUseLinks(!document.adoptedStyleSheets) will only enable the usage of <link> tags for browsers that do not support constructable stylesheets. | ||
* Call this function to enable or disable the usage of `<link>` tags instead of `<style>` tags to achieve CSP compliance | ||
* | ||
* Example: "setUseLinks(true)" will unconditionally use `<link>` tags for all browsers. | ||
* | ||
* Example: "setUseLinks(!document.adoptedStyleSheets) will only enable the usage of `<link>` tags for browsers that do not support constructable stylesheets. | ||
* | ||
* @public | ||
@@ -21,6 +23,7 @@ * @param use whether links will be used | ||
/** | ||
* Call this function to enable or disable the preloading of <link> tags. | ||
* Note: only taken into account when <link> tags are being used. | ||
* Note: links are being preloaded by default, so call "setPreloadLinks(false)" to opt out of this. | ||
* Call this function to enable or disable the preloading of `<link>` tags. | ||
* | ||
* **Note:** only taken into account when `<link>` tags are being used. | ||
* **Note:** links are being preloaded by default, so call "setPreloadLinks(false)" to opt out of this. | ||
* | ||
* @public | ||
@@ -27,0 +30,0 @@ * @param preload |
@@ -23,6 +23,8 @@ const roots = new Map(); | ||
/** | ||
* Call this function to enable or disable the usage of <link> tags instead of <style> tags to achieve CSP compliance | ||
* Example: "setUseLinks(true)" will unconditionally use <link> tags for all browsers; | ||
* Example: "setUseLinks(!document.adoptedStyleSheets) will only enable the usage of <link> tags for browsers that do not support constructable stylesheets. | ||
* Call this function to enable or disable the usage of `<link>` tags instead of `<style>` tags to achieve CSP compliance | ||
* | ||
* Example: "setUseLinks(true)" will unconditionally use `<link>` tags for all browsers. | ||
* | ||
* Example: "setUseLinks(!document.adoptedStyleSheets) will only enable the usage of `<link>` tags for browsers that do not support constructable stylesheets. | ||
* | ||
* @public | ||
@@ -35,6 +37,7 @@ * @param use whether links will be used | ||
/** | ||
* Call this function to enable or disable the preloading of <link> tags. | ||
* Note: only taken into account when <link> tags are being used. | ||
* Note: links are being preloaded by default, so call "setPreloadLinks(false)" to opt out of this. | ||
* Call this function to enable or disable the preloading of `<link>` tags. | ||
* | ||
* **Note:** only taken into account when `<link>` tags are being used. | ||
* **Note:** links are being preloaded by default, so call "setPreloadLinks(false)" to opt out of this. | ||
* | ||
* @public | ||
@@ -41,0 +44,0 @@ * @param preload |
@@ -1,7 +0,7 @@ | ||
import { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag } from "./CustomElementsScopeUtils.js"; | ||
import { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, getScopedVarName } from "./CustomElementsScopeUtils.js"; | ||
declare class LitStatic { | ||
static html: (strings: TemplateStringsArray, ...values: unknown[]) => import("lit-html").TemplateResult<1 | 2>; | ||
static svg: (strings: TemplateStringsArray, ...values: unknown[]) => import("lit-html").TemplateResult<1 | 2>; | ||
static html: (strings: TemplateStringsArray, ...values: unknown[]) => import("lit-html").TemplateResult; | ||
static svg: (strings: TemplateStringsArray, ...values: unknown[]) => import("lit-html").TemplateResult; | ||
static unsafeStatic: (value: string) => object; | ||
} | ||
export { LitStatic, setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, }; | ||
export { LitStatic, setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, getScopedVarName, }; |
import { html, svg, unsafeStatic, } from "lit-html/static.js"; | ||
import { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, } from "./CustomElementsScopeUtils.js"; | ||
import { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, getScopedVarName, } from "./CustomElementsScopeUtils.js"; | ||
import { registerFeature } from "./FeaturesRegistry.js"; | ||
@@ -10,3 +10,3 @@ class LitStatic { | ||
registerFeature("LitStatic", LitStatic); | ||
export { LitStatic, setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, }; | ||
export { LitStatic, setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, getScopedVarName, }; | ||
//# sourceMappingURL=CustomElementsScope.js.map |
@@ -55,2 +55,9 @@ type Rules = { | ||
declare const getEffectiveScopingSuffixForTag: (tag: string) => string | undefined; | ||
export { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, }; | ||
/** | ||
* @public | ||
* Used for getting a scoped name for a CSS variable using the same transformation used in the build | ||
* @name the name of the css variable as written in the code | ||
* @returns a variable name with the current version inserted as available at runtime | ||
*/ | ||
declare const getScopedVarName: (name: string) => string; | ||
export { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, getScopedVarName, }; |
@@ -0,1 +1,2 @@ | ||
import VersionInfo from "./generated/VersionInfo.js"; | ||
let suf; | ||
@@ -89,3 +90,14 @@ let rulesObj = { | ||
}; | ||
export { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, }; | ||
/** | ||
* @public | ||
* Used for getting a scoped name for a CSS variable using the same transformation used in the build | ||
* @name the name of the css variable as written in the code | ||
* @returns a variable name with the current version inserted as available at runtime | ||
*/ | ||
const getScopedVarName = (name) => { | ||
const versionStr = `v${VersionInfo.version.replaceAll(".", "-")}`; | ||
const expr = /(--_?ui5)([^,:)\s]+)/g; | ||
return name.replaceAll(expr, `$1-${versionStr}$2`); | ||
}; | ||
export { setCustomElementsScopingSuffix, getCustomElementsScopingSuffix, setCustomElementsScopingRules, getCustomElementsScopingRules, shouldScopeCustomElement, getEffectiveScopingSuffixForTag, getScopedVarName, }; | ||
//# sourceMappingURL=CustomElementsScopeUtils.js.map |
@@ -0,8 +1,24 @@ | ||
import type UI5Element from "../UI5Element.js"; | ||
import type { Renderer } from "../UI5Element.js"; | ||
import type { TemplateFunction as Template } from "../renderer/executeTemplate.js"; | ||
import type { ComponentStylesData as Styles } from "../types.js"; | ||
/** | ||
* Returns a custom element class decorator. | ||
* | ||
* @param { string } tag | ||
* @param { string | object } tagNameOrComponentSettings | ||
* @returns { ClassDecorator } | ||
*/ | ||
declare const customElement: (tag: string) => ClassDecorator; | ||
declare const customElement: (tagNameOrComponentSettings?: string | { | ||
tag?: string; | ||
renderer?: Renderer; | ||
styles?: Styles; | ||
template?: Template; | ||
dependencies?: Array<typeof UI5Element>; | ||
staticAreaStyles?: Styles; | ||
staticAreaTemplate?: Template; | ||
languageAware?: boolean; | ||
themeAware?: boolean; | ||
fastNavigation?: boolean; | ||
features?: Array<string>; | ||
}) => ClassDecorator; | ||
export default customElement; |
/** | ||
* Returns a custom element class decorator. | ||
* | ||
* @param { string } tag | ||
* @param { string | object } tagNameOrComponentSettings | ||
* @returns { ClassDecorator } | ||
*/ | ||
const customElement = (tag) => { | ||
const customElement = (tagNameOrComponentSettings = {}) => { | ||
return (target) => { | ||
if (!Object.prototype.hasOwnProperty.call(target, "decoratorMetadata")) { | ||
target.decoratorMetadata = {}; | ||
if (!Object.prototype.hasOwnProperty.call(target, "metadata")) { | ||
target.metadata = {}; | ||
} | ||
target.decoratorMetadata.tag = tag; | ||
if (typeof tagNameOrComponentSettings === "string") { | ||
target.metadata.tag = tagNameOrComponentSettings; | ||
return; | ||
} | ||
const { tag, languageAware, themeAware, fastNavigation, features, } = tagNameOrComponentSettings; | ||
target.metadata.tag = tag; | ||
if (languageAware) { | ||
target.metadata.languageAware = languageAware; | ||
} | ||
if (features) { | ||
target.metadata.features = features; | ||
} | ||
if (themeAware) { | ||
target.metadata.themeAware = themeAware; | ||
} | ||
if (fastNavigation) { | ||
target.metadata.fastNavigation = fastNavigation; | ||
} | ||
["render", "renderer", "template", "staticAreaTemplate", "styles", "staticAreaStyles", "dependencies"].forEach((customElementEntity) => { | ||
const customElementEntityValue = tagNameOrComponentSettings[customElementEntity]; | ||
customElementEntityValue && Object.defineProperty(target, customElementEntity, { | ||
get: () => tagNameOrComponentSettings[customElementEntity], | ||
}); | ||
}); | ||
}; | ||
@@ -14,0 +37,0 @@ }; |
@@ -1,2 +0,1 @@ | ||
import { EventData } from "../UI5ElementMetadata.js"; | ||
/** | ||
@@ -9,3 +8,7 @@ * Returns an event class decorator. | ||
*/ | ||
declare const event: (name: string, data?: EventData) => ClassDecorator; | ||
declare const event: <EventDetail>(name: string, data?: { | ||
detail?: Record<keyof EventDetail, { | ||
type: any; | ||
}> | undefined; | ||
}) => ClassDecorator; | ||
export default event; |
@@ -10,10 +10,10 @@ /** | ||
return (target) => { | ||
if (!Object.prototype.hasOwnProperty.call(target, "decoratorMetadata")) { | ||
target.decoratorMetadata = {}; | ||
if (!Object.prototype.hasOwnProperty.call(target, "metadata")) { | ||
target.metadata = {}; | ||
} | ||
const decoratorMetadata = target.decoratorMetadata; | ||
if (!decoratorMetadata.events) { | ||
decoratorMetadata.events = {}; | ||
const metadata = target.metadata; | ||
if (!metadata.events) { | ||
metadata.events = {}; | ||
} | ||
const eventsMetadata = decoratorMetadata.events; | ||
const eventsMetadata = metadata.events; | ||
if (!eventsMetadata[name]) { | ||
@@ -20,0 +20,0 @@ eventsMetadata[name] = data; |
@@ -10,10 +10,10 @@ /** | ||
const ctor = target.constructor; | ||
if (!Object.prototype.hasOwnProperty.call(ctor, "decoratorMetadata")) { | ||
ctor.decoratorMetadata = {}; | ||
if (!Object.prototype.hasOwnProperty.call(ctor, "metadata")) { | ||
ctor.metadata = {}; | ||
} | ||
const decoratorMetadata = ctor.decoratorMetadata; | ||
if (!decoratorMetadata.properties) { | ||
decoratorMetadata.properties = {}; | ||
const metadata = ctor.metadata; | ||
if (!metadata.properties) { | ||
metadata.properties = {}; | ||
} | ||
const propsMetadata = decoratorMetadata.properties; | ||
const propsMetadata = metadata.properties; | ||
if (!propsMetadata[propertyKey]) { | ||
@@ -20,0 +20,0 @@ propsMetadata[propertyKey] = propData || { type: String }; |
@@ -10,14 +10,14 @@ /** | ||
const ctor = target.constructor; | ||
if (!Object.prototype.hasOwnProperty.call(ctor, "decoratorMetadata")) { | ||
ctor.decoratorMetadata = {}; | ||
if (!Object.prototype.hasOwnProperty.call(ctor, "metadata")) { | ||
ctor.metadata = {}; | ||
} | ||
const decoratorMetadata = ctor.decoratorMetadata; | ||
if (!decoratorMetadata.slots) { | ||
decoratorMetadata.slots = {}; | ||
const metadata = ctor.metadata; | ||
if (!metadata.slots) { | ||
metadata.slots = {}; | ||
} | ||
const slotMetadata = decoratorMetadata.slots; | ||
if (slotData?.default && slotMetadata.default) { | ||
const slotMetadata = metadata.slots; | ||
if (slotData && slotData.default && slotMetadata.default) { | ||
throw new Error("Only one slot can be the default slot."); | ||
} | ||
const key = slotData?.default ? "default" : slotKey; | ||
const key = slotData && slotData.default ? "default" : slotKey; | ||
slotData = slotData || { type: HTMLElement }; | ||
@@ -34,3 +34,3 @@ if (!slotData.type) { | ||
} | ||
ctor.decoratorMetadata.managedSlots = true; | ||
ctor.metadata.managedSlots = true; | ||
}; | ||
@@ -37,0 +37,0 @@ }; |
@@ -6,3 +6,3 @@ import NavigationMode from "../types/NavigationMode.js"; | ||
id: string; | ||
_tabIndex: string; | ||
forcedTabIndex: string; | ||
} | ||
@@ -31,4 +31,4 @@ type ItemNavigationOptions = { | ||
* Each item passed to ItemNavigation via "getItemsCallback" must be: | ||
* - A) either a UI5Element with a "_tabIndex" property | ||
* - B) or an Object with "id" and "_tabIndex" properties which represents a part of the root component's shadow DOM. | ||
* - A) either a UI5Element with a "forcedTabIndex" property | ||
* - B) or an Object with "id" and "forcedTabIndex" properties which represents a part of the root component's shadow DOM. | ||
* The "id" must be a valid ID within the shadow root of the component ItemNavigation operates on. | ||
@@ -39,7 +39,7 @@ * This object must not be a DOM object because, as said, ItemNavigation will not set "tabindex" on it. It must be a representation of a DOM object only | ||
* | ||
* Whenever the user navigates with the keyboard, ItemNavigation will modify the "_tabIndex" properties of the items. | ||
* It is the items' responsibilities to re-render themselves and apply the correct value of "tabindex" (i.e. to map the "_tabIndex" ItemNavigation set to them to the "tabindex" property). | ||
* If the items of the ItemNavigation are UI5Elements themselves, this can happen naturally since they will be invalidated by their "_tabIndex" property. | ||
* If the items are Objects with "id" and "_tabIndex" however, it is the developer's responsibility to apply these and the easiest way is to have the root component invalidated by ItemNavigation. | ||
* To do so, set the "affectedPropertiesNames" constructor property to point to one or more of the root component's properties that need refreshing when "_tabIndex" is changed deeply. | ||
* Whenever the user navigates with the keyboard, ItemNavigation will modify the "forcedTabIndex" properties of the items. | ||
* It is the items' responsibilities to re-render themselves and apply the correct value of "tabindex" (i.e. to map the "forcedTabIndex" ItemNavigation set to them to the "tabindex" property). | ||
* If the items of the ItemNavigation are UI5Elements themselves, this can happen naturally since they will be invalidated by their "forcedTabIndex" property. | ||
* If the items are Objects with "id" and "forcedTabIndex" however, it is the developer's responsibility to apply these and the easiest way is to have the root component invalidated by ItemNavigation. | ||
* To do so, set the "affectedPropertiesNames" constructor property to point to one or more of the root component's properties that need refreshing when "forcedTabIndex" is changed deeply. | ||
* | ||
@@ -62,2 +62,3 @@ * 2) Call the "setCurrentItem" method of ItemNavigation whenever you want to change the current item. | ||
_skipItemsSize: number | null; | ||
_initBound: () => void; | ||
/** | ||
@@ -64,0 +65,0 @@ * |
@@ -19,4 +19,4 @@ import { isDown, isUp, isLeft, isRight, isHome, isEnd, isPageDown, isPageUp, } from "../Keys.js"; | ||
* Each item passed to ItemNavigation via "getItemsCallback" must be: | ||
* - A) either a UI5Element with a "_tabIndex" property | ||
* - B) or an Object with "id" and "_tabIndex" properties which represents a part of the root component's shadow DOM. | ||
* - A) either a UI5Element with a "forcedTabIndex" property | ||
* - B) or an Object with "id" and "forcedTabIndex" properties which represents a part of the root component's shadow DOM. | ||
* The "id" must be a valid ID within the shadow root of the component ItemNavigation operates on. | ||
@@ -27,7 +27,7 @@ * This object must not be a DOM object because, as said, ItemNavigation will not set "tabindex" on it. It must be a representation of a DOM object only | ||
* | ||
* Whenever the user navigates with the keyboard, ItemNavigation will modify the "_tabIndex" properties of the items. | ||
* It is the items' responsibilities to re-render themselves and apply the correct value of "tabindex" (i.e. to map the "_tabIndex" ItemNavigation set to them to the "tabindex" property). | ||
* If the items of the ItemNavigation are UI5Elements themselves, this can happen naturally since they will be invalidated by their "_tabIndex" property. | ||
* If the items are Objects with "id" and "_tabIndex" however, it is the developer's responsibility to apply these and the easiest way is to have the root component invalidated by ItemNavigation. | ||
* To do so, set the "affectedPropertiesNames" constructor property to point to one or more of the root component's properties that need refreshing when "_tabIndex" is changed deeply. | ||
* Whenever the user navigates with the keyboard, ItemNavigation will modify the "forcedTabIndex" properties of the items. | ||
* It is the items' responsibilities to re-render themselves and apply the correct value of "tabindex" (i.e. to map the "forcedTabIndex" ItemNavigation set to them to the "tabindex" property). | ||
* If the items of the ItemNavigation are UI5Elements themselves, this can happen naturally since they will be invalidated by their "forcedTabIndex" property. | ||
* If the items are Objects with "id" and "forcedTabIndex" however, it is the developer's responsibility to apply these and the easiest way is to have the root component invalidated by ItemNavigation. | ||
* To do so, set the "affectedPropertiesNames" constructor property to point to one or more of the root component's properties that need refreshing when "forcedTabIndex" is changed deeply. | ||
* | ||
@@ -62,5 +62,4 @@ * 2) Call the "setCurrentItem" method of ItemNavigation whenever you want to change the current item. | ||
this.rootWebComponent.addEventListener("keydown", this._onkeydown.bind(this)); | ||
this.rootWebComponent._onComponentStateFinalized = () => { | ||
this._init(); | ||
}; | ||
this._initBound = this._init.bind(this); | ||
this.rootWebComponent.attachComponentStateFinalized(this._initBound); | ||
if (typeof options.getItemsCallback !== "function") { | ||
@@ -104,3 +103,3 @@ throw new Error("getItemsCallback is required"); | ||
this._getItems().forEach((item, idx) => { | ||
item._tabIndex = (idx === this._currentIndex) ? "0" : "-1"; | ||
item.forcedTabIndex = (idx === this._currentIndex) ? "0" : "-1"; | ||
}); | ||
@@ -273,3 +272,3 @@ } | ||
for (let i = 0; i < items.length; i++) { | ||
items[i]._tabIndex = i === this._currentIndex ? "0" : "-1"; | ||
items[i].forcedTabIndex = i === this._currentIndex ? "0" : "-1"; | ||
} | ||
@@ -284,3 +283,3 @@ this._affectedPropertiesNames.forEach(propName => { | ||
if (currentItem) { | ||
currentItem.focus({ focusVisible: true }); | ||
currentItem.focus(); | ||
} | ||
@@ -317,3 +316,3 @@ } | ||
if (currentItem.id) { | ||
return currentItemDOMRef.querySelector(`#${currentItem.id}`); | ||
return currentItemDOMRef.querySelector(`[id="${currentItem.id}"]`); | ||
} | ||
@@ -320,0 +319,0 @@ } |
@@ -1,2 +0,2 @@ | ||
type ResizeObserverCallback = () => void; | ||
type ResizeObserverCallback = () => Promise<void> | void; | ||
/** | ||
@@ -10,13 +10,11 @@ * Allows to register/deregister resize observers for a DOM element | ||
/** | ||
* @static | ||
* @public | ||
* @param {*} element UI5 Web Component or DOM Element to be observed | ||
* @param {*} callback Callback to be executed | ||
* @param element UI5 Web Component or DOM Element to be observed | ||
* @param callback Callback to be executed | ||
*/ | ||
static register(element: HTMLElement, callback: ResizeObserverCallback): void; | ||
/** | ||
* @static | ||
* @public | ||
* @param {*} element UI5 Web Component or DOM Element to be unobserved | ||
* @param {*} callback Callback to be removed | ||
* @param element UI5 Web Component or DOM Element to be unobserved | ||
* @param callback Callback to be removed | ||
*/ | ||
@@ -26,1 +24,2 @@ static deregister(element: HTMLElement, callback: ResizeObserverCallback): void; | ||
export default ResizeHandler; | ||
export type { ResizeObserverCallback, }; |
@@ -7,5 +7,9 @@ import { instanceOfUI5Element } from "../UI5Element.js"; | ||
resizeObserver = new window.ResizeObserver(entries => { | ||
entries.forEach(entry => { | ||
const callbacks = observedElements.get(entry.target); | ||
callbacks?.forEach((callback) => callback()); | ||
window.requestAnimationFrame(() => { | ||
entries.forEach(entry => { | ||
const callbacks = observedElements.get(entry.target); | ||
// Callbacks could be async and we need to handle returned promises to comply with the eslint "no-misused-promises" rule. | ||
// Although Promise.all awaits all, we don't await the additional task after calling the callbacks and should not make any difference. | ||
callbacks && Promise.all(callbacks.map((callback) => callback())); | ||
}); | ||
}); | ||
@@ -47,6 +51,5 @@ }); | ||
/** | ||
* @static | ||
* @public | ||
* @param {*} element UI5 Web Component or DOM Element to be observed | ||
* @param {*} callback Callback to be executed | ||
* @param element UI5 Web Component or DOM Element to be observed | ||
* @param callback Callback to be executed | ||
*/ | ||
@@ -66,6 +69,5 @@ static register(element, callback) { | ||
/** | ||
* @static | ||
* @public | ||
* @param {*} element UI5 Web Component or DOM Element to be unobserved | ||
* @param {*} callback Callback to be removed | ||
* @param element UI5 Web Component or DOM Element to be unobserved | ||
* @param callback Callback to be removed | ||
*/ | ||
@@ -72,0 +74,0 @@ static deregister(element, callback) { |
@@ -95,3 +95,3 @@ import { supportsTouch } from "../Device.js"; | ||
} | ||
if (!this.supportsTouch) { | ||
if (!touch) { | ||
document.addEventListener("mouseup", this.mouseUp, { passive: true }); | ||
@@ -105,3 +105,3 @@ document.addEventListener("mousemove", this.mouseMove, { passive: true }); | ||
} | ||
if (this.supportsTouch && event instanceof TouchEvent) { | ||
if (touch) { | ||
this._prevDragX = touch.pageX; | ||
@@ -108,0 +108,0 @@ this._prevDragY = touch.pageY; |
@@ -11,3 +11,4 @@ declare const supportsTouch: () => boolean; | ||
declare const isIOS: () => boolean; | ||
declare const isMac: () => boolean; | ||
declare const isAndroid: () => boolean; | ||
export { supportsTouch, isIE, isSafari, isChrome, isFirefox, isPhone, isTablet, isDesktop, isCombi, isIOS, isAndroid, }; | ||
export { supportsTouch, isIE, isSafari, isChrome, isFirefox, isPhone, isTablet, isDesktop, isCombi, isIOS, isAndroid, isMac, }; |
@@ -1,16 +0,85 @@ | ||
const ua = navigator.userAgent; | ||
const touch = "ontouchstart" in window || navigator.maxTouchPoints > 0; | ||
const ie = /(msie|trident)/i.test(ua); | ||
const chrome = !ie && /(Chrome|CriOS)/.test(ua); | ||
const firefox = /Firefox/.test(ua); | ||
const safari = !ie && !chrome && /(Version|PhantomJS)\/(\d+\.\d+).*Safari/.test(ua); | ||
const webkit = !ie && /webkit/.test(ua); | ||
const windows = navigator.platform.indexOf("Win") !== -1; | ||
const iOS = !!(navigator.platform.match(/iPhone|iPad|iPod/)) || !!(navigator.userAgent.match(/Mac/) && "ontouchend" in document); | ||
const android = !windows && /Android/.test(ua); | ||
const androidPhone = android && /(?=android)(?=.*mobile)/i.test(ua); | ||
const ipad = /ipad/i.test(ua) || (/Macintosh/i.test(ua) && "ontouchend" in document); | ||
// With iOS 13 the string 'iPad' was removed from the user agent string through a browser setting, which is applied on all sites by default: | ||
// "Request Desktop Website -> All websites" (for more infos see: https://forums.developer.apple.com/thread/119186). | ||
// Therefore the OS is detected as MACINTOSH instead of iOS and the device is a tablet if the Device.support.touch is true. | ||
const isSSR = typeof document === "undefined"; | ||
const internals = { | ||
get userAgent() { | ||
if (isSSR) { | ||
return ""; | ||
} | ||
return navigator.userAgent; | ||
}, | ||
get touch() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return "ontouchstart" in window || navigator.maxTouchPoints > 0; | ||
}, | ||
get ie() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return /(msie|trident)/i.test(internals.userAgent); | ||
}, | ||
get chrome() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return !internals.ie && /(Chrome|CriOS)/.test(internals.userAgent); | ||
}, | ||
get firefox() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return /Firefox/.test(internals.userAgent); | ||
}, | ||
get safari() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return !internals.ie && !internals.chrome && /(Version|PhantomJS)\/(\d+\.\d+).*Safari/.test(internals.userAgent); | ||
}, | ||
get webkit() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return !internals.ie && /webkit/.test(internals.userAgent); | ||
}, | ||
get windows() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return navigator.platform.indexOf("Win") !== -1; | ||
}, | ||
get macOS() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return !!navigator.userAgent.match(/Macintosh|Mac OS X/i); | ||
}, | ||
get iOS() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return !!(navigator.platform.match(/iPhone|iPad|iPod/)) || !!(internals.userAgent.match(/Mac/) && "ontouchend" in document); | ||
}, | ||
get android() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return !internals.windows && /Android/.test(internals.userAgent); | ||
}, | ||
get androidPhone() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return internals.android && /(?=android)(?=.*mobile)/i.test(internals.userAgent); | ||
}, | ||
get ipad() { | ||
if (isSSR) { | ||
return false; | ||
} | ||
// With iOS 13 the string 'iPad' was removed from the user agent string through a browser setting, which is applied on all sites by default: | ||
// "Request Desktop Website -> All websites" (for more infos see: https://forums.developer.apple.com/thread/119186). | ||
// Therefore the OS is detected as MACINTOSH instead of iOS and the device is a tablet if the Device.support.touch is true. | ||
return /ipad/i.test(internals.userAgent) || (/Macintosh/i.test(internals.userAgent) && "ontouchend" in document); | ||
}, | ||
}; | ||
let windowsVersion; | ||
@@ -20,7 +89,10 @@ let webkitVersion; | ||
const isWindows8OrAbove = () => { | ||
if (!windows) { | ||
if (isSSR) { | ||
return false; | ||
} | ||
if (!internals.windows) { | ||
return false; | ||
} | ||
if (windowsVersion === undefined) { | ||
const matches = ua.match(/Windows NT (\d+).(\d)/); | ||
const matches = internals.userAgent.match(/Windows NT (\d+).(\d)/); | ||
windowsVersion = matches ? parseFloat(matches[1]) : 0; | ||
@@ -31,7 +103,10 @@ } | ||
const isWebkit537OrAbove = () => { | ||
if (!webkit) { | ||
if (isSSR) { | ||
return false; | ||
} | ||
if (!internals.webkit) { | ||
return false; | ||
} | ||
if (webkitVersion === undefined) { | ||
const matches = ua.match(/(webkit)[ /]([\w.]+)/); | ||
const matches = internals.userAgent.match(/(webkit)[ /]([\w.]+)/); | ||
webkitVersion = matches ? parseFloat(matches[1]) : 0; | ||
@@ -42,10 +117,13 @@ } | ||
const detectTablet = () => { | ||
if (isSSR) { | ||
return false; | ||
} | ||
if (tablet !== undefined) { | ||
return; | ||
} | ||
if (ipad) { | ||
if (internals.ipad) { | ||
tablet = true; | ||
return; | ||
} | ||
if (touch) { | ||
if (internals.touch) { | ||
if (isWindows8OrAbove()) { | ||
@@ -55,8 +133,8 @@ tablet = true; | ||
} | ||
if (chrome && android) { | ||
tablet = !/Mobile Safari\/[.0-9]+/.test(ua); | ||
if (internals.chrome && internals.android) { | ||
tablet = !/Mobile Safari\/[.0-9]+/.test(internals.userAgent); | ||
return; | ||
} | ||
let densityFactor = window.devicePixelRatio ? window.devicePixelRatio : 1; // may be undefined in Windows Phone devices | ||
if (android && isWebkit537OrAbove()) { | ||
if (internals.android && isWebkit537OrAbove()) { | ||
densityFactor = 1; | ||
@@ -67,18 +145,21 @@ } | ||
} | ||
tablet = (ie && ua.indexOf("Touch") !== -1) || (android && !androidPhone); | ||
tablet = (internals.ie && internals.userAgent.indexOf("Touch") !== -1) || (internals.android && !internals.androidPhone); | ||
}; | ||
const supportsTouch = () => touch; | ||
const isIE = () => ie; | ||
const isSafari = () => safari; | ||
const isChrome = () => chrome; | ||
const isFirefox = () => firefox; | ||
const supportsTouch = () => internals.touch; | ||
const isIE = () => internals.ie; | ||
const isSafari = () => internals.safari; | ||
const isChrome = () => internals.chrome; | ||
const isFirefox = () => internals.firefox; | ||
const isTablet = () => { | ||
detectTablet(); | ||
return (touch || isWindows8OrAbove()) && tablet; | ||
return (internals.touch || isWindows8OrAbove()) && tablet; | ||
}; | ||
const isPhone = () => { | ||
detectTablet(); | ||
return touch && !tablet; | ||
return internals.touch && !tablet; | ||
}; | ||
const isDesktop = () => { | ||
if (isSSR) { | ||
return false; | ||
} | ||
return (!isTablet() && !isPhone()) || isWindows8OrAbove(); | ||
@@ -90,8 +171,11 @@ }; | ||
const isIOS = () => { | ||
return iOS; | ||
return internals.iOS; | ||
}; | ||
const isMac = () => { | ||
return internals.macOS; | ||
}; | ||
const isAndroid = () => { | ||
return android || androidPhone; | ||
return internals.android || internals.androidPhone; | ||
}; | ||
export { supportsTouch, isIE, isSafari, isChrome, isFirefox, isPhone, isTablet, isDesktop, isCombi, isIOS, isAndroid, }; | ||
export { supportsTouch, isIE, isSafari, isChrome, isFirefox, isPhone, isTablet, isDesktop, isCombi, isIOS, isAndroid, isMac, }; | ||
//# sourceMappingURL=Device.js.map |
@@ -44,3 +44,3 @@ class EventProvider { | ||
return eventListeners.map(fn => { | ||
return fn.call(this, data); // eslint-disable-line | ||
return fn.call(this, data); | ||
}); | ||
@@ -47,0 +47,0 @@ } |
@@ -8,2 +8,5 @@ declare class F6Navigation { | ||
attachEventListeners(): void; | ||
groupElementToFocus(nextElement: HTMLElement): Promise<HTMLElement | undefined>; | ||
findNextFocusableGroupElement(currentIndex: number): Promise<HTMLElement | undefined>; | ||
findPreviousFocusableGroupElement(currentIndex: number): Promise<HTMLElement | undefined>; | ||
_keydownHandler(event: KeyboardEvent): Promise<void>; | ||
@@ -10,0 +13,0 @@ removeEventListeners(): void; |
@@ -6,2 +6,3 @@ import { registerFeature } from "../FeaturesRegistry.js"; | ||
import getFastNavigationGroups from "../util/getFastNavigationGroups.js"; | ||
import isElementClickable from "../util/isElementClickable.js"; | ||
class F6Navigation { | ||
@@ -17,43 +18,47 @@ constructor() { | ||
} | ||
async _keydownHandler(event) { | ||
if (isF6Next(event)) { | ||
this.updateGroups(); | ||
if (this.groups.length < 1) { | ||
return; | ||
async groupElementToFocus(nextElement) { | ||
const nextElementDomRef = instanceOfUI5Element(nextElement) ? nextElement.getDomRef() : nextElement; | ||
if (nextElementDomRef) { | ||
if (isElementClickable(nextElementDomRef)) { | ||
return nextElementDomRef; | ||
} | ||
event.preventDefault(); | ||
let nextIndex = -1; | ||
const elementToFocus = await getFirstFocusableElement(nextElementDomRef); | ||
if (elementToFocus) { | ||
return elementToFocus; | ||
} | ||
} | ||
} | ||
async findNextFocusableGroupElement(currentIndex) { | ||
let elementToFocus; | ||
/* eslint-disable no-await-in-loop */ | ||
for (let index = 0; index < this.groups.length; index++) { | ||
let nextElement; | ||
if (this.selectedGroup) { | ||
nextIndex = this.groups.indexOf(this.selectedGroup); | ||
} | ||
if (nextIndex > -1) { | ||
if (nextIndex + 1 >= this.groups.length) { | ||
nextElement = this.groups[0]; | ||
if (currentIndex > -1) { | ||
if (currentIndex + 1 >= this.groups.length) { | ||
currentIndex = 0; | ||
nextElement = this.groups[currentIndex]; | ||
} | ||
else { | ||
nextElement = this.groups[nextIndex + 1]; | ||
currentIndex += 1; | ||
nextElement = this.groups[currentIndex]; | ||
} | ||
} | ||
else { | ||
nextElement = this.groups[0]; | ||
currentIndex = 0; | ||
nextElement = this.groups[currentIndex]; | ||
} | ||
const nextElementDomRef = instanceOfUI5Element(nextElement) ? nextElement.getDomRef() : nextElement; | ||
if (nextElementDomRef) { | ||
const elementToFocus = await getFirstFocusableElement(nextElementDomRef, true); | ||
elementToFocus?.focus(); | ||
elementToFocus = await this.groupElementToFocus(nextElement); | ||
if (elementToFocus) { | ||
break; | ||
} | ||
} | ||
if (isF6Previous(event)) { | ||
this.updateGroups(); | ||
if (this.groups.length < 1) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
let nextIndex = -1; | ||
/* eslint-enable no-await-in-loop */ | ||
return elementToFocus; | ||
} | ||
async findPreviousFocusableGroupElement(currentIndex) { | ||
let elementToFocus; | ||
/* eslint-disable no-await-in-loop */ | ||
for (let index = 0; index < this.groups.length; index++) { | ||
let nextElement; | ||
if (this.selectedGroup) { | ||
nextIndex = this.groups.indexOf(this.selectedGroup); | ||
} | ||
if (nextIndex > 0) { | ||
if (currentIndex > 0) { | ||
// Handle the situation where the first focusable element of two neighbor groups is the same | ||
@@ -67,16 +72,50 @@ // For example: | ||
// Here for both FCL & List the firstFoccusableElement is the same (the ui5-li) | ||
const firstFocusable = await getFirstFocusableElement(this.groups[nextIndex - 1], true); | ||
const shouldSkipParent = firstFocusable === await getFirstFocusableElement(this.groups[nextIndex], true); | ||
nextElement = this.groups[shouldSkipParent ? nextIndex - 2 : nextIndex - 1]; | ||
const firstFocusable = await this.groupElementToFocus(this.groups[currentIndex - 1]); | ||
const shouldSkipParent = firstFocusable === await this.groupElementToFocus(this.groups[currentIndex]); | ||
currentIndex = shouldSkipParent ? currentIndex - 2 : currentIndex - 1; | ||
if (currentIndex < 0) { | ||
currentIndex = this.groups.length - 1; | ||
} | ||
nextElement = this.groups[currentIndex]; | ||
} | ||
else { | ||
nextElement = this.groups[this.groups.length - 1]; | ||
currentIndex = this.groups.length - 1; | ||
nextElement = this.groups[currentIndex]; | ||
} | ||
const nextElementDomRef = instanceOfUI5Element(nextElement) ? nextElement.getDomRef() : nextElement; | ||
if (nextElementDomRef) { | ||
const elementToFocus = await getFirstFocusableElement(nextElementDomRef, true); | ||
elementToFocus?.focus(); | ||
elementToFocus = await this.groupElementToFocus(nextElement); | ||
if (elementToFocus) { | ||
break; | ||
} | ||
} | ||
/* eslint-enable no-await-in-loop */ | ||
return elementToFocus; | ||
} | ||
async _keydownHandler(event) { | ||
const forward = isF6Next(event); | ||
const backward = isF6Previous(event); | ||
if (!(forward || backward)) { | ||
return; | ||
} | ||
this.updateGroups(); | ||
if (this.groups.length < 1) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
let elementToFocus; | ||
if (this.groups.length === 0) { | ||
elementToFocus = await this.groupElementToFocus(this.groups[0]); | ||
return elementToFocus?.focus(); | ||
} | ||
let currentIndex = -1; | ||
if (this.selectedGroup) { | ||
currentIndex = this.groups.indexOf(this.selectedGroup); | ||
} | ||
if (forward) { | ||
elementToFocus = await this.findNextFocusableGroupElement(currentIndex); | ||
} | ||
if (backward) { | ||
elementToFocus = await this.findPreviousFocusableGroupElement(currentIndex); | ||
} | ||
elementToFocus?.focus(); | ||
} | ||
removeEventListeners() { | ||
@@ -83,0 +122,0 @@ document.removeEventListener("keydown", this.keydownHandler); |
@@ -5,3 +5,3 @@ import { TemplateResult } from "lit-html"; | ||
declare class OpenUI5Enablement { | ||
static wrapTemplateResultInBusyMarkup(html: (strings: TemplateStringsArray, ...values: Array<unknown>) => TemplateResult, host: OpenUI5Element, templateResult: TemplateResult): TemplateResult<1 | 2>; | ||
static wrapTemplateResultInBusyMarkup(html: (strings: TemplateStringsArray, ...values: Array<unknown>) => TemplateResult, host: OpenUI5Element, templateResult: TemplateResult): TemplateResult; | ||
static enrichBusyIndicatorSettings(klass: typeof UI5Element): void; | ||
@@ -8,0 +8,0 @@ static enrichBusyIndicatorMetadata(klass: typeof UI5Element): void; |
import { CLDRData } from "../asset-registries/LocaleData.js"; | ||
import type { LegacyDateCalendarCustomizing } from "../features/LegacyDateFormats.js"; | ||
declare class OpenUI5Support { | ||
static isLoaded(): boolean; | ||
static isAtLeastVersion116(): boolean; | ||
static isOpenUI5Detected(): boolean; | ||
static init(): Promise<void>; | ||
static getConfigurationSettingsObject(): { | ||
animationMode?: undefined; | ||
language?: undefined; | ||
theme?: undefined; | ||
themeRoot?: undefined; | ||
rtl?: undefined; | ||
timezone?: undefined; | ||
calendarType?: undefined; | ||
formatSettings?: undefined; | ||
} | { | ||
animationMode: string; | ||
@@ -11,7 +22,9 @@ language: string; | ||
rtl: string; | ||
timezone: string; | ||
calendarType: string; | ||
formatSettings: { | ||
firstDayOfWeek: any; | ||
firstDayOfWeek: number | undefined; | ||
legacyDateCalendarCustomizing: LegacyDateCalendarCustomizing; | ||
}; | ||
} | undefined; | ||
}; | ||
static getLocaleDataObject(): CLDRData | undefined; | ||
@@ -18,0 +31,0 @@ static _listenForThemeChange(): void; |
import { registerFeature } from "../FeaturesRegistry.js"; | ||
import { setTheme } from "../config/Theme.js"; | ||
import { getCurrentZIndex } from "../util/PopupUtils.js"; | ||
const getCore = () => { | ||
return window.sap?.ui?.getCore?.(); | ||
}; | ||
import patchPopup from "./patchPopup.js"; | ||
class OpenUI5Support { | ||
static isLoaded() { | ||
return !!getCore(); | ||
static isAtLeastVersion116() { | ||
if (!window.sap.ui.version) { | ||
return true; // sap.ui.version will be removed in newer OpenUI5 versions | ||
} | ||
const version = window.sap.ui.version; | ||
const parts = version.split("."); | ||
if (!parts || parts.length < 2) { | ||
return false; | ||
} | ||
return parseInt(parts[0]) > 1 || parseInt(parts[1]) >= 116; | ||
} | ||
static isOpenUI5Detected() { | ||
return typeof window.sap?.ui?.require === "function"; | ||
} | ||
static init() { | ||
const core = getCore(); | ||
if (!core) { | ||
if (!OpenUI5Support.isOpenUI5Detected()) { | ||
return Promise.resolve(); | ||
} | ||
return new Promise(resolve => { | ||
core.attachInit(() => { | ||
window.sap.ui.require(["sap/ui/core/LocaleData", "sap/ui/core/Popup"], (LocaleData, Popup) => { | ||
Popup.setInitialZIndex(getCurrentZIndex()); | ||
resolve(); | ||
}); | ||
window.sap.ui.require(["sap/ui/core/Core"], async (Core) => { | ||
const callback = () => { | ||
let deps = ["sap/ui/core/Popup", "sap/ui/core/LocaleData"]; | ||
if (OpenUI5Support.isAtLeastVersion116()) { // for versions since 1.116.0 and onward, use the modular core | ||
deps = [ | ||
...deps, | ||
"sap/base/i18n/Formatting", | ||
"sap/base/i18n/Localization", | ||
"sap/ui/core/ControlBehavior", | ||
"sap/ui/core/Theming", | ||
"sap/ui/core/date/CalendarUtils", | ||
]; | ||
} | ||
window.sap.ui.require(deps, (Popup) => { | ||
Popup.setInitialZIndex(getCurrentZIndex()); | ||
patchPopup(Popup); | ||
resolve(); | ||
}); | ||
}; | ||
if (OpenUI5Support.isAtLeastVersion116()) { | ||
await Core.ready(); | ||
callback(); | ||
} | ||
else { | ||
Core.attachInit(callback); | ||
} | ||
}); | ||
@@ -26,7 +55,28 @@ }); | ||
static getConfigurationSettingsObject() { | ||
const core = getCore(); | ||
if (!core) { | ||
return; | ||
if (!OpenUI5Support.isOpenUI5Detected()) { | ||
return {}; | ||
} | ||
const config = core.getConfiguration(); | ||
if (OpenUI5Support.isAtLeastVersion116()) { | ||
const ControlBehavior = window.sap.ui.require("sap/ui/core/ControlBehavior"); | ||
const Localization = window.sap.ui.require("sap/base/i18n/Localization"); | ||
const Theming = window.sap.ui.require("sap/ui/core/Theming"); | ||
const Formatting = window.sap.ui.require("sap/base/i18n/Formatting"); | ||
const CalendarUtils = window.sap.ui.require("sap/ui/core/date/CalendarUtils"); | ||
return { | ||
animationMode: ControlBehavior.getAnimationMode(), | ||
language: Localization.getLanguage(), | ||
theme: Theming.getTheme(), | ||
themeRoot: Theming.getThemeRoot(), | ||
rtl: Localization.getRTL(), | ||
timezone: Localization.getTimezone(), | ||
calendarType: Formatting.getCalendarType(), | ||
formatSettings: { | ||
firstDayOfWeek: CalendarUtils.getWeekConfigurationValues().firstDayOfWeek, | ||
legacyDateCalendarCustomizing: Formatting.getCustomIslamicCalendarData?.() | ||
?? Formatting.getLegacyDateCalendarCustomizing?.(), | ||
}, | ||
}; | ||
} | ||
const Core = window.sap.ui.require("sap/ui/core/Core"); | ||
const config = Core.getConfiguration(); | ||
const LocaleData = window.sap.ui.require("sap/ui/core/LocaleData"); | ||
@@ -39,5 +89,7 @@ return { | ||
rtl: config.getRTL(), | ||
timezone: config.getTimezone(), | ||
calendarType: config.getCalendarType(), | ||
formatSettings: { | ||
firstDayOfWeek: LocaleData ? LocaleData.getInstance(config.getLocale()).getFirstDayOfWeek() : undefined, | ||
legacyDateCalendarCustomizing: config.getFormatSettings().getLegacyDateCalendarCustomizing(), | ||
}, | ||
@@ -47,20 +99,31 @@ }; | ||
static getLocaleDataObject() { | ||
const core = getCore(); | ||
if (!core) { | ||
if (!OpenUI5Support.isOpenUI5Detected()) { | ||
return; | ||
} | ||
const config = core.getConfiguration(); | ||
const LocaleData = window.sap.ui.require("sap/ui/core/LocaleData"); | ||
if (OpenUI5Support.isAtLeastVersion116()) { | ||
const Localization = window.sap.ui.require("sap/base/i18n/Localization"); | ||
return LocaleData.getInstance(Localization.getLanguageTag())._get(); | ||
} | ||
const Core = window.sap.ui.require("sap/ui/core/Core"); | ||
const config = Core.getConfiguration(); | ||
return LocaleData.getInstance(config.getLocale())._get(); | ||
} | ||
static _listenForThemeChange() { | ||
const core = getCore(); | ||
const config = core.getConfiguration(); | ||
core.attachThemeChanged(async () => { | ||
await setTheme(config.getTheme()); | ||
}); | ||
if (OpenUI5Support.isAtLeastVersion116()) { | ||
const Theming = window.sap.ui.require("sap/ui/core/Theming"); | ||
Theming.attachApplied(() => { | ||
setTheme(Theming.getTheme()); | ||
}); | ||
} | ||
else { | ||
const Core = window.sap.ui.require("sap/ui/core/Core"); | ||
const config = Core.getConfiguration(); | ||
Core.attachThemeChanged(() => { | ||
setTheme(config.getTheme()); | ||
}); | ||
} | ||
} | ||
static attachListeners() { | ||
const core = getCore(); | ||
if (!core) { | ||
if (!OpenUI5Support.isOpenUI5Detected()) { | ||
return; | ||
@@ -71,4 +134,3 @@ } | ||
static cssVariablesLoaded() { | ||
const core = getCore(); | ||
if (!core) { | ||
if (!OpenUI5Support.isOpenUI5Detected()) { | ||
return; | ||
@@ -78,3 +140,3 @@ } | ||
if (!link) { | ||
return; | ||
return false; | ||
} | ||
@@ -84,12 +146,13 @@ return !!link.href.match(/\/css(-|_)variables\.css/); | ||
static getNextZIndex() { | ||
const core = getCore(); | ||
if (!core) { | ||
if (!OpenUI5Support.isOpenUI5Detected()) { | ||
return; | ||
} | ||
const Popup = window.sap.ui.require("sap/ui/core/Popup"); | ||
if (!Popup) { | ||
console.warn(`The OpenUI5Support feature hasn't been initialized properly. Make sure you import the "@ui5/webcomponents-base/dist/features/OpenUI5Support.js" module before all components' modules.`); // eslint-disable-line | ||
} | ||
return Popup.getNextZIndex(); | ||
} | ||
static setInitialZIndex() { | ||
const core = getCore(); | ||
if (!core) { | ||
if (!OpenUI5Support.isOpenUI5Detected()) { | ||
return; | ||
@@ -96,0 +159,0 @@ } |
@@ -0,3 +1,12 @@ | ||
import type UI5Element from "./UI5Element.js"; | ||
declare abstract class ComponentFeature { | ||
constructor(...args: any[]); | ||
static define?: () => Promise<void>; | ||
static dependencies?: Array<typeof UI5Element>; | ||
} | ||
declare const registerFeature: (name: string, feature: object) => void; | ||
declare const getFeature: <T>(name: string) => T; | ||
export { registerFeature, getFeature, }; | ||
declare const registerComponentFeature: (name: string, feature: typeof ComponentFeature) => Promise<void>; | ||
declare const getComponentFeature: <T>(name: string) => T; | ||
declare const subscribeForFeatureLoad: (name: string, klass: typeof UI5Element, callback: () => void) => void; | ||
export { registerFeature, getFeature, registerComponentFeature, getComponentFeature, subscribeForFeatureLoad, ComponentFeature, }; |
@@ -0,2 +1,12 @@ | ||
import EventProvider from "./EventProvider.js"; | ||
class ComponentFeature { | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-empty-function | ||
constructor(...args) { } | ||
} | ||
const features = new Map(); | ||
const componentFeatures = new Map(); | ||
const subscribers = new Map(); | ||
const EVENT_NAME = "componentFeatureLoad"; | ||
const eventProvider = new EventProvider(); | ||
const featureLoadEventName = (name) => `${EVENT_NAME}_${name}`; | ||
const registerFeature = (name, feature) => { | ||
@@ -8,3 +18,29 @@ features.set(name, feature); | ||
}; | ||
export { registerFeature, getFeature, }; | ||
const registerComponentFeature = async (name, feature) => { | ||
await Promise.all(feature.dependencies?.map(dep => dep.define()) || []); | ||
await feature.define?.(); | ||
componentFeatures.set(name, feature); | ||
notifyForFeatureLoad(name); | ||
}; | ||
const getComponentFeature = (name) => { | ||
return componentFeatures.get(name); | ||
}; | ||
const subscribeForFeatureLoad = (name, klass, callback) => { | ||
const subscriber = subscribers.get(klass); | ||
const isSubscribed = subscriber?.includes(name); | ||
if (isSubscribed) { | ||
return; | ||
} | ||
if (!subscriber) { | ||
subscribers.set(klass, [name]); | ||
} | ||
else { | ||
subscriber.push(name); | ||
} | ||
eventProvider.attachEvent(featureLoadEventName(name), callback); | ||
}; | ||
const notifyForFeatureLoad = (name) => { | ||
eventProvider.fireEvent(featureLoadEventName(name), undefined); | ||
}; | ||
export { registerFeature, getFeature, registerComponentFeature, getComponentFeature, subscribeForFeatureLoad, ComponentFeature, }; | ||
//# sourceMappingURL=FeaturesRegistry.js.map |
@@ -8,3 +8,3 @@ import { hasStyle, createStyle } from "./ManagedStyles.js"; | ||
// Only set the main font if there is no OpenUI5 support, or there is, but OpenUI5 is not loaded | ||
if (!openUI5Support || !openUI5Support.isLoaded()) { | ||
if (!openUI5Support || !openUI5Support.isOpenUI5Detected()) { | ||
insertMainFontFace(); | ||
@@ -11,0 +11,0 @@ } |
@@ -1,13 +0,8 @@ | ||
const assetParameters = {"themes":{"default":"sap_fiori_3","all":["sap_fiori_3","sap_fiori_3_dark","sap_belize","sap_belize_hcb","sap_belize_hcw","sap_fiori_3_hcb","sap_fiori_3_hcw","sap_horizon","sap_horizon_dark","sap_horizon_hcb","sap_horizon_hcw","sap_horizon_exp"]},"languages":{"default":"en","all":["ar","bg","ca","cs","cy","da","de","el","en","en_GB","en_US_sappsd","en_US_saprigi","en_US_saptrc","es","es_MX","et","fi","fr","fr_CA","hi","hr","hu","in","it","iw","ja","kk","ko","lt","lv","ms","nl","no","pl","pt_PT","pt","ro","ru","sh","sk","sl","sv","th","tr","uk","vi","zh_CN","zh_TW"]},"locales":{"default":"en","all":["ar","ar_EG","ar_SA","bg","ca","cs","da","de","de_AT","de_CH","el","el_CY","en","en_AU","en_GB","en_HK","en_IE","en_IN","en_NZ","en_PG","en_SG","en_ZA","es","es_AR","es_BO","es_CL","es_CO","es_MX","es_PE","es_UY","es_VE","et","fa","fi","fr","fr_BE","fr_CA","fr_CH","fr_LU","he","hi","hr","hu","id","it","it_CH","ja","kk","ko","lt","lv","ms","nb","nl","nl_BE","pl","pt","pt_PT","ro","ru","ru_UA","sk","sl","sr","sr_Latn","sv","th","tr","uk","vi","zh_CN","zh_HK","zh_SG","zh_TW"]}}; | ||
const assetParameters = { "themes": { "default": "sap_horizon", "all": ["sap_fiori_3", "sap_fiori_3_dark", "sap_belize", "sap_belize_hcb", "sap_belize_hcw", "sap_fiori_3_hcb", "sap_fiori_3_hcw", "sap_horizon", "sap_horizon_dark", "sap_horizon_hcb", "sap_horizon_hcw", "sap_horizon_exp", "sap_horizon_dark_exp", "sap_horizon_hcb_exp", "sap_horizon_hcw_exp"] }, "languages": { "default": "en", "all": ["ar", "bg", "ca", "cnr", "cs", "cy", "da", "de", "el", "en", "en_GB", "en_US_sappsd", "en_US_saprigi", "en_US_saptrc", "es", "es_MX", "et", "fi", "fr", "fr_CA", "hi", "hr", "hu", "in", "it", "iw", "ja", "kk", "ko", "lt", "lv", "mk", "ms", "nl", "no", "pl", "pt_PT", "pt", "ro", "ru", "sh", "sk", "sl", "sr", "sv", "th", "tr", "uk", "vi", "zh_CN", "zh_TW"] }, "locales": { "default": "en", "all": ["ar", "ar_EG", "ar_SA", "bg", "ca", "cnr", "cs", "da", "de", "de_AT", "de_CH", "el", "el_CY", "en", "en_AU", "en_GB", "en_HK", "en_IE", "en_IN", "en_NZ", "en_PG", "en_SG", "en_ZA", "es", "es_AR", "es_BO", "es_CL", "es_CO", "es_MX", "es_PE", "es_UY", "es_VE", "et", "fa", "fi", "fr", "fr_BE", "fr_CA", "fr_CH", "fr_LU", "he", "hi", "hr", "hu", "id", "it", "it_CH", "ja", "kk", "ko", "lt", "lv", "ms", "mk", "nb", "nl", "nl_BE", "pl", "pt", "pt_PT", "ro", "ru", "ru_UA", "sk", "sl", "sr", "sr_Latn", "sv", "th", "tr", "uk", "vi", "zh_CN", "zh_HK", "zh_SG", "zh_TW"] } }; | ||
const DEFAULT_THEME = assetParameters.themes.default; | ||
const SUPPORTED_THEMES = assetParameters.themes.all; | ||
const DEFAULT_LANGUAGE = assetParameters.languages.default; | ||
const DEFAULT_LOCALE = assetParameters.locales.default; | ||
const SUPPORTED_LOCALES = assetParameters.locales.all; | ||
export { | ||
DEFAULT_THEME, | ||
DEFAULT_LANGUAGE, | ||
DEFAULT_LOCALE, | ||
SUPPORTED_LOCALES, | ||
}; | ||
export { DEFAULT_THEME, SUPPORTED_THEMES, DEFAULT_LANGUAGE, DEFAULT_LOCALE, SUPPORTED_LOCALES, }; | ||
//# sourceMappingURL=AssetParameters.js.map |
const styleData = { | ||
packageName: "@ui5/webcomponents-base", | ||
fileName: "FontFace.css", | ||
content: `@font-face{font-family:"72";font-style:normal;font-weight:400;src:local("72"),url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:"72full";font-style:normal;font-weight:400;src:local('72-full'),url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular-full.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:"72";font-style:normal;font-weight:700;src:local('72-Bold'),url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:"72full";font-style:normal;font-weight:700;src:local('72-Bold-full'),url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:'72-Bold';font-style:normal;src:local('72-Bold'),url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:'72-Boldfull';font-style:normal;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:'72-Light';font-style:normal;src:local('72-Light'),url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:'72-Lightfull';font-style:normal;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light-full.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:"72Black";font-style:bold;font-weight:900;src:local('72Black'),url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff2?ui5-webcomponents) format("woff2")}`, | ||
content: `@font-face{font-family:"72";font-style:normal;font-weight:400;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Regular.woff2?ui5-webcomponents) format("woff2"),local("72");unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}@font-face{font-family:"72full";font-style:normal;font-weight:400;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Regular-full.woff2?ui5-webcomponents) format("woff2"),local('72-full')}@font-face{font-family:"72";font-style:normal;font-weight:700;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2"),local('72-Bold');unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}@font-face{font-family:"72full";font-style:normal;font-weight:700;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:'72-Bold';font-style:normal;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2"),local('72-Bold');unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}@font-face{font-family:'72-Boldfull';font-style:normal;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:'72-Light';font-style:normal;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light.woff2?ui5-webcomponents) format("woff2"),local('72-Light');unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}@font-face{font-family:'72-Lightfull';font-style:normal;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Light-full.woff2?ui5-webcomponents) format("woff2")}@font-face{font-family:'72Mono';src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Regular.woff2?ui5-webcomponents) format('woff2'),local('72Mono');unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}@font-face{font-family:'72Monofull';src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Regular-full.woff2?ui5-webcomponents) format('woff2')}@font-face{font-family:'72Mono-Bold';src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Bold.woff2?ui5-webcomponents) format('woff2'),local('72Mono-Bold');unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}@font-face{font-family:'72Mono-Boldfull';src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72Mono-Bold-full.woff2?ui5-webcomponents) format('woff2')}@font-face{font-family:"72Black";font-style:bold;font-weight:900;src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff2?ui5-webcomponents) format("woff2"),local('72Black');unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}@font-face{font-family:'72Blackfull';src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black-full.woff2?ui5-webcomponents) format('woff2')}@font-face{font-family:"72-SemiboldDuplex";src:url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-SemiboldDuplex.woff2?ui5-webcomponents) format("woff2"),local('72-SemiboldDuplex');unicode-range:U+00,U+0D,U+20-7E,U+A0-FF,U+131,U+152-153,U+161,U+178,U+17D-17E,U+192,U+237,U+2C6,U+2DC,U+3BC,U+1E9E,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122}`, | ||
}; | ||
export default styleData; | ||
//# sourceMappingURL=FontFace.css.js.map |
const styleData = { | ||
packageName: "@ui5/webcomponents-base", | ||
fileName: "SystemCSSVars.css", | ||
content: `:root{--_ui5_content_density:cozy}.sapUiSizeCompact,.ui5-content-density-compact,[data-ui5-compact-size]{--_ui5_content_density:compact}[dir=rtl]{--_ui5_dir:rtl}[dir=ltr]{--_ui5_dir:ltr}`, | ||
content: `:root{--_ui5_content_density:cozy}.sapUiSizeCompact,.ui5-content-density-compact,[data-ui5-compact-size]{--_ui5_content_density:compact}`, | ||
}; | ||
export default styleData; | ||
//# sourceMappingURL=SystemCSSVars.css.js.map |
/* eslint no-unused-vars: 0 */ | ||
import { html, svg, repeat, classMap, styleMap, ifDefined, unsafeHTML, scopeTag } from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; | ||
const block0 = (context, tags, suffix) => html`<div>Root text: ${ifDefined(context.text)}${ repeat(context.items, (item, index) => item._id || index, (item, index) => block1(item, index, context, tags, suffix)) } Root text: ${ifDefined(context.text)}</div>`; | ||
const block1 = (item, index, context, tags, suffix) => html`<h3>Item-${index}</h3>${ item.text ? block2(item, index, context, tags, suffix) : undefined }<ul>${ repeat(item.words, (item, index) => item._id || index, (item, index) => block3(item, index, context, tags, suffix)) }</ul>${ item.text ? block4(item, index, context, tags, suffix) : undefined }`; | ||
const block2 = (item, index, context, tags, suffix) => html`<div class="before-each-content--start--${index}">Root text: ${ifDefined(context.text)}, Item text: ${ifDefined(item.text)}</div>`; | ||
const block3 = (item, index, context, tags, suffix) => html`<li><h3>Word-${index}</h3><div class="nested-each-content--${index}--0">Root Text: ${ifDefined(context.text)}, Word text: ${ifDefined(item.text)}</div><div class="nested-each-content--${index}--1">Root Text: ${ifDefined(context.text)}, Word text: ${ifDefined(item.text)}</div></li>`; | ||
const block4 = (item, index, context, tags, suffix) => html`<div class="after-each-content--end--${index}">Root text: ${ifDefined(context.text)}, Item text: ${ifDefined(item.text)}</div>`; | ||
export default block0; | ||
import { html, repeat, ifDefined } from "../../../renderer/LitRenderer.js"; | ||
function block0(context, tags, suffix) { return html `<div>Root text: ${ifDefined(this.text)}${repeat(this.items, (item, index) => item._id || index, (item, index) => block1.call(this, context, tags, suffix, item, index))} Root text: ${ifDefined(this.text)}</div>`; } | ||
function block1(context, tags, suffix, item, index) { return html `<h3>Item-${index}</h3>${item.text ? block2.call(this, context, tags, suffix, item, index) : undefined}<ul>${repeat(item.words, (item, index) => item._id || index, (item, index) => block3.call(this, context, tags, suffix, item, index))}</ul>${item.text ? block4.call(this, context, tags, suffix, item, index) : undefined}`; } | ||
function block2(context, tags, suffix, item, index) { return html `<div class="before-each-content--start--${index}">Root text: ${ifDefined(this.text)}, Item text: ${ifDefined(item.text)}</div>`; } | ||
function block3(context, tags, suffix, item, index) { return html `<li><h3>Word-${index}</h3><div class="nested-each-content--${index}--0">Root Text: ${ifDefined(this.text)}, Word text: ${ifDefined(item.text)}</div><div class="nested-each-content--${index}--1">Root Text: ${ifDefined(this.text)}, Word text: ${ifDefined(item.text)}</div></li>`; } | ||
function block4(context, tags, suffix, item, index) { return html `<div class="after-each-content--end--${index}">Root text: ${ifDefined(this.text)}, Item text: ${ifDefined(item.text)}</div>`; } | ||
export default block0; | ||
//# sourceMappingURL=WithComplexTemplateTemplate.lit.js.map |
const VersionInfo = { | ||
version: "0.0.0-7d5f73b20", | ||
major: 0, | ||
minor: 0, | ||
patch: 0, | ||
suffix: "-7d5f73b20", | ||
isNext: true, | ||
buildTime: 1675347767, | ||
version: "1.24.7", | ||
major: 1, | ||
minor: 24, | ||
patch: 7, | ||
suffix: "", | ||
isNext: false, | ||
buildTime: 1721986098, | ||
}; | ||
export default VersionInfo; | ||
export default VersionInfo; | ||
//# sourceMappingURL=VersionInfo.js.map |
/** | ||
* Use this method to initialize/get resources that you would like to be shared among UI5 Web Components runtime instances. | ||
* The data will be accessed via a singleton "ui5-shared-resources" HTML element in the "head" element of the page. | ||
* The data will be accessed via a singleton "ui5-shared-resources" HTML element in the "body" element of the page. | ||
* | ||
@@ -5,0 +5,0 @@ * @public |
import getSingletonElementInstance from "./util/getSingletonElementInstance.js"; | ||
const getSharedResourcesInstance = () => getSingletonElementInstance("ui5-shared-resources", document.head); | ||
const getMetaDomEl = () => { | ||
const el = document.createElement("meta"); | ||
el.setAttribute("name", "ui5-shared-resources"); | ||
el.setAttribute("content", ""); // attribute "content" should be present when "name" is set. | ||
return el; | ||
}; | ||
const getSharedResourcesInstance = () => { | ||
if (typeof document === "undefined") { | ||
return null; | ||
} | ||
return getSingletonElementInstance(`meta[name="ui5-shared-resources"]`, document.head, getMetaDomEl); | ||
}; | ||
/** | ||
* Use this method to initialize/get resources that you would like to be shared among UI5 Web Components runtime instances. | ||
* The data will be accessed via a singleton "ui5-shared-resources" HTML element in the "head" element of the page. | ||
* The data will be accessed via a singleton "ui5-shared-resources" HTML element in the "body" element of the page. | ||
* | ||
@@ -15,2 +26,5 @@ * @public | ||
let current = getSharedResourcesInstance(); | ||
if (!current) { | ||
return initialValue; | ||
} | ||
for (let i = 0; i < parts.length; i++) { | ||
@@ -17,0 +31,0 @@ const part = parts[i]; |
@@ -23,2 +23,3 @@ export {}; | ||
const DEFAULT_THEME: string; | ||
const SUPPORTED_THEMES: Array<string>; | ||
const DEFAULT_LANGUAGE: string; | ||
@@ -29,2 +30,3 @@ const DEFAULT_LOCALE: string; | ||
DEFAULT_THEME, | ||
SUPPORTED_THEMES, | ||
DEFAULT_LANGUAGE, | ||
@@ -31,0 +33,0 @@ DEFAULT_LOCALE, |
@@ -18,7 +18,6 @@ import { registerI18nLoader } from "./asset-registries/i18n.js"; | ||
* @public | ||
* @param {Object|String} textObj key/defaultText pair or just the key | ||
* @param textObj key/defaultText pair or just the key | ||
* @param params Values for the placeholders | ||
* @returns {string} | ||
*/ | ||
getText(textObj: I18nText, ...params: Array<number | string>): string; | ||
getText(textObj: I18nText | string, ...params: Array<number | string>): string; | ||
} | ||
@@ -30,3 +29,2 @@ /** | ||
* @param packageName | ||
* @returns { Promise<I18nBundle> } | ||
*/ | ||
@@ -33,0 +31,0 @@ declare const getI18nBundle: (packageName: string) => Promise<I18nBundle>; |
@@ -17,5 +17,4 @@ import { registerI18nLoader, fetchI18nBundle, getI18nBundleData } from "./asset-registries/i18n.js"; | ||
* @public | ||
* @param {Object|String} textObj key/defaultText pair or just the key | ||
* @param textObj key/defaultText pair or just the key | ||
* @param params Values for the placeholders | ||
* @returns {string} | ||
*/ | ||
@@ -31,3 +30,4 @@ getText(textObj, ...params) { | ||
if (bundle && !bundle[textObj.key]) { | ||
console.warn(`Key ${textObj.key} not found in the i18n bundle, the default text will be used`); // eslint-disable-line | ||
// eslint-disable-next-line no-console | ||
console.warn(`Key ${textObj.key} not found in the i18n bundle, the default text will be used`); | ||
} | ||
@@ -43,3 +43,2 @@ const messageText = bundle && bundle[textObj.key] ? bundle[textObj.key] : (textObj.defaultText || textObj.key); | ||
* @param packageName | ||
* @returns { I18nBundle } | ||
*/ | ||
@@ -59,3 +58,2 @@ const getI18nBundleSync = (packageName) => { | ||
* @param packageName | ||
* @returns { Promise<I18nBundle> } | ||
*/ | ||
@@ -62,0 +60,0 @@ const getI18nBundle = async (packageName) => { |
@@ -7,3 +7,2 @@ import type { FormatSettings } from "./config/FormatSettings.js"; | ||
declare const getThemeRoot: () => string | undefined; | ||
declare const getRTL: () => boolean | undefined; | ||
declare const getLanguage: () => string | undefined; | ||
@@ -22,3 +21,9 @@ /** | ||
declare const getCalendarType: () => CalendarType | undefined; | ||
declare const getSecondaryCalendarType: () => CalendarType | undefined; | ||
/** | ||
* Returns the configured IANA timezone ID. | ||
* @returns { String } the configured IANA timezone ID, e.g. "America/New_York" | ||
*/ | ||
declare const getTimezone: () => string | undefined; | ||
declare const getFormatSettings: () => FormatSettings; | ||
export { getAnimationMode, getTheme, getThemeRoot, getRTL, getLanguage, getFetchDefaultLanguage, getNoConflict, getCalendarType, getFormatSettings, }; | ||
export { getAnimationMode, getTheme, getThemeRoot, getLanguage, getFetchDefaultLanguage, getNoConflict, getCalendarType, getSecondaryCalendarType, getTimezone, getFormatSettings, }; |
@@ -13,3 +13,5 @@ import merge from "./thirdparty/merge.js"; | ||
language: undefined, | ||
timezone: undefined, | ||
calendarType: undefined, | ||
secondaryCalendarType: undefined, | ||
noConflict: false, | ||
@@ -32,6 +34,2 @@ formatSettings: {}, | ||
}; | ||
const getRTL = () => { | ||
initConfiguration(); | ||
return initialConfig.rtl; | ||
}; | ||
const getLanguage = () => { | ||
@@ -62,2 +60,14 @@ initConfiguration(); | ||
}; | ||
const getSecondaryCalendarType = () => { | ||
initConfiguration(); | ||
return initialConfig.secondaryCalendarType; | ||
}; | ||
/** | ||
* Returns the configured IANA timezone ID. | ||
* @returns { String } the configured IANA timezone ID, e.g. "America/New_York" | ||
*/ | ||
const getTimezone = () => { | ||
initConfiguration(); | ||
return initialConfig.timezone; | ||
}; | ||
const getFormatSettings = () => { | ||
@@ -131,3 +141,3 @@ initConfiguration(); | ||
const openUI5Support = getFeature("OpenUI5Support"); | ||
if (!openUI5Support || !openUI5Support.isLoaded()) { | ||
if (!openUI5Support || !openUI5Support.isOpenUI5Detected()) { | ||
return; | ||
@@ -139,3 +149,3 @@ } | ||
const initConfiguration = () => { | ||
if (initialized) { | ||
if (typeof document === "undefined" || initialized) { | ||
return; | ||
@@ -151,3 +161,3 @@ } | ||
}; | ||
export { getAnimationMode, getTheme, getThemeRoot, getRTL, getLanguage, getFetchDefaultLanguage, getNoConflict, getCalendarType, getFormatSettings, }; | ||
export { getAnimationMode, getTheme, getThemeRoot, getLanguage, getFetchDefaultLanguage, getNoConflict, getCalendarType, getSecondaryCalendarType, getTimezone, getFormatSettings, }; | ||
//# sourceMappingURL=InitialConfiguration.js.map |
@@ -57,2 +57,6 @@ declare const isEnter: (event: KeyboardEvent) => boolean; | ||
declare const isCtrlV: (event: KeyboardEvent) => boolean; | ||
export { isEnter, isEnterShift, isSpace, isSpaceShift, isSpaceCtrl, isLeft, isRight, isUp, isDown, isLeftCtrl, isRightCtrl, isUpCtrl, isDownCtrl, isUpShift, isDownShift, isUpAlt, isDownAlt, isLeftShift, isRightShift, isLeftShiftCtrl, isRightShiftCtrl, isUpShiftCtrl, isDownShiftCtrl, isHome, isEnd, isPlus, isMinus, isHomeCtrl, isEndCtrl, isHomeShift, isEndShift, isEscape, isTabNext, isTabPrevious, isBackSpace, isDelete, isShow, isF4, isF4Shift, isF6Previous, isF6Next, isF7, isPageUp, isPageDown, isPageUpShift, isPageUpAlt, isPageDownShift, isPageDownAlt, isPageUpShiftCtrl, isPageDownShiftCtrl, isShift, isCtrlA, isCtrlV, isDeleteShift, isInsertShift, isInsertCtrl, }; | ||
declare const isKeyA: (event: KeyboardEvent) => boolean; | ||
declare const isKeyP: (event: KeyboardEvent) => boolean; | ||
declare const isNumber: (event: KeyboardEvent) => boolean; | ||
declare const isColon: (event: KeyboardEvent) => boolean; | ||
export { isEnter, isEnterShift, isSpace, isSpaceShift, isSpaceCtrl, isLeft, isRight, isUp, isDown, isLeftCtrl, isRightCtrl, isUpCtrl, isDownCtrl, isUpShift, isDownShift, isUpAlt, isDownAlt, isLeftShift, isRightShift, isLeftShiftCtrl, isRightShiftCtrl, isUpShiftCtrl, isDownShiftCtrl, isHome, isEnd, isPlus, isMinus, isHomeCtrl, isEndCtrl, isHomeShift, isEndShift, isEscape, isTabNext, isTabPrevious, isBackSpace, isDelete, isShow, isF4, isF4Shift, isF6Previous, isF6Next, isF7, isPageUp, isPageDown, isPageUpShift, isPageUpAlt, isPageDownShift, isPageDownAlt, isPageUpShiftCtrl, isPageDownShiftCtrl, isShift, isCtrlA, isCtrlV, isKeyA, isKeyP, isDeleteShift, isInsertShift, isInsertCtrl, isNumber, isColon, }; |
215
dist/Keys.js
@@ -1,106 +0,105 @@ | ||
var KeyCodes; | ||
(function (KeyCodes) { | ||
KeyCodes[KeyCodes["BACKSPACE"] = 8] = "BACKSPACE"; | ||
KeyCodes[KeyCodes["TAB"] = 9] = "TAB"; | ||
KeyCodes[KeyCodes["ENTER"] = 13] = "ENTER"; | ||
KeyCodes[KeyCodes["SHIFT"] = 16] = "SHIFT"; | ||
KeyCodes[KeyCodes["CONTROL"] = 17] = "CONTROL"; | ||
KeyCodes[KeyCodes["ALT"] = 18] = "ALT"; | ||
KeyCodes[KeyCodes["BREAK"] = 19] = "BREAK"; | ||
KeyCodes[KeyCodes["CAPS_LOCK"] = 20] = "CAPS_LOCK"; | ||
KeyCodes[KeyCodes["ESCAPE"] = 27] = "ESCAPE"; | ||
KeyCodes[KeyCodes["SPACE"] = 32] = "SPACE"; | ||
KeyCodes[KeyCodes["PAGE_UP"] = 33] = "PAGE_UP"; | ||
KeyCodes[KeyCodes["PAGE_DOWN"] = 34] = "PAGE_DOWN"; | ||
KeyCodes[KeyCodes["END"] = 35] = "END"; | ||
KeyCodes[KeyCodes["HOME"] = 36] = "HOME"; | ||
KeyCodes[KeyCodes["ARROW_LEFT"] = 37] = "ARROW_LEFT"; | ||
KeyCodes[KeyCodes["ARROW_UP"] = 38] = "ARROW_UP"; | ||
KeyCodes[KeyCodes["ARROW_RIGHT"] = 39] = "ARROW_RIGHT"; | ||
KeyCodes[KeyCodes["ARROW_DOWN"] = 40] = "ARROW_DOWN"; | ||
KeyCodes[KeyCodes["PRINT"] = 44] = "PRINT"; | ||
KeyCodes[KeyCodes["INSERT"] = 45] = "INSERT"; | ||
KeyCodes[KeyCodes["DELETE"] = 46] = "DELETE"; | ||
KeyCodes[KeyCodes["DIGIT_0"] = 48] = "DIGIT_0"; | ||
KeyCodes[KeyCodes["DIGIT_1"] = 49] = "DIGIT_1"; | ||
KeyCodes[KeyCodes["DIGIT_2"] = 50] = "DIGIT_2"; | ||
KeyCodes[KeyCodes["DIGIT_3"] = 51] = "DIGIT_3"; | ||
KeyCodes[KeyCodes["DIGIT_4"] = 52] = "DIGIT_4"; | ||
KeyCodes[KeyCodes["DIGIT_5"] = 53] = "DIGIT_5"; | ||
KeyCodes[KeyCodes["DIGIT_6"] = 54] = "DIGIT_6"; | ||
KeyCodes[KeyCodes["DIGIT_7"] = 55] = "DIGIT_7"; | ||
KeyCodes[KeyCodes["DIGIT_8"] = 56] = "DIGIT_8"; | ||
KeyCodes[KeyCodes["DIGIT_9"] = 57] = "DIGIT_9"; | ||
KeyCodes[KeyCodes["A"] = 65] = "A"; | ||
KeyCodes[KeyCodes["B"] = 66] = "B"; | ||
KeyCodes[KeyCodes["C"] = 67] = "C"; | ||
KeyCodes[KeyCodes["D"] = 68] = "D"; | ||
KeyCodes[KeyCodes["E"] = 69] = "E"; | ||
KeyCodes[KeyCodes["F"] = 70] = "F"; | ||
KeyCodes[KeyCodes["G"] = 71] = "G"; | ||
KeyCodes[KeyCodes["H"] = 72] = "H"; | ||
KeyCodes[KeyCodes["I"] = 73] = "I"; | ||
KeyCodes[KeyCodes["J"] = 74] = "J"; | ||
KeyCodes[KeyCodes["K"] = 75] = "K"; | ||
KeyCodes[KeyCodes["L"] = 76] = "L"; | ||
KeyCodes[KeyCodes["M"] = 77] = "M"; | ||
KeyCodes[KeyCodes["N"] = 78] = "N"; | ||
KeyCodes[KeyCodes["O"] = 79] = "O"; | ||
KeyCodes[KeyCodes["P"] = 80] = "P"; | ||
KeyCodes[KeyCodes["Q"] = 81] = "Q"; | ||
KeyCodes[KeyCodes["R"] = 82] = "R"; | ||
KeyCodes[KeyCodes["S"] = 83] = "S"; | ||
KeyCodes[KeyCodes["T"] = 84] = "T"; | ||
KeyCodes[KeyCodes["U"] = 85] = "U"; | ||
KeyCodes[KeyCodes["V"] = 86] = "V"; | ||
KeyCodes[KeyCodes["W"] = 87] = "W"; | ||
KeyCodes[KeyCodes["X"] = 88] = "X"; | ||
KeyCodes[KeyCodes["Y"] = 89] = "Y"; | ||
KeyCodes[KeyCodes["Z"] = 90] = "Z"; | ||
KeyCodes[KeyCodes["WINDOWS"] = 91] = "WINDOWS"; | ||
KeyCodes[KeyCodes["CONTEXT_MENU"] = 93] = "CONTEXT_MENU"; | ||
KeyCodes[KeyCodes["TURN_OFF"] = 94] = "TURN_OFF"; | ||
KeyCodes[KeyCodes["SLEEP"] = 95] = "SLEEP"; | ||
KeyCodes[KeyCodes["NUMPAD_0"] = 96] = "NUMPAD_0"; | ||
KeyCodes[KeyCodes["NUMPAD_1"] = 97] = "NUMPAD_1"; | ||
KeyCodes[KeyCodes["NUMPAD_2"] = 98] = "NUMPAD_2"; | ||
KeyCodes[KeyCodes["NUMPAD_3"] = 99] = "NUMPAD_3"; | ||
KeyCodes[KeyCodes["NUMPAD_4"] = 100] = "NUMPAD_4"; | ||
KeyCodes[KeyCodes["NUMPAD_5"] = 101] = "NUMPAD_5"; | ||
KeyCodes[KeyCodes["NUMPAD_6"] = 102] = "NUMPAD_6"; | ||
KeyCodes[KeyCodes["NUMPAD_7"] = 103] = "NUMPAD_7"; | ||
KeyCodes[KeyCodes["NUMPAD_8"] = 104] = "NUMPAD_8"; | ||
KeyCodes[KeyCodes["NUMPAD_9"] = 105] = "NUMPAD_9"; | ||
KeyCodes[KeyCodes["NUMPAD_ASTERISK"] = 106] = "NUMPAD_ASTERISK"; | ||
KeyCodes[KeyCodes["NUMPAD_PLUS"] = 107] = "NUMPAD_PLUS"; | ||
KeyCodes[KeyCodes["NUMPAD_MINUS"] = 109] = "NUMPAD_MINUS"; | ||
KeyCodes[KeyCodes["NUMPAD_COMMA"] = 110] = "NUMPAD_COMMA"; | ||
KeyCodes[KeyCodes["NUMPAD_SLASH"] = 111] = "NUMPAD_SLASH"; | ||
KeyCodes[KeyCodes["F1"] = 112] = "F1"; | ||
KeyCodes[KeyCodes["F2"] = 113] = "F2"; | ||
KeyCodes[KeyCodes["F3"] = 114] = "F3"; | ||
KeyCodes[KeyCodes["F4"] = 115] = "F4"; | ||
KeyCodes[KeyCodes["F5"] = 116] = "F5"; | ||
KeyCodes[KeyCodes["F6"] = 117] = "F6"; | ||
KeyCodes[KeyCodes["F7"] = 118] = "F7"; | ||
KeyCodes[KeyCodes["F8"] = 119] = "F8"; | ||
KeyCodes[KeyCodes["F9"] = 120] = "F9"; | ||
KeyCodes[KeyCodes["F10"] = 121] = "F10"; | ||
KeyCodes[KeyCodes["F11"] = 122] = "F11"; | ||
KeyCodes[KeyCodes["F12"] = 123] = "F12"; | ||
KeyCodes[KeyCodes["NUM_LOCK"] = 144] = "NUM_LOCK"; | ||
KeyCodes[KeyCodes["SCROLL_LOCK"] = 145] = "SCROLL_LOCK"; | ||
KeyCodes[KeyCodes["OPEN_BRACKET"] = 186] = "OPEN_BRACKET"; | ||
KeyCodes[KeyCodes["PLUS"] = 187] = "PLUS"; | ||
KeyCodes[KeyCodes["COMMA"] = 188] = "COMMA"; | ||
KeyCodes[KeyCodes["SLASH"] = 189] = "SLASH"; | ||
KeyCodes[KeyCodes["DOT"] = 190] = "DOT"; | ||
KeyCodes[KeyCodes["PIPE"] = 191] = "PIPE"; | ||
KeyCodes[KeyCodes["SEMICOLON"] = 192] = "SEMICOLON"; | ||
KeyCodes[KeyCodes["MINUS"] = 219] = "MINUS"; | ||
KeyCodes[KeyCodes["GREAT_ACCENT"] = 220] = "GREAT_ACCENT"; | ||
KeyCodes[KeyCodes["EQUALS"] = 221] = "EQUALS"; | ||
KeyCodes[KeyCodes["SINGLE_QUOTE"] = 222] = "SINGLE_QUOTE"; | ||
KeyCodes[KeyCodes["BACKSLASH"] = 226] = "BACKSLASH"; | ||
})(KeyCodes || (KeyCodes = {})); | ||
const KeyCodes = { | ||
BACKSPACE: 8, | ||
TAB: 9, | ||
ENTER: 13, | ||
SHIFT: 16, | ||
CONTROL: 17, | ||
ALT: 18, | ||
BREAK: 19, | ||
CAPS_LOCK: 20, | ||
ESCAPE: 27, | ||
SPACE: 32, | ||
PAGE_UP: 33, | ||
PAGE_DOWN: 34, | ||
END: 35, | ||
HOME: 36, | ||
ARROW_LEFT: 37, | ||
ARROW_UP: 38, | ||
ARROW_RIGHT: 39, | ||
ARROW_DOWN: 40, | ||
PRINT: 44, | ||
INSERT: 45, | ||
DELETE: 46, | ||
DIGIT_0: 48, | ||
DIGIT_1: 49, | ||
DIGIT_2: 50, | ||
DIGIT_3: 51, | ||
DIGIT_4: 52, | ||
DIGIT_5: 53, | ||
DIGIT_6: 54, | ||
DIGIT_7: 55, | ||
DIGIT_8: 56, | ||
DIGIT_9: 57, | ||
A: 65, | ||
B: 66, | ||
C: 67, | ||
D: 68, | ||
E: 69, | ||
F: 70, | ||
G: 71, | ||
H: 72, | ||
I: 73, | ||
J: 74, | ||
K: 75, | ||
L: 76, | ||
M: 77, | ||
N: 78, | ||
O: 79, | ||
P: 80, | ||
Q: 81, | ||
R: 82, | ||
S: 83, | ||
T: 84, | ||
U: 85, | ||
V: 86, | ||
W: 87, | ||
X: 88, | ||
Y: 89, | ||
Z: 90, | ||
WINDOWS: 91, | ||
CONTEXT_MENU: 93, | ||
TURN_OFF: 94, | ||
SLEEP: 95, | ||
NUMPAD_0: 96, | ||
NUMPAD_1: 97, | ||
NUMPAD_2: 98, | ||
NUMPAD_3: 99, | ||
NUMPAD_4: 100, | ||
NUMPAD_5: 101, | ||
NUMPAD_6: 102, | ||
NUMPAD_7: 103, | ||
NUMPAD_8: 104, | ||
NUMPAD_9: 105, | ||
NUMPAD_ASTERISK: 106, | ||
NUMPAD_PLUS: 107, | ||
NUMPAD_MINUS: 109, | ||
NUMPAD_COMMA: 110, | ||
NUMPAD_SLASH: 111, | ||
F1: 112, | ||
F2: 113, | ||
F3: 114, | ||
F4: 115, | ||
F5: 116, | ||
F6: 117, | ||
F7: 118, | ||
F8: 119, | ||
F9: 120, | ||
F10: 121, | ||
F11: 122, | ||
F12: 123, | ||
NUM_LOCK: 144, | ||
SCROLL_LOCK: 145, | ||
COLON: 186, | ||
PLUS: 187, | ||
COMMA: 188, | ||
SLASH: 189, | ||
DOT: 190, | ||
PIPE: 191, | ||
SEMICOLON: 192, | ||
MINUS: 219, | ||
GREAT_ACCENT: 220, | ||
EQUALS: 221, | ||
SINGLE_QUOTE: 222, | ||
BACKSLASH: 226, | ||
}; | ||
const isEnter = (event) => (event.key ? event.key === "Enter" : event.keyCode === KeyCodes.ENTER) && !hasModifierKeys(event); | ||
@@ -174,6 +173,10 @@ const isEnterShift = (event) => (event.key ? event.key === "Enter" : event.keyCode === KeyCodes.ENTER) && checkModifierKeys(event, false, false, true); | ||
const isCtrlV = (event) => ((event.key === "V" || event.key === "v") || event.which === KeyCodes.V) && checkModifierKeys(event, true, false, false); | ||
const isKeyA = (event) => ((event.key === "A" || event.key === "a") || event.which === KeyCodes.A) && checkModifierKeys(event, false, false, false); | ||
const isKeyP = (event) => ((event.key === "P" || event.key === "p") || event.which === KeyCodes.P) && checkModifierKeys(event, false, false, false); | ||
const hasModifierKeys = (event) => event.shiftKey || event.altKey || getCtrlKey(event); | ||
const getCtrlKey = (event) => !!(event.metaKey || event.ctrlKey); // double negation doesn't have effect on boolean but ensures null and undefined are equivalent to false. | ||
const checkModifierKeys = (event, bCtrlKey, bAltKey, bShiftKey) => event.shiftKey === bShiftKey && event.altKey === bAltKey && getCtrlKey(event) === bCtrlKey; | ||
export { isEnter, isEnterShift, isSpace, isSpaceShift, isSpaceCtrl, isLeft, isRight, isUp, isDown, isLeftCtrl, isRightCtrl, isUpCtrl, isDownCtrl, isUpShift, isDownShift, isUpAlt, isDownAlt, isLeftShift, isRightShift, isLeftShiftCtrl, isRightShiftCtrl, isUpShiftCtrl, isDownShiftCtrl, isHome, isEnd, isPlus, isMinus, isHomeCtrl, isEndCtrl, isHomeShift, isEndShift, isEscape, isTabNext, isTabPrevious, isBackSpace, isDelete, isShow, isF4, isF4Shift, isF6Previous, isF6Next, isF7, isPageUp, isPageDown, isPageUpShift, isPageUpAlt, isPageDownShift, isPageDownAlt, isPageUpShiftCtrl, isPageDownShiftCtrl, isShift, isCtrlA, isCtrlV, isDeleteShift, isInsertShift, isInsertCtrl, }; | ||
const isNumber = (event) => ((event.key ? "0123456789".indexOf(event.key) !== -1 : event.keyCode >= KeyCodes.DIGIT_0 && event.keyCode <= KeyCodes.DIGIT_9) && checkModifierKeys(event, false, false, false)); | ||
const isColon = (event) => ((event.key ? event.key === ":" : event.keyCode === KeyCodes.COLON) && checkModifierKeys(event, false, false, true)); | ||
export { isEnter, isEnterShift, isSpace, isSpaceShift, isSpaceCtrl, isLeft, isRight, isUp, isDown, isLeftCtrl, isRightCtrl, isUpCtrl, isDownCtrl, isUpShift, isDownShift, isUpAlt, isDownAlt, isLeftShift, isRightShift, isLeftShiftCtrl, isRightShiftCtrl, isUpShiftCtrl, isDownShiftCtrl, isHome, isEnd, isPlus, isMinus, isHomeCtrl, isEndCtrl, isHomeShift, isEndShift, isEscape, isTabNext, isTabPrevious, isBackSpace, isDelete, isShow, isF4, isF4Shift, isF6Previous, isF6Next, isF7, isPageUp, isPageDown, isPageUpShift, isPageUpAlt, isPageDownShift, isPageDownAlt, isPageUpShiftCtrl, isPageDownShiftCtrl, isShift, isCtrlA, isCtrlV, isKeyA, isKeyP, isDeleteShift, isInsertShift, isInsertCtrl, isNumber, isColon, }; | ||
//# sourceMappingURL=Keys.js.map |
/** | ||
* Re-renders all RTL-aware UI5 Elements. | ||
* | ||
* <b>Note:</b> Call this method whenever you change the "dir" property anywhere in your HTML page. | ||
* <b>Example:</b> <code>document.body.dir = "rtl"; applyDirection();</code> | ||
* **Note:** Call this method whenever you change the "dir" property anywhere in your HTML page. | ||
* | ||
* **Example:** `document.body.dir = "rtl"; applyDirection();` | ||
* @public | ||
@@ -7,0 +8,0 @@ * @returns {Promise<void>} |
@@ -6,4 +6,5 @@ import { reRenderAllUI5Elements } from "../Render.js"; | ||
* | ||
* <b>Note:</b> Call this method whenever you change the "dir" property anywhere in your HTML page. | ||
* <b>Example:</b> <code>document.body.dir = "rtl"; applyDirection();</code> | ||
* **Note:** Call this method whenever you change the "dir" property anywhere in your HTML page. | ||
* | ||
* **Example:** `document.body.dir = "rtl"; applyDirection();` | ||
* @public | ||
@@ -10,0 +11,0 @@ * @returns {Promise<void>} |
@@ -1,2 +0,2 @@ | ||
declare const getEffectiveDir: (element: HTMLElement) => string | undefined; | ||
declare const getEffectiveDir: (element: HTMLElement) => "rtl" | "ltr"; | ||
export default getEffectiveDir; |
@@ -1,24 +0,8 @@ | ||
import { getRTL } from "../config/RTL.js"; | ||
const GLOBAL_DIR_CSS_VAR = "--_ui5_dir"; | ||
const getEffectiveDir = (element) => { | ||
const doc = window.document; | ||
const dirValues = ["ltr", "rtl"]; // exclude "auto" and "" from all calculations | ||
const locallyAppliedDir = getComputedStyle(element).getPropertyValue(GLOBAL_DIR_CSS_VAR); | ||
// In that order, inspect the CSS Var (for modern browsers), the element itself, html and body (for IE fallback) | ||
if (dirValues.includes(locallyAppliedDir)) { | ||
return locallyAppliedDir; | ||
if (element.matches(":dir(rtl)")) { | ||
return "rtl"; | ||
} | ||
if (dirValues.includes(element.dir)) { | ||
return element.dir; | ||
} | ||
if (dirValues.includes(doc.documentElement.dir)) { | ||
return doc.documentElement.dir; | ||
} | ||
if (dirValues.includes(doc.body.dir)) { | ||
return doc.body.dir; | ||
} | ||
// Finally, check the configuration for explicitly set RTL or language-implied RTL | ||
return getRTL() ? "rtl" : undefined; | ||
return "ltr"; | ||
}; | ||
export default getEffectiveDir; | ||
//# sourceMappingURL=getEffectiveDir.js.map |
@@ -1,4 +0,4 @@ | ||
import type UI5Element from "../UI5Element"; | ||
import type UI5Element from "../UI5Element.js"; | ||
declare const markAsRtlAware: (klass: typeof UI5Element) => void; | ||
declare const isRtlAware: (klass: typeof UI5Element) => boolean; | ||
export { markAsRtlAware, isRtlAware, }; |
import { StyleData, StyleDataCSP } from "./types.js"; | ||
declare const createStyle: (data: StyleData, name: string, value?: string) => void; | ||
declare const updateStyle: (data: StyleData, name: string, value?: string) => void; | ||
declare const createStyle: (data: StyleData, name: string, value?: string, theme?: string) => void; | ||
declare const updateStyle: (data: StyleData, name: string, value?: string, theme?: string) => void; | ||
declare const hasStyle: (name: string, value?: string) => boolean; | ||
declare const removeStyle: (name: string, value?: string) => void; | ||
declare const createOrUpdateStyle: (data: StyleData, name: string, value?: string) => void; | ||
export { createStyle, hasStyle, updateStyle, removeStyle, createOrUpdateStyle, }; | ||
declare const createOrUpdateStyle: (data: StyleData, name: string, value?: string, theme?: string) => void; | ||
declare const mergeStyles: (style1?: StyleData, style2?: StyleData) => StyleData | undefined; | ||
export { createStyle, hasStyle, updateStyle, removeStyle, createOrUpdateStyle, mergeStyles, }; | ||
export type { StyleData, StyleDataCSP, }; |
import createStyleInHead from "./util/createStyleInHead.js"; | ||
import createLinkInHead from "./util/createLinkInHead.js"; | ||
import { shouldUseLinks, getUrl } from "./CSP.js"; | ||
import { isSafari } from "./Device.js"; | ||
import { getCurrentRuntimeIndex, compareRuntimes } from "./Runtimes.js"; | ||
const isSSR = typeof document === "undefined"; | ||
const getStyleId = (name, value) => { | ||
return value ? `${name}|${value}` : name; | ||
}; | ||
const createStyle = (data, name, value = "") => { | ||
const shouldUpdate = (runtimeIndex) => { | ||
if (runtimeIndex === undefined) { | ||
return true; | ||
} | ||
return compareRuntimes(getCurrentRuntimeIndex(), parseInt(runtimeIndex)) === 1; // 1 means the current is newer, 0 means the same, -1 means the resource's runtime is newer | ||
}; | ||
const createStyle = (data, name, value = "", theme) => { | ||
const content = typeof data === "string" ? data : data.content; | ||
const currentRuntimeIndex = getCurrentRuntimeIndex(); | ||
if (shouldUseLinks()) { | ||
const attributes = {}; | ||
attributes[name] = value; | ||
if (theme) { | ||
attributes["data-ui5-runtime-index"] = currentRuntimeIndex; | ||
attributes["data-ui5-theme"] = theme; | ||
} | ||
const href = getUrl(data.packageName, data.fileName); | ||
createLinkInHead(href, attributes); | ||
} | ||
else if (document.adoptedStyleSheets) { | ||
else if (document.adoptedStyleSheets && !isSafari()) { | ||
const stylesheet = new CSSStyleSheet(); | ||
stylesheet.replaceSync(content); | ||
stylesheet._ui5StyleId = getStyleId(name, value); // set an id so that we can find the style later | ||
if (theme) { | ||
stylesheet._ui5RuntimeIndex = currentRuntimeIndex; | ||
stylesheet._ui5Theme = theme; | ||
} | ||
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet]; | ||
@@ -24,32 +42,77 @@ } | ||
attributes[name] = value; | ||
if (theme) { | ||
attributes["data-ui5-runtime-index"] = currentRuntimeIndex; | ||
attributes["data-ui5-theme"] = theme; | ||
} | ||
createStyleInHead(content, attributes); | ||
} | ||
}; | ||
const updateStyle = (data, name, value = "") => { | ||
const updateStyle = (data, name, value = "", theme) => { | ||
const content = typeof data === "string" ? data : data.content; | ||
const currentRuntimeIndex = getCurrentRuntimeIndex(); | ||
if (shouldUseLinks()) { | ||
const link = document.querySelector(`head>link[${name}="${value}"]`); | ||
link.href = getUrl(data.packageName, data.fileName); | ||
const href = getUrl(data.packageName, data.fileName); | ||
if (!theme) { | ||
link.href = href; | ||
} | ||
else { | ||
const linkRuntimeIndex = link.getAttribute("data-ui5-runtime-index") || undefined; | ||
const linkTheme = link.getAttribute("data-ui5-theme"); | ||
if (linkTheme !== theme || shouldUpdate(linkRuntimeIndex)) { | ||
link.href = href; | ||
link.setAttribute("data-ui5-runtime-index", String(currentRuntimeIndex)); | ||
link.setAttribute("data-ui5-theme", theme); | ||
} | ||
} | ||
} | ||
else if (document.adoptedStyleSheets) { | ||
else if (document.adoptedStyleSheets && !isSafari()) { | ||
const stylesheet = document.adoptedStyleSheets.find(sh => sh._ui5StyleId === getStyleId(name, value)); | ||
if (stylesheet) { | ||
if (!stylesheet) { | ||
return; | ||
} | ||
if (!theme) { | ||
stylesheet.replaceSync(content || ""); | ||
} | ||
else { | ||
const stylesheetRuntimeIndex = stylesheet._ui5RuntimeIndex; | ||
const stylesheetTheme = stylesheet._ui5Theme; | ||
if (stylesheetTheme !== theme || shouldUpdate(stylesheetRuntimeIndex)) { | ||
stylesheet.replaceSync(content || ""); | ||
stylesheet._ui5RuntimeIndex = String(currentRuntimeIndex); | ||
stylesheet._ui5Theme = theme; | ||
} | ||
} | ||
} | ||
else { | ||
const style = document.querySelector(`head>style[${name}="${value}"]`); | ||
if (style) { | ||
if (!style) { | ||
return; | ||
} | ||
if (!theme) { | ||
style.textContent = content || ""; | ||
} | ||
else { | ||
const styleRuntimeIndex = style.getAttribute("data-ui5-runtime-index") || undefined; | ||
const styleTheme = style.getAttribute("data-ui5-theme"); | ||
if (styleTheme !== theme || shouldUpdate(styleRuntimeIndex)) { | ||
style.textContent = content || ""; | ||
style.setAttribute("data-ui5-runtime-index", String(currentRuntimeIndex)); | ||
style.setAttribute("data-ui5-theme", theme); | ||
} | ||
} | ||
} | ||
}; | ||
const hasStyle = (name, value = "") => { | ||
if (isSSR) { | ||
return true; | ||
} | ||
if (shouldUseLinks()) { | ||
return !!document.querySelector(`head>link[${name}="${value}"]`); | ||
} | ||
if (document.adoptedStyleSheets) { | ||
return !!document.adoptedStyleSheets.find(sh => sh._ui5StyleId === getStyleId(name, value)); | ||
const styleElement = document.querySelector(`head>style[${name}="${value}"]`); | ||
if (document.adoptedStyleSheets && !isSafari()) { | ||
return !!styleElement || !!document.adoptedStyleSheets.find(sh => sh._ui5StyleId === getStyleId(name, value)); | ||
} | ||
return !!document.querySelector(`head>style[${name}="${value}"]`); | ||
return !!styleElement; | ||
}; | ||
@@ -61,3 +124,3 @@ const removeStyle = (name, value = "") => { | ||
} | ||
else if (document.adoptedStyleSheets) { | ||
else if (document.adoptedStyleSheets && !isSafari()) { | ||
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(sh => sh._ui5StyleId !== getStyleId(name, value)); | ||
@@ -70,11 +133,28 @@ } | ||
}; | ||
const createOrUpdateStyle = (data, name, value = "") => { | ||
const createOrUpdateStyle = (data, name, value = "", theme) => { | ||
if (hasStyle(name, value)) { | ||
updateStyle(data, name, value); | ||
updateStyle(data, name, value, theme); | ||
} | ||
else { | ||
createStyle(data, name, value); | ||
createStyle(data, name, value, theme); | ||
} | ||
}; | ||
export { createStyle, hasStyle, updateStyle, removeStyle, createOrUpdateStyle, }; | ||
const mergeStyles = (style1, style2) => { | ||
if (style1 === undefined) { | ||
return style2; | ||
} | ||
if (style2 === undefined) { | ||
return style1; | ||
} | ||
const style2Content = typeof style2 === "string" ? style2 : style2.content; | ||
if (typeof style1 === "string") { | ||
return `${style1} ${style2Content}`; | ||
} | ||
return { | ||
content: `${style1.content} ${style2Content}`, | ||
packageName: style1.packageName, | ||
fileName: style1.fileName, | ||
}; | ||
}; | ||
export { createStyle, hasStyle, updateStyle, removeStyle, createOrUpdateStyle, mergeStyles, }; | ||
//# sourceMappingURL=ManagedStyles.js.map |
@@ -5,4 +5,2 @@ type Range = Map<string, Array<number>>; | ||
* | ||
* @namespace | ||
* @name MediaRange.RANGESETS | ||
* @public | ||
@@ -15,10 +13,9 @@ */ | ||
* The ranges of this set are: | ||
* <ul> | ||
* <li><code>"S"</code>: For screens smaller than 600 pixels.</li> | ||
* <li><code>"M"</code>: For screens greater than or equal to 600 pixels and smaller than 1024 pixels.</li> | ||
* <li><code>"L"</code>: For screens greater than or equal to 1024 pixels and smaller than 1440 pixels.</li> | ||
* <li><code>"XL"</code>: For screens greater than or equal to 1440 pixels.</li> | ||
* </ul> | ||
* | ||
* @name MediaRange.RANGESETS.RANGE_4STEPS | ||
* - `"S"`: For screens smaller than 600 pixels. | ||
* - `"M"`: For screens greater than or equal to 600 pixels and smaller than 1024 pixels. | ||
* - `"L"`: For screens greater than or equal to 1024 pixels and smaller than 1440 pixels. | ||
* - `"XL"`: For screens greater than or equal to 1440 pixels. | ||
* | ||
* | ||
* @public | ||
@@ -30,5 +27,2 @@ */ | ||
* API for screen width changes. | ||
* | ||
* @namespace | ||
* @name MediaRange | ||
*/ | ||
@@ -35,0 +29,0 @@ declare const MediaRange: { |
@@ -10,4 +10,2 @@ const mediaRanges = new Map(); | ||
* | ||
* @namespace | ||
* @name MediaRange.RANGESETS | ||
* @public | ||
@@ -21,10 +19,9 @@ */ | ||
* The ranges of this set are: | ||
* <ul> | ||
* <li><code>"S"</code>: For screens smaller than 600 pixels.</li> | ||
* <li><code>"M"</code>: For screens greater than or equal to 600 pixels and smaller than 1024 pixels.</li> | ||
* <li><code>"L"</code>: For screens greater than or equal to 1024 pixels and smaller than 1440 pixels.</li> | ||
* <li><code>"XL"</code>: For screens greater than or equal to 1440 pixels.</li> | ||
* </ul> | ||
* | ||
* @name MediaRange.RANGESETS.RANGE_4STEPS | ||
* - `"S"`: For screens smaller than 600 pixels. | ||
* - `"M"`: For screens greater than or equal to 600 pixels and smaller than 1024 pixels. | ||
* - `"L"`: For screens greater than or equal to 1024 pixels and smaller than 1440 pixels. | ||
* - `"XL"`: For screens greater than or equal to 1440 pixels. | ||
* | ||
* | ||
* @public | ||
@@ -37,19 +34,18 @@ */ | ||
* | ||
* This initialization step makes the range set ready to be used for one of the other functions in namespace <code>MediaRange</code>. | ||
* This initialization step makes the range set ready to be used for one of the other functions in namespace `MediaRange`. | ||
* | ||
* A range set can be defined as shown in the following example: | ||
* <pre> | ||
* ``` | ||
* MediaRange.initRangeSet("MyRangeSet", [200, 400], ["Small", "Medium", "Large"]); | ||
* </pre> | ||
* ``` | ||
* This example defines the following named ranges: | ||
* <ul> | ||
* <li><code>"Small"</code>: For screens smaller than 200 pixels.</li> | ||
* <li><code>"Medium"</code>: For screens greater than or equal to 200 pixels and smaller than 400 pixels.</li> | ||
* <li><code>"Large"</code>: For screens greater than or equal to 400 pixels.</li> | ||
* </ul> | ||
* | ||
* @param {string} name The name of the range set to be initialized. | ||
* - `"Small"`: For screens smaller than 200 pixels. | ||
* - `"Medium"`: For screens greater than or equal to 200 pixels and smaller than 400 pixels. | ||
* - `"Large"`: For screens greater than or equal to 400 pixels. | ||
* | ||
* | ||
* @param name The name of the range set to be initialized. | ||
* The name must be a valid id and consist only of letters and numeric digits. | ||
* @param {Range} [range] The given range set. | ||
* @name MediaRange.initRangeSet | ||
* @param range The given range set. | ||
*/ | ||
@@ -62,12 +58,9 @@ const initRangeSet = (name, range) => { | ||
* | ||
* If the optional parameter <code>width</code> is given, the active range will be determined for that width, | ||
* If the optional parameter `width` is given, the active range will be determined for that width, | ||
* otherwise it is determined for the current window size. | ||
* | ||
* @param {string} name The name of the range set. The range set must be initialized beforehand ({@link MediaRange.initRangeSet}) | ||
* @param {number} [width] An optional width, based on which the range should be determined; | ||
* If <code>width</code> is not provided, the window size will be used. | ||
* @returns {string} The name of the current active interval of the range set. | ||
* | ||
* @name MediaRange.getCurrentRange | ||
* @function | ||
* @param name The name of the range set. The range set must be initialized beforehand ({@link MediaRange.initRangeSet}) | ||
* @param [width] An optional width, based on which the range should be determined; | ||
* If `width` is not provided, the window size will be used. | ||
* @returns The name of the current active interval of the range set. | ||
* @public | ||
@@ -91,5 +84,2 @@ */ | ||
* API for screen width changes. | ||
* | ||
* @namespace | ||
* @name MediaRange | ||
*/ | ||
@@ -96,0 +86,0 @@ const MediaRange = { |
@@ -0,1 +1,3 @@ | ||
// @ts-nocheck | ||
/* eslint-disable */ | ||
/** | ||
@@ -6,68 +8,66 @@ * @license | ||
*/ | ||
/** | ||
* This is the original style-map.js directive from lit-html 2 with the only difference that "render" is not called even for the first rendering (update is used instead) | ||
*/ | ||
import { noChange } from 'lit-html'; | ||
import { directive, Directive, PartType, } from 'lit-html/directive.js'; | ||
class StyleMapDirective extends Directive { | ||
constructor(partInfo) { | ||
var _a; | ||
super(partInfo); | ||
if (partInfo.type !== PartType.ATTRIBUTE || | ||
partInfo.name !== 'style' || | ||
((_a = partInfo.strings) === null || _a === void 0 ? void 0 : _a.length) > 2) { | ||
throw new Error('The `styleMap` directive must be used in the `style` attribute ' + | ||
'and must be the only part in the attribute.'); | ||
} | ||
} | ||
render(styleInfo) { | ||
return ""; | ||
} | ||
update(part, [styleInfo]) { | ||
const { style } = part.element; | ||
if (this._previousStyleProperties === undefined) { | ||
this._previousStyleProperties = new Set(); | ||
for (const name in styleInfo) { | ||
this._previousStyleProperties.add(name); | ||
} | ||
// return this.render(styleInfo); | ||
} | ||
// Remove old properties that no longer exist in styleInfo | ||
// We use forEach() instead of for-of so that re don't require down-level | ||
// iteration. | ||
this._previousStyleProperties.forEach((name) => { | ||
// If the name isn't in styleInfo or it's null/undefined | ||
if (styleInfo[name] == null) { | ||
this._previousStyleProperties.delete(name); | ||
if (name.includes('-')) { | ||
style.removeProperty(name); | ||
} | ||
else { | ||
// Note reset using empty string (vs null) as IE11 does not always | ||
// reset via null (https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style#setting_styles) | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
style[name] = ''; | ||
} | ||
} | ||
}); | ||
// Add or update properties | ||
for (const name in styleInfo) { | ||
const value = styleInfo[name]; | ||
if (value != null) { | ||
this._previousStyleProperties.add(name); | ||
if (name.includes('-')) { | ||
style.setProperty(name, value); | ||
} | ||
else { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
style[name] = value; | ||
} | ||
} | ||
} | ||
return noChange; | ||
} | ||
constructor(partInfo) { | ||
var _a; | ||
super(partInfo); | ||
if (partInfo.type !== PartType.ATTRIBUTE || | ||
partInfo.name !== 'style' || | ||
((_a = partInfo.strings) === null || _a === void 0 ? void 0 : _a.length) > 2) { | ||
throw new Error('The `styleMap` directive must be used in the `style` attribute ' + | ||
'and must be the only part in the attribute.'); | ||
} | ||
} | ||
render(styleInfo) { | ||
return ""; | ||
} | ||
update(part, [styleInfo]) { | ||
const { style } = part.element; | ||
if (this._previousStyleProperties === undefined) { | ||
this._previousStyleProperties = new Set(); | ||
for (const name in styleInfo) { | ||
this._previousStyleProperties.add(name); | ||
} | ||
// return this.render(styleInfo); | ||
} | ||
// Remove old properties that no longer exist in styleInfo | ||
// We use forEach() instead of for-of so that re don't require down-level | ||
// iteration. | ||
this._previousStyleProperties.forEach((name) => { | ||
// If the name isn't in styleInfo or it's null/undefined | ||
if (styleInfo[name] == null) { | ||
this._previousStyleProperties.delete(name); | ||
if (name.includes('-')) { | ||
style.removeProperty(name); | ||
} | ||
else { | ||
// Note reset using empty string (vs null) as IE11 does not always | ||
// reset via null (https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style#setting_styles) | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
style[name] = ''; | ||
} | ||
} | ||
}); | ||
// Add or update properties | ||
for (const name in styleInfo) { | ||
const value = styleInfo[name]; | ||
if (value != null) { | ||
this._previousStyleProperties.add(name); | ||
if (name.includes('-')) { | ||
style.setProperty(name, value); | ||
} | ||
else { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
style[name] = value; | ||
} | ||
} | ||
} | ||
return noChange; | ||
} | ||
} | ||
export const styleMap = directive(StyleMapDirective); | ||
//# sourceMappingURL=style-map.js.map |
@@ -12,3 +12,3 @@ import { getCustomElementsScopingSuffix, shouldScopeCustomElement } from "../CustomElementsScopeUtils.js"; | ||
const scope = getCustomElementsScopingSuffix(); | ||
return template(component, tagsToScope, scope); | ||
return template.call(component, component, tagsToScope, scope); | ||
}; | ||
@@ -15,0 +15,0 @@ /** |
@@ -1,6 +0,6 @@ | ||
import { TemplateResult, RenderOptions } from "lit-html"; | ||
import { TemplateFunctionResult } from "./executeTemplate.js"; | ||
declare const effectiveHtml: (strings: TemplateStringsArray, ...values: Array<unknown>) => TemplateResult<1 | 2>; | ||
declare const effectiveSvg: (strings: TemplateStringsArray, ...values: Array<unknown>) => TemplateResult<1 | 2>; | ||
declare const litRender: (templateResult: TemplateFunctionResult, container: HTMLElement | DocumentFragment, styleStrOrHrefsArr: string | Array<string> | undefined, forStaticArea: boolean, options: RenderOptions) => void; | ||
import { TemplateResult } from "lit-html"; | ||
import type { Renderer } from "../UI5Element.js"; | ||
declare const effectiveHtml: (strings: TemplateStringsArray, ...values: Array<unknown>) => TemplateResult; | ||
declare const effectiveSvg: (strings: TemplateStringsArray, ...values: Array<unknown>) => TemplateResult; | ||
declare const litRender: Renderer; | ||
declare const scopeTag: (tag: string, tags: Array<string>, suffix: string) => object | undefined; | ||
@@ -7,0 +7,0 @@ export { effectiveHtml as html, effectiveSvg as svg, }; |
@@ -0,7 +1,34 @@ | ||
// TODO-evo:assert on node throws an error if the assertion is violated | ||
/** | ||
* A simple assertion mechanism that logs a message when a given condition is not met. | ||
* | ||
* <b>Note:</b> Calls to this method might be removed when the JavaScript code | ||
* is optimized during build. Therefore, callers should not rely on any side effects | ||
* of this method. | ||
* | ||
* @function | ||
* @since 1.58 | ||
* @alias module:sap/base/assert | ||
* @param {boolean} bResult Result of the checked assertion | ||
* @param {string|function():any} vMessage Message that will be logged when the result is <code>false</code>. | ||
* In case this is a function, the return value of the function will be displayed. This can be used to execute | ||
* complex code only if the assertion fails. | ||
* @public | ||
* @SecSink {1|SECRET} Could expose secret data in logs | ||
* | ||
*/ /*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
var fnAssert = function (bResult, vMessage) { | ||
if (!bResult) { | ||
var sMessage = typeof vMessage === "function" ? vMessage() : vMessage; | ||
/*eslint-disable no-console */ | ||
console.assert(bResult, sMessage); | ||
/*eslint-enable no-console */ | ||
} | ||
}; | ||
export default fnAssert; | ||
export default fnAssert; |
@@ -1,240 +0,750 @@ | ||
import now from './util/now.js'; | ||
/*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
import BaseConfig from "./config.js"; | ||
import now from "./util/now.js"; | ||
/** | ||
* A Logging API for JavaScript. | ||
* | ||
* Provides methods to manage a client-side log and to create entries in it. Each of the logging methods | ||
* {@link module:sap/base/Log.debug}, {@link module:sap/base/Log.info}, {@link module:sap/base/Log.warning}, | ||
* {@link module:sap/base/Log.error} and {@link module:sap/base/Log.fatal} creates and records a log entry, | ||
* containing a timestamp, a log level, a message with details and a component info. | ||
* The log level will be one of {@link module:sap/base/Log.Level} and equals the name of the concrete logging method. | ||
* | ||
* By using the {@link module:sap/base/Log.setLevel} method, consumers can determine the least important | ||
* log level which should be recorded. Less important entries will be filtered out. (Note that higher numeric | ||
* values represent less important levels). The initially set level depends on the mode that UI5 is running in. | ||
* When the optimized sources are executed, the default level will be {@link module:sap/base/Log.Level.ERROR}. | ||
* For normal (debug sources), the default level is {@link module:sap/base/Log.Level.DEBUG}. | ||
* | ||
* All logging methods allow to specify a <b>component</b>. These components are simple strings and | ||
* don't have a special meaning to the UI5 framework. However they can be used to semantically group | ||
* log entries that belong to the same software component (or feature). There are two APIs that help | ||
* to manage logging for such a component. With {@link module:sap/base/Log.getLogger}, | ||
* one can retrieve a logger that automatically adds the given <code>sComponent</code> as component | ||
* parameter to each log entry, if no other component is specified. Typically, JavaScript code will | ||
* retrieve such a logger once during startup and reuse it for the rest of its lifecycle. | ||
* Second, the {@link module:sap/base/Log.setLevel}(iLevel, sComponent) method allows to set the log level | ||
* for a specific component only. This allows a more fine grained control about the created logging entries. | ||
* {@link module:sap/base/Log.getLevel} allows to retrieve the currently effective log level for a given | ||
* component. | ||
* | ||
* {@link module:sap/base/Log.getLogEntries} returns an array of the currently collected log entries. | ||
* | ||
* Furthermore, a listener can be registered to the log. It will be notified whenever a new entry | ||
* is added to the log. The listener can be used for displaying log entries in a separate page area, | ||
* or for sending it to some external target (server). | ||
* | ||
* @public | ||
* @since 1.58 | ||
* @namespace | ||
* @alias module:sap/base/Log | ||
*/ | ||
var Log = {}; | ||
/** | ||
* Enumeration of the configurable log levels that a Logger should persist to the log. | ||
* | ||
* Only if the current LogLevel is higher than the level {@link module:sap/base/Log.Level} of the currently added log entry, | ||
* then this very entry is permanently added to the log. Otherwise it is ignored. | ||
* @enum {int} | ||
* @public | ||
*/ | ||
Log.Level = { | ||
NONE: -1, | ||
FATAL: 0, | ||
ERROR: 1, | ||
WARNING: 2, | ||
INFO: 3, | ||
DEBUG: 4, | ||
TRACE: 5, | ||
ALL: 5 + 1 | ||
/** | ||
* Do not log anything | ||
* @public | ||
*/ | ||
NONE: -1, | ||
/** | ||
* Fatal level. Use this for logging unrecoverable situations | ||
* @public | ||
*/ | ||
FATAL: 0, | ||
/** | ||
* Error level. Use this for logging of erroneous but still recoverable situations | ||
* @public | ||
*/ | ||
ERROR: 1, | ||
/** | ||
* Warning level. Use this for logging unwanted but foreseen situations | ||
* @public | ||
*/ | ||
WARNING: 2, | ||
/** | ||
* Info level. Use this for logging information of purely informative nature | ||
* @public | ||
*/ | ||
INFO: 3, | ||
/** | ||
* Debug level. Use this for logging information necessary for debugging | ||
* @public | ||
*/ | ||
DEBUG: 4, | ||
/** | ||
* Trace level. Use this for tracing the program flow. | ||
* @public | ||
*/ | ||
TRACE: 5, | ||
/** | ||
* Trace level to log everything. | ||
* @public | ||
*/ | ||
ALL: 5 + 1 | ||
}; | ||
var aLog = [], mMaxLevel = { '': Log.Level.ERROR }, iLogEntriesLimit = 3000, oListener = null, bLogSupportInfo = false; | ||
/** | ||
* The array that holds the log entries that have been recorded so far | ||
*/ | ||
var aLog = [], | ||
/** | ||
* Maximum log level to be recorded (per component). | ||
*/ | ||
mMaxLevel = { | ||
'': Log.Level.ERROR | ||
}, | ||
/** | ||
* Maximum amount of stored log entries | ||
*/ | ||
iLogEntriesLimit = 3000, | ||
/** | ||
* Registered listener to be informed about new log entries. | ||
*/ | ||
oListener = null, | ||
/** | ||
* Additional support information delivered by callback should be logged | ||
*/ | ||
bLogSupportInfo = false; | ||
function pad0(i, w) { | ||
return ('000' + String(i)).slice(-w); | ||
return ("000" + String(i)).slice(-w); | ||
} | ||
function level(sComponent) { | ||
return !sComponent || isNaN(mMaxLevel[sComponent]) ? mMaxLevel[''] : mMaxLevel[sComponent]; | ||
return !sComponent || isNaN(mMaxLevel[sComponent]) ? mMaxLevel[''] : mMaxLevel[sComponent]; | ||
} | ||
/** | ||
* Discard 30 percent of log entries when the limit is reached | ||
*/ | ||
function discardLogEntries() { | ||
var iLogLength = aLog.length; | ||
if (iLogLength) { | ||
var iEntriesToKeep = Math.min(iLogLength, Math.floor(iLogEntriesLimit * 0.7)); | ||
if (oListener) { | ||
oListener.onDiscardLogEntries(aLog.slice(0, iLogLength - iEntriesToKeep)); | ||
} | ||
if (iEntriesToKeep) { | ||
aLog = aLog.slice(-iEntriesToKeep, iLogLength); | ||
} else { | ||
aLog = []; | ||
} | ||
var iLogLength = aLog.length; | ||
if (iLogLength) { | ||
var iEntriesToKeep = Math.min(iLogLength, Math.floor(iLogEntriesLimit * 0.7)); | ||
if (oListener) { | ||
// Notify listener that entries are being discarded | ||
oListener.onDiscardLogEntries(aLog.slice(0, iLogLength - iEntriesToKeep)); | ||
} | ||
if (iEntriesToKeep) { | ||
aLog = aLog.slice(-iEntriesToKeep, iLogLength); | ||
} else { | ||
aLog = []; | ||
} | ||
} | ||
} | ||
/** | ||
* Gets the log entry listener instance, if not present creates a new one | ||
* @returns {Object} the singleton log entry listener | ||
*/ | ||
function getLogEntryListenerInstance() { | ||
if (!oListener) { | ||
oListener = { | ||
listeners: [], | ||
onLogEntry: function (oLogEntry) { | ||
for (var i = 0; i < oListener.listeners.length; i++) { | ||
if (oListener.listeners[i].onLogEntry) { | ||
oListener.listeners[i].onLogEntry(oLogEntry); | ||
} | ||
} | ||
}, | ||
onDiscardLogEntries: function (aDiscardedLogEntries) { | ||
for (var i = 0; i < oListener.listeners.length; i++) { | ||
if (oListener.listeners[i].onDiscardLogEntries) { | ||
oListener.listeners[i].onDiscardLogEntries(aDiscardedLogEntries); | ||
} | ||
} | ||
}, | ||
attach: function (oLog, oLstnr) { | ||
if (oLstnr) { | ||
oListener.listeners.push(oLstnr); | ||
if (oLstnr.onAttachToLog) { | ||
oLstnr.onAttachToLog(oLog); | ||
} | ||
} | ||
}, | ||
detach: function (oLog, oLstnr) { | ||
for (var i = 0; i < oListener.listeners.length; i++) { | ||
if (oListener.listeners[i] === oLstnr) { | ||
if (oLstnr.onDetachFromLog) { | ||
oLstnr.onDetachFromLog(oLog); | ||
} | ||
oListener.listeners.splice(i, 1); | ||
return; | ||
} | ||
} | ||
if (!oListener) { | ||
oListener = { | ||
listeners: [], | ||
onLogEntry: function (oLogEntry) { | ||
for (var i = 0; i < oListener.listeners.length; i++) { | ||
if (oListener.listeners[i].onLogEntry) { | ||
oListener.listeners[i].onLogEntry(oLogEntry); | ||
} | ||
} | ||
}, | ||
onDiscardLogEntries: function (aDiscardedLogEntries) { | ||
for (var i = 0; i < oListener.listeners.length; i++) { | ||
if (oListener.listeners[i].onDiscardLogEntries) { | ||
oListener.listeners[i].onDiscardLogEntries(aDiscardedLogEntries); | ||
} | ||
} | ||
}, | ||
attach: function (oLog, oLstnr) { | ||
if (oLstnr) { | ||
oListener.listeners.push(oLstnr); | ||
if (oLstnr.onAttachToLog) { | ||
oLstnr.onAttachToLog(oLog); | ||
} | ||
} | ||
}, | ||
detach: function (oLog, oLstnr) { | ||
for (var i = 0; i < oListener.listeners.length; i++) { | ||
if (oListener.listeners[i] === oLstnr) { | ||
if (oLstnr.onDetachFromLog) { | ||
oLstnr.onDetachFromLog(oLog); | ||
} | ||
}; | ||
} | ||
return oListener; | ||
oListener.listeners.splice(i, 1); | ||
return; | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
return oListener; | ||
} | ||
/** | ||
* Creates a new fatal-level entry in the log with the given message, details and calling component. | ||
* | ||
* @param {string} sMessage | ||
* Message text to display | ||
* @param {string|Error} [vDetails=''] | ||
* Optional details about the message, might be omitted. Can be an Error object which will be | ||
* logged together with its stacktrace. | ||
* @param {string} [sComponent=''] | ||
* Name of the component that produced the log entry | ||
* @param {function} [fnSupportInfo] | ||
* Callback that returns an additional support object to be logged in support mode. | ||
* This function is only called if support info mode is turned on with | ||
* <code>logSupportInfo(true)</code>. To avoid negative effects regarding execution times and | ||
* memory consumption, the returned object should be a simple immutable JSON object with mostly | ||
* static and stable content. | ||
* @public | ||
* @SecSink {0 1 2|SECRET} Could expose secret data in logs | ||
*/ | ||
Log.fatal = function (sMessage, vDetails, sComponent, fnSupportInfo) { | ||
log(Log.Level.FATAL, sMessage, vDetails, sComponent, fnSupportInfo); | ||
log(Log.Level.FATAL, sMessage, vDetails, sComponent, fnSupportInfo); | ||
}; | ||
/** | ||
* Creates a new error-level entry in the log with the given message, details and calling component. | ||
* | ||
* @param {string} sMessage | ||
* Message text to display | ||
* @param {string|Error} [vDetails=''] | ||
* Optional details about the message, might be omitted. Can be an Error object which will be | ||
* logged together with its stacktrace. | ||
* @param {string} [sComponent=''] | ||
* Name of the component that produced the log entry | ||
* @param {function} [fnSupportInfo] | ||
* Callback that returns an additional support object to be logged in support mode. | ||
* This function is only called if support info mode is turned on with | ||
* <code>logSupportInfo(true)</code>. To avoid negative effects regarding execution times and | ||
* memory consumption, the returned object should be a simple immutable JSON object with mostly | ||
* static and stable content. | ||
* @public | ||
* @SecSink {0 1 2|SECRET} Could expose secret data in logs | ||
*/ | ||
Log.error = function (sMessage, vDetails, sComponent, fnSupportInfo) { | ||
log(Log.Level.ERROR, sMessage, vDetails, sComponent, fnSupportInfo); | ||
log(Log.Level.ERROR, sMessage, vDetails, sComponent, fnSupportInfo); | ||
}; | ||
/** | ||
* Creates a new warning-level entry in the log with the given message, details and calling component. | ||
* | ||
* @param {string} sMessage | ||
* Message text to display | ||
* @param {string|Error} [vDetails=''] | ||
* Optional details about the message, might be omitted. Can be an Error object which will be | ||
* logged together with its stacktrace. | ||
* @param {string} [sComponent=''] | ||
* Name of the component that produced the log entry | ||
* @param {function} [fnSupportInfo] | ||
* Callback that returns an additional support object to be logged in support mode. | ||
* This function is only called if support info mode is turned on with | ||
* <code>logSupportInfo(true)</code>. To avoid negative effects regarding execution times and | ||
* memory consumption, the returned object should be a simple immutable JSON object with mostly | ||
* static and stable content. | ||
* @public | ||
* @SecSink {0 1 2|SECRET} Could expose secret data in logs | ||
*/ | ||
Log.warning = function (sMessage, vDetails, sComponent, fnSupportInfo) { | ||
log(Log.Level.WARNING, sMessage, vDetails, sComponent, fnSupportInfo); | ||
log(Log.Level.WARNING, sMessage, vDetails, sComponent, fnSupportInfo); | ||
}; | ||
/** | ||
* Creates a new info-level entry in the log with the given message, details and calling component. | ||
* | ||
* @param {string} sMessage | ||
* Message text to display | ||
* @param {string|Error} [vDetails=''] | ||
* Optional details about the message, might be omitted. Can be an Error object which will be | ||
* logged with the stack. | ||
* @param {string} [sComponent=''] | ||
* Name of the component that produced the log entry | ||
* @param {function} [fnSupportInfo] | ||
* Callback that returns an additional support object to be logged in support mode. | ||
* This function is only called if support info mode is turned on with | ||
* <code>logSupportInfo(true)</code>. To avoid negative effects regarding execution times and | ||
* memory consumption, the returned object should be a simple immutable JSON object with mostly | ||
* static and stable content. | ||
* @public | ||
* @SecSink {0 1 2|SECRET} Could expose secret data in logs | ||
*/ | ||
Log.info = function (sMessage, vDetails, sComponent, fnSupportInfo) { | ||
log(Log.Level.INFO, sMessage, vDetails, sComponent, fnSupportInfo); | ||
log(Log.Level.INFO, sMessage, vDetails, sComponent, fnSupportInfo); | ||
}; | ||
/** | ||
* Creates a new debug-level entry in the log with the given message, details and calling component. | ||
* | ||
* @param {string} sMessage | ||
* Message text to display | ||
* @param {string|Error} [vDetails=''] | ||
* Optional details about the message, might be omitted. Can be an Error object which will be | ||
* logged with the stack. | ||
* @param {string} [sComponent=''] | ||
* Name of the component that produced the log entry | ||
* @param {function} [fnSupportInfo] | ||
* Callback that returns an additional support object to be logged in support mode. | ||
* This function is only called if support info mode is turned on with | ||
* <code>logSupportInfo(true)</code>. To avoid negative effects regarding execution times and | ||
* memory consumption, the returned object should be a simple immutable JSON object with mostly | ||
* static and stable content. | ||
* @public | ||
* @SecSink {0 1 2|SECRET} Could expose secret data in logs | ||
*/ | ||
Log.debug = function (sMessage, vDetails, sComponent, fnSupportInfo) { | ||
log(Log.Level.DEBUG, sMessage, vDetails, sComponent, fnSupportInfo); | ||
log(Log.Level.DEBUG, sMessage, vDetails, sComponent, fnSupportInfo); | ||
}; | ||
/** | ||
* Creates a new trace-level entry in the log with the given message, details and calling component. | ||
* | ||
* @param {string} sMessage | ||
* Message text to display | ||
* @param {string|Error} [vDetails=''] | ||
* Optional details about the message, might be omitted. Can be an Error object which will be | ||
* logged with the stack. | ||
* @param {string} [sComponent=''] | ||
* Name of the component that produced the log entry | ||
* @param {function} [fnSupportInfo] | ||
* Callback that returns an additional support object to be logged in support mode. | ||
* This function is only called if support info mode is turned on with | ||
* <code>logSupportInfo(true)</code>. To avoid negative effects regarding execution times and | ||
* memory consumption, the returned object should be a simple immutable JSON object with mostly | ||
* static and stable content. | ||
* @public | ||
* @SecSink {0 1 2|SECRET} Could expose secret data in logs | ||
*/ | ||
Log.trace = function (sMessage, vDetails, sComponent, fnSupportInfo) { | ||
log(Log.Level.TRACE, sMessage, vDetails, sComponent, fnSupportInfo); | ||
log(Log.Level.TRACE, sMessage, vDetails, sComponent, fnSupportInfo); | ||
}; | ||
/** | ||
* Defines the maximum <code>sap/base/Log.Level</code> of log entries that will be recorded. | ||
* Log entries with a higher (less important) log level will be omitted from the log. | ||
* When a component name is given, the log level will be configured for that component | ||
* only, otherwise the log level for the default component of this logger is set. | ||
* For the global logger, the global default level is set. | ||
* | ||
* <b>Note</b>: Setting a global default log level has no impact on already defined | ||
* component log levels. They always override the global default log level. | ||
* | ||
* @param {module:sap/base/Log.Level} iLogLevel The new log level | ||
* @param {string} [sComponent] The log component to set the log level for | ||
* @public | ||
*/ | ||
Log.setLevel = function (iLogLevel, sComponent, _bDefault) { | ||
sComponent = sComponent || ''; | ||
if (!_bDefault || mMaxLevel[sComponent] == null) { | ||
mMaxLevel[sComponent] = iLogLevel; | ||
var sLogLevel; | ||
Object.keys(Log.Level).forEach(function (sLevel) { | ||
if (Log.Level[sLevel] === iLogLevel) { | ||
sLogLevel = sLevel; | ||
} | ||
}); | ||
log(Log.Level.INFO, 'Changing log level ' + (sComponent ? 'for \'' + sComponent + '\' ' : '') + 'to ' + sLogLevel, '', 'sap.base.log'); | ||
} | ||
sComponent = sComponent || ''; | ||
if (!_bDefault || mMaxLevel[sComponent] == null) { | ||
mMaxLevel[sComponent] = iLogLevel; | ||
var sLogLevel; | ||
Object.keys(Log.Level).forEach(function (sLevel) { | ||
if (Log.Level[sLevel] === iLogLevel) { | ||
sLogLevel = sLevel; | ||
} | ||
}); | ||
log(Log.Level.INFO, "Changing log level " + (sComponent ? "for '" + sComponent + "' " : "") + "to " + sLogLevel, "", "sap.base.log"); | ||
} | ||
}; | ||
/** | ||
* Returns the log level currently effective for the given component. | ||
* If no component is given or when no level has been configured for a | ||
* given component, the log level for the default component of this logger is returned. | ||
* | ||
* @param {string} [sComponent] Name of the component to retrieve the log level for | ||
* @returns {module:sap/base/Log.Level} The log level for the given component or the default log level | ||
* @public | ||
*/ | ||
Log.getLevel = function (sComponent) { | ||
return level(sComponent); | ||
return level(sComponent); | ||
}; | ||
/** | ||
* Checks whether logging is enabled for the given log level, | ||
* depending on the currently effective log level for the given component. | ||
* | ||
* If no component is given, the default component of this logger will be taken into account. | ||
* | ||
* @param {module:sap/base/Log.Level} [iLevel=Level.DEBUG] The log level in question | ||
* @param {string} [sComponent] Name of the component to check the log level for | ||
* @returns {boolean} Whether logging is enabled or not | ||
* @public | ||
*/ | ||
Log.isLoggable = function (iLevel, sComponent) { | ||
return (iLevel == null ? Log.Level.DEBUG : iLevel) <= level(sComponent); | ||
return (iLevel == null ? Log.Level.DEBUG : iLevel) <= level(sComponent); | ||
}; | ||
/** | ||
* Enables or disables whether additional support information is logged in a trace. | ||
* If enabled, logging methods like error, warning, info and debug are calling the additional | ||
* optional callback parameter fnSupportInfo and store the returned object in the log entry property supportInfo. | ||
* | ||
* @param {boolean} bEnabled true if the support information should be logged | ||
* @private | ||
* @ui5-restricted sap.ui.support | ||
*/ | ||
Log.logSupportInfo = function (bEnabled) { | ||
bLogSupportInfo = bEnabled; | ||
bLogSupportInfo = bEnabled; | ||
}; | ||
/** | ||
* Creates a new log entry depending on its level and component. | ||
* | ||
* If the given level is higher than the max level for the given component | ||
* (or higher than the global level, if no component is given), | ||
* then no entry is created and <code>undefined</code> is returned. | ||
* | ||
* If an <code>Error</code> is passed via <code>vDetails</code> the stack | ||
* of the <code>Error</code> will be logged as a separate parameter in | ||
* the proper <code>console</code> function for the matching log level. | ||
* | ||
* @param {module:sap/base/Log.Level} iLevel | ||
* One of the log levels FATAL, ERROR, WARNING, INFO, DEBUG, TRACE | ||
* @param {string} sMessage | ||
* The message to be logged | ||
* @param {string|Error} [vDetails] | ||
* The optional details for the message; could be an Error which will be logged with the | ||
* stacktrace, to easily find the root cause of the Error | ||
* @param {string} [sComponent] | ||
* The log component under which the message should be logged | ||
* @param {function} [fnSupportInfo] Callback that returns an additional support object to be | ||
* logged in support mode. This function is only called if support info mode is turned on with | ||
* <code>logSupportInfo(true)</code>. To avoid negative effects regarding execution times and | ||
* memory consumption, the returned object should be a simple immutable JSON object with mostly | ||
* static and stable content. | ||
* @returns {module:sap/base/Log.Entry} | ||
* The log entry as an object or <code>undefined</code> if no entry was created | ||
* @private | ||
*/ | ||
function log(iLevel, sMessage, vDetails, sComponent, fnSupportInfo) { | ||
if (!fnSupportInfo && !sComponent && typeof vDetails === 'function') { | ||
fnSupportInfo = vDetails; | ||
vDetails = ''; | ||
if (!fnSupportInfo && !sComponent && typeof vDetails === "function") { | ||
fnSupportInfo = vDetails; | ||
vDetails = ""; | ||
} | ||
if (!fnSupportInfo && typeof sComponent === "function") { | ||
fnSupportInfo = sComponent; | ||
sComponent = ""; | ||
} | ||
if (iLevel <= level(sComponent)) { | ||
var fNow = now(), | ||
oNow = new Date(fNow), | ||
iMicroSeconds = Math.floor((fNow - Math.floor(fNow)) * 1000), | ||
oLogEntry = { | ||
time: pad0(oNow.getHours(), 2) + ":" + pad0(oNow.getMinutes(), 2) + ":" + pad0(oNow.getSeconds(), 2) + "." + pad0(oNow.getMilliseconds(), 3) + pad0(iMicroSeconds, 3), | ||
date: pad0(oNow.getFullYear(), 4) + "-" + pad0(oNow.getMonth() + 1, 2) + "-" + pad0(oNow.getDate(), 2), | ||
timestamp: fNow, | ||
level: iLevel, | ||
message: String(sMessage || ""), | ||
details: String(vDetails || ""), | ||
component: String(sComponent || "") | ||
}; | ||
if (bLogSupportInfo && typeof fnSupportInfo === "function") { | ||
oLogEntry.supportInfo = fnSupportInfo(); | ||
} | ||
if (!fnSupportInfo && typeof sComponent === 'function') { | ||
fnSupportInfo = sComponent; | ||
sComponent = ''; | ||
if (iLogEntriesLimit) { | ||
if (aLog.length >= iLogEntriesLimit) { | ||
// Cap the amount of stored log messages by 30 percent | ||
discardLogEntries(); | ||
} | ||
aLog.push(oLogEntry); | ||
} | ||
if (iLevel <= level(sComponent)) { | ||
var fNow = now(), oNow = new Date(fNow), iMicroSeconds = Math.floor((fNow - Math.floor(fNow)) * 1000), oLogEntry = { | ||
time: pad0(oNow.getHours(), 2) + ':' + pad0(oNow.getMinutes(), 2) + ':' + pad0(oNow.getSeconds(), 2) + '.' + pad0(oNow.getMilliseconds(), 3) + pad0(iMicroSeconds, 3), | ||
date: pad0(oNow.getFullYear(), 4) + '-' + pad0(oNow.getMonth() + 1, 2) + '-' + pad0(oNow.getDate(), 2), | ||
timestamp: fNow, | ||
level: iLevel, | ||
message: String(sMessage || ''), | ||
details: String(vDetails || ''), | ||
component: String(sComponent || '') | ||
}; | ||
if (bLogSupportInfo && typeof fnSupportInfo === 'function') { | ||
oLogEntry.supportInfo = fnSupportInfo(); | ||
} | ||
if (iLogEntriesLimit) { | ||
if (aLog.length >= iLogEntriesLimit) { | ||
discardLogEntries(); | ||
} | ||
aLog.push(oLogEntry); | ||
} | ||
if (oListener) { | ||
oListener.onLogEntry(oLogEntry); | ||
} | ||
if (console) { | ||
var isDetailsError = vDetails instanceof Error, logText = oLogEntry.date + ' ' + oLogEntry.time + ' ' + oLogEntry.message + ' - ' + oLogEntry.details + ' ' + oLogEntry.component; | ||
switch (iLevel) { | ||
case Log.Level.FATAL: | ||
case Log.Level.ERROR: | ||
isDetailsError ? console.error(logText, '\n', vDetails) : console.error(logText); | ||
break; | ||
case Log.Level.WARNING: | ||
isDetailsError ? console.warn(logText, '\n', vDetails) : console.warn(logText); | ||
break; | ||
case Log.Level.INFO: | ||
if (console.info) { | ||
isDetailsError ? console.info(logText, '\n', vDetails) : console.info(logText); | ||
} else { | ||
isDetailsError ? console.log(logText, '\n', vDetails) : console.log(logText); | ||
} | ||
break; | ||
case Log.Level.DEBUG: | ||
isDetailsError ? console.debug(logText, '\n', vDetails) : console.debug(logText); | ||
break; | ||
case Log.Level.TRACE: | ||
isDetailsError ? console.trace(logText, '\n', vDetails) : console.trace(logText); | ||
break; | ||
} | ||
if (console.info && oLogEntry.supportInfo) { | ||
console.info(oLogEntry.supportInfo); | ||
} | ||
} | ||
return oLogEntry; | ||
if (oListener) { | ||
oListener.onLogEntry(oLogEntry); | ||
} | ||
/* | ||
* Console Log, also tries to log to the console, if available. | ||
* | ||
* Unfortunately, the support for console is quite different between the UI5 browsers. The most important differences are: | ||
* - in FF3.6 the console is not available, until FireBug is opened. It disappears again, when fire bug is closed. | ||
* But when the settings for a web site are stored (convenience), the console remains open | ||
* When the console is available, it supports all relevant methods | ||
* - in FF9.0, the console is always available, but method assert is only available when firebug is open | ||
* - in Webkit browsers, the console object is always available and has all required methods | ||
* - Exception: in the iOS Simulator, console.info() does not exist | ||
*/ | ||
/*eslint-disable no-console */ | ||
if (console) { | ||
// in Firefox, console might not exist or it might even disappear | ||
var isDetailsError = vDetails instanceof Error, | ||
logText = oLogEntry.date + " " + oLogEntry.time + " " + oLogEntry.message + " - " + oLogEntry.details + " " + oLogEntry.component; | ||
switch (iLevel) { | ||
case Log.Level.FATAL: | ||
case Log.Level.ERROR: | ||
isDetailsError ? console.error(logText, "\n", vDetails) : console.error(logText); | ||
break; | ||
case Log.Level.WARNING: | ||
isDetailsError ? console.warn(logText, "\n", vDetails) : console.warn(logText); | ||
break; | ||
case Log.Level.INFO: | ||
if (console.info) { | ||
// info not available in iOS simulator | ||
isDetailsError ? console.info(logText, "\n", vDetails) : console.info(logText); | ||
} else { | ||
isDetailsError ? console.log(logText, "\n", vDetails) : console.log(logText); | ||
} | ||
break; | ||
case Log.Level.DEBUG: | ||
isDetailsError ? console.debug(logText, "\n", vDetails) : console.debug(logText); | ||
break; | ||
case Log.Level.TRACE: | ||
isDetailsError ? console.trace(logText, "\n", vDetails) : console.trace(logText); | ||
break; | ||
} | ||
if (console.info && oLogEntry.supportInfo) { | ||
console.info(oLogEntry.supportInfo); | ||
} | ||
} | ||
/*eslint-enable no-console */ | ||
return oLogEntry; | ||
} | ||
} | ||
/** | ||
* Returns the logged entries recorded so far as an array. | ||
* | ||
* Log entries are plain JavaScript objects with the following properties | ||
* <ul> | ||
* <li>timestamp {number} point in time when the entry was created | ||
* <li>level {module:sap/base/Log.Level} LogLevel level of the entry | ||
* <li>message {string} message text of the entry | ||
* </ul> | ||
* The default amount of stored log entries is limited to 3000 entries. | ||
* @returns {Array<module:sap/base/Log.Entry>} an array containing the recorded log entries | ||
* @public | ||
* @static | ||
*/ | ||
Log.getLogEntries = function () { | ||
return aLog.slice(); | ||
return aLog.slice(); | ||
}; | ||
/** | ||
* Returns the maximum amount of stored log entries. | ||
* | ||
* @returns {int|Infinity} The maximum amount of stored log entries or Infinity if no limit is set | ||
* @private | ||
* @ui5-restricted | ||
*/ | ||
Log.getLogEntriesLimit = function () { | ||
return iLogEntriesLimit; | ||
return iLogEntriesLimit; | ||
}; | ||
/** | ||
* Sets the limit of stored log entries | ||
* | ||
* If the new limit is lower than the current limit, the overlap of old log entries will be discarded. | ||
* If the limit is reached the amount of stored messages will be reduced by 30 percent. | ||
* | ||
* @param {int|Infinity} iLimit The maximum amount of stored log entries or Infinity for unlimited entries | ||
* @private | ||
* @ui5-restricted | ||
*/ | ||
Log.setLogEntriesLimit = function (iLimit) { | ||
if (iLimit < 0) { | ||
throw new Error('The log entries limit needs to be greater than or equal to 0!'); | ||
} | ||
iLogEntriesLimit = iLimit; | ||
if (aLog.length >= iLogEntriesLimit) { | ||
discardLogEntries(); | ||
} | ||
if (iLimit < 0) { | ||
throw new Error("The log entries limit needs to be greater than or equal to 0!"); | ||
} | ||
iLogEntriesLimit = iLimit; | ||
if (aLog.length >= iLogEntriesLimit) { | ||
discardLogEntries(); | ||
} | ||
}; | ||
/** | ||
* @typedef {object} module:sap/base/Log.Entry | ||
* @property {float} timestamp The number of milliseconds since the epoch | ||
* @property {string} time Time string in format HH:mm:ss:mmmnnn | ||
* @property {string} date Date string in format yyyy-MM-dd | ||
* @property {module:sap/base/Log.Level} level The level of the log entry, see {@link module:sap/base/Log.Level} | ||
* @property {string} message The message of the log entry | ||
* @property {string} details The detailed information of the log entry | ||
* @property {string} component The component that creates the log entry | ||
* @property {function():any} [supportInfo] Callback that returns an additional support object to be | ||
* logged in support mode. | ||
* @public | ||
*/ | ||
/** | ||
* Interface to be implemented by a log listener. | ||
* | ||
* Typically, a listener will at least implement the {@link #.onLogEntry} method, | ||
* but in general, all methods are optional. | ||
* | ||
* @interface | ||
* @name module:sap/base/Log.Listener | ||
* @public | ||
*/ | ||
/** | ||
* The function that is called when a new log entry is created | ||
* | ||
* @param {module:sap/base/Log.Entry} oLogEntry The newly created log entry | ||
* @name module:sap/base/Log.Listener.onLogEntry? | ||
* @function | ||
* @public | ||
*/ | ||
/** | ||
* The function that is called once the Listener is attached | ||
* | ||
* @param {module:sap/base/Log} oLog The Log instance where the listener is attached | ||
* @name module:sap/base/Log.Listener.onAttachToLog? | ||
* @function | ||
* @public | ||
*/ | ||
/** | ||
* The function that is called once the Listener is detached | ||
* | ||
* @param {module:sap/base/Log} oLog The Log instance where the listener is detached | ||
* @name module:sap/base/Log.Listener.onDetachFromLog? | ||
* @function | ||
* @public | ||
*/ | ||
/** | ||
* The function that is called once log entries are discarded due to the exceed of total log entry amount | ||
* | ||
* @param {Array<module:sap/base/Log.Entry>} aDiscardedEntries The discarded log entries | ||
* @name module:sap/base/Log.Listener.onDiscardLogEntries? | ||
* @function | ||
* @public | ||
*/ | ||
/** | ||
* Allows to add a new listener that will be notified for new log entries. | ||
* | ||
* The given object must provide method <code>onLogEntry</code> and can also be informed | ||
* about <code>onDetachFromLog</code>, <code>onAttachToLog</code> and <code>onDiscardLogEntries</code>. | ||
* @param {module:sap/base/Log.Listener} oListener The new listener object that should be informed | ||
* @public | ||
* @static | ||
*/ | ||
Log.addLogListener = function (oListener) { | ||
getLogEntryListenerInstance().attach(this, oListener); | ||
getLogEntryListenerInstance().attach(this, oListener); | ||
}; | ||
/** | ||
* Allows to remove a registered LogListener. | ||
* @param {module:sap/base/Log.Listener} oListener The listener object that should be removed | ||
* @public | ||
* @static | ||
*/ | ||
Log.removeLogListener = function (oListener) { | ||
getLogEntryListenerInstance().detach(this, oListener); | ||
getLogEntryListenerInstance().detach(this, oListener); | ||
}; | ||
/** | ||
* The logger comes with a subset of the API of the <code>sap/base/Log</code> module: | ||
* <ul> | ||
* <li><code>#fatal</code> - see: {@link module:sap/base/Log.fatal} | ||
* <li><code>#error</code> - see: {@link module:sap/base/Log.error} | ||
* <li><code>#warning</code> - see: {@link module:sap/base/Log.warning} | ||
* <li><code>#info</code> - see: {@link module:sap/base/Log.info} | ||
* <li><code>#debug</code> - see: {@link module:sap/base/Log.debug} | ||
* <li><code>#trace</code> - see: {@link module:sap/base/Log.trace} | ||
* <li><code>#setLevel</code> - see: {@link module:sap/base/Log.setLevel} | ||
* <li><code>#getLevel</code> - see: {@link module:sap/base/Log.getLevel} | ||
* <li><code>#isLoggable</code> - see: {@link module:sap/base/Log.isLoggable} | ||
* </ul> | ||
* @interface | ||
* @borrows module:sap/base/Log.fatal as #fatal | ||
* @borrows module:sap/base/Log.error as #error | ||
* @borrows module:sap/base/Log.warning as #warning | ||
* @borrows module:sap/base/Log.info as #info | ||
* @borrows module:sap/base/Log.debug as #debug | ||
* @borrows module:sap/base/Log.trace as #trace | ||
* @borrows module:sap/base/Log.setLevel as #setLevel | ||
* @borrows module:sap/base/Log.getLevel as #getLevel | ||
* @borrows module:sap/base/Log.isLoggable as #isLoggable | ||
* @name module:sap/base/Log.Logger | ||
* @public | ||
*/ | ||
function Logger(sComponent) { | ||
this.fatal = function (msg, detail, comp, support) { | ||
Log.fatal(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.error = function (msg, detail, comp, support) { | ||
Log.error(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.warning = function (msg, detail, comp, support) { | ||
Log.warning(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.info = function (msg, detail, comp, support) { | ||
Log.info(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.debug = function (msg, detail, comp, support) { | ||
Log.debug(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.trace = function (msg, detail, comp, support) { | ||
Log.trace(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.setLevel = function (level, comp) { | ||
Log.setLevel(level, comp || sComponent); | ||
return this; | ||
}; | ||
this.getLevel = function (comp) { | ||
return Log.getLevel(comp || sComponent); | ||
}; | ||
this.isLoggable = function (level, comp) { | ||
return Log.isLoggable(level, comp || sComponent); | ||
}; | ||
this.fatal = function (msg, detail, comp, support) { | ||
Log.fatal(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.error = function (msg, detail, comp, support) { | ||
Log.error(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.warning = function (msg, detail, comp, support) { | ||
Log.warning(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.info = function (msg, detail, comp, support) { | ||
Log.info(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.debug = function (msg, detail, comp, support) { | ||
Log.debug(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.trace = function (msg, detail, comp, support) { | ||
Log.trace(msg, detail, comp || sComponent, support); | ||
return this; | ||
}; | ||
this.setLevel = function (level, comp) { | ||
Log.setLevel(level, comp || sComponent); | ||
return this; | ||
}; | ||
this.getLevel = function (comp) { | ||
return Log.getLevel(comp || sComponent); | ||
}; | ||
this.isLoggable = function (level, comp) { | ||
return Log.isLoggable(level, comp || sComponent); | ||
}; | ||
} | ||
/** | ||
* Returns a dedicated logger for a component. | ||
* | ||
* The logger comes with the same API as the <code>sap/base/Log</code> module: | ||
* <ul> | ||
* <li><code>#fatal</code> - see: {@link module:sap/base/Log.fatal} | ||
* <li><code>#error</code> - see: {@link module:sap/base/Log.error} | ||
* <li><code>#warning</code> - see: {@link module:sap/base/Log.warning} | ||
* <li><code>#info</code> - see: {@link module:sap/base/Log.info} | ||
* <li><code>#debug</code> - see: {@link module:sap/base/Log.debug} | ||
* <li><code>#trace</code> - see: {@link module:sap/base/Log.trace} | ||
* <li><code>#setLevel</code> - see: {@link module:sap/base/Log.setLevel} | ||
* <li><code>#getLevel</code> - see: {@link module:sap/base/Log.getLevel} | ||
* <li><code>#isLoggable</code> - see: {@link module:sap/base/Log.isLoggable} | ||
* </ul> | ||
* | ||
* @param {string} sComponent Name of the component which should be logged | ||
* @param {module:sap/base/Log.Level} [iDefaultLogLevel] The default log level | ||
* @return {module:sap/base/Log.Logger} A logger with a specified component | ||
* @public | ||
* @static | ||
*/ | ||
Log.getLogger = function (sComponent, iDefaultLogLevel) { | ||
if (!isNaN(iDefaultLogLevel) && mMaxLevel[sComponent] == null) { | ||
mMaxLevel[sComponent] = iDefaultLogLevel; | ||
} | ||
return new Logger(sComponent); | ||
if (!isNaN(iDefaultLogLevel) && mMaxLevel[sComponent] == null) { | ||
mMaxLevel[sComponent] = iDefaultLogLevel; | ||
} | ||
return new Logger(sComponent); | ||
}; | ||
// set LogLevel | ||
const sLogLevel = BaseConfig.get({ | ||
name: "sapUiLogLevel", | ||
type: BaseConfig.Type.String, | ||
defaultValue: undefined, | ||
external: true | ||
}); | ||
if (sLogLevel) { | ||
Log.setLevel(Log.Level[sLogLevel.toUpperCase()] || parseInt(sLogLevel)); | ||
} else if (!globalThis["sap-ui-optimized"]) { | ||
Log.setLevel(Log.Level.DEBUG); | ||
} | ||
export default Log; |
@@ -1,14 +0,40 @@ | ||
import toHex from '../strings/toHex.js'; | ||
/*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
import toHex from "../strings/toHex.js"; | ||
/** | ||
* RegExp and escape function for CSS escaping | ||
*/ | ||
// eslint-disable-next-line no-control-regex -- special characters are really needed here! | ||
var rCSS = /[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xff\u2028\u2029][0-9A-Fa-f]?/g; | ||
var fnCSS = function (sChar) { | ||
var iChar = sChar.charCodeAt(0); | ||
if (sChar.length === 1) { | ||
return '\\' + toHex(iChar); | ||
} else { | ||
return '\\' + toHex(iChar) + ' ' + sChar.substr(1); | ||
} | ||
var iChar = sChar.charCodeAt(0); | ||
if (sChar.length === 1) { | ||
return "\\" + toHex(iChar); | ||
} else { | ||
return "\\" + toHex(iChar) + " " + sChar.substr(1); | ||
} | ||
}; | ||
/* | ||
* Encoding according to the Secure Programming Guide | ||
* <SAPWIKI>/wiki/display/NWCUIAMSIM/XSS+Secure+Programming+Guide | ||
*/ | ||
/** | ||
* Encode the string for inclusion into CSS string literals or identifiers. | ||
* | ||
* @function | ||
* @since 1.58 | ||
* @alias module:sap/base/security/encodeCSS | ||
* @param {string} sString The string to be escaped | ||
* @returns {string} The encoded string | ||
* @SecValidate {0|return|XSS} validates the given string for a CSS context | ||
* @public | ||
*/ | ||
var fnEncodeCSS = function (sString) { | ||
return sString.replace(rCSS, fnCSS); | ||
return sString.replace(rCSS, fnCSS); | ||
}; | ||
export default fnEncodeCSS; |
@@ -1,23 +0,53 @@ | ||
import toHex from '../strings/toHex.js'; | ||
var rHtml = /[\x00-\x2b\x2f\x3a-\x40\x5b-\x5e\x60\x7b-\xff\u2028\u2029]/g, rHtmlReplace = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/, mHtmlLookup = { | ||
'<': '<', | ||
'>': '>', | ||
'&': '&', | ||
'"': '"' | ||
}; | ||
/*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
import toHex from "../strings/toHex.js"; | ||
/* eslint-disable no-control-regex -- special characters are really needed here! */ | ||
/** | ||
* RegExp and escape function for HTML escaping | ||
*/ | ||
var rHtml = /[\x00-\x2b\x2f\x3a-\x40\x5b-\x5e\x60\x7b-\xff\u2028\u2029]/g, | ||
rHtmlReplace = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/, | ||
mHtmlLookup = { | ||
"<": "<", | ||
">": ">", | ||
"&": "&", | ||
"\"": """ | ||
}; | ||
/* eslint-enable no-control-regex */ | ||
var fnHtml = function (sChar) { | ||
var sEncoded = mHtmlLookup[sChar]; | ||
if (!sEncoded) { | ||
if (rHtmlReplace.test(sChar)) { | ||
sEncoded = '�'; | ||
} else { | ||
sEncoded = '&#x' + toHex(sChar.charCodeAt(0)) + ';'; | ||
} | ||
mHtmlLookup[sChar] = sEncoded; | ||
var sEncoded = mHtmlLookup[sChar]; | ||
if (!sEncoded) { | ||
if (rHtmlReplace.test(sChar)) { | ||
sEncoded = "�"; | ||
} else { | ||
sEncoded = "&#x" + toHex(sChar.charCodeAt(0)) + ";"; | ||
} | ||
return sEncoded; | ||
mHtmlLookup[sChar] = sEncoded; | ||
} | ||
return sEncoded; | ||
}; | ||
/* | ||
* Encoding according to the Secure Programming Guide | ||
* <SAPWIKI>/wiki/display/NWCUIAMSIM/XSS+Secure+Programming+Guide | ||
*/ | ||
/** | ||
* Encode the string for inclusion into XML content/attribute. | ||
* | ||
* @function | ||
* @since 1.58 | ||
* @alias module:sap/base/security/encodeXML | ||
* @param {string} sString The string to be escaped | ||
* @returns {string} The encoded string | ||
* @SecValidate {0|return|XSS} validates the given string for XML contexts | ||
* @public | ||
*/ | ||
var fnEncodeXML = function (sString) { | ||
return sString.replace(rHtml, fnHtml); | ||
return sString.replace(rHtml, fnHtml); | ||
}; | ||
export default fnEncodeXML; |
@@ -1,16 +0,38 @@ | ||
import assert from '../assert.js'; | ||
import URLListValidator from './URLListValidator.js'; | ||
import '../../ui/thirdparty/caja-html-sanitizer.js'; | ||
/*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
/* | ||
* IMPORTANT: This is a private module, its API must not be used and is subject to change. | ||
* Code other than the OpenUI5 libraries must not introduce dependencies to this module. | ||
*/ | ||
import assert from "../assert.js"; | ||
import URLListValidator from "./URLListValidator.js"; | ||
import "../../ui/thirdparty/caja-html-sanitizer.js"; | ||
/** | ||
* Strips unsafe tags and attributes from HTML. | ||
* | ||
* @function | ||
* @since 1.58 | ||
* @alias module:sap/base/security/sanitizeHTML | ||
* @param {string} sHTML the HTML to be sanitized. | ||
* @param {object} [mOptions={}] options for the sanitizer | ||
* @return {string} sanitized HTML | ||
* @private | ||
*/ | ||
var fnSanitizeHTML = function (sHTML, mOptions) { | ||
assert(window.html && window.html.sanitize, 'Sanitizer should have been loaded'); | ||
mOptions = mOptions || { | ||
uriRewriter: function (sUrl) { | ||
if (URLListValidator.validate(sUrl)) { | ||
return sUrl; | ||
} | ||
} | ||
}; | ||
var oTagPolicy = mOptions.tagPolicy || window.html.makeTagPolicy(mOptions.uriRewriter, mOptions.tokenPolicy); | ||
return window.html.sanitizeWithPolicy(sHTML, oTagPolicy); | ||
assert(window.html && window.html.sanitize, "Sanitizer should have been loaded"); | ||
mOptions = mOptions || { | ||
uriRewriter: function (sUrl) { | ||
// by default, we use the URLListValidator to check the URLs | ||
if (URLListValidator.validate(sUrl)) { | ||
return sUrl; | ||
} | ||
} | ||
}; | ||
var oTagPolicy = mOptions.tagPolicy || window.html.makeTagPolicy(mOptions.uriRewriter, mOptions.tokenPolicy); | ||
return window.html.sanitizeWithPolicy(sHTML, oTagPolicy); | ||
}; | ||
export default fnSanitizeHTML; |
@@ -0,1 +1,8 @@ | ||
// validation regexes | ||
/*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
var rBasicUrl = /^(?:([^:\/?#]+):)?((?:[\/\\]{2,}((?:\[[^\]]+\]|[^\/?#:]+))(?::([0-9]+))?)?([^?#]*))(?:\?([^#]*))?(?:#(.*))?$/; | ||
@@ -12,7 +19,40 @@ var rCheckPath = /^([a-z0-9-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*$/i; | ||
var rSpecialSchemeURLs = /^((?:ftp|https?|wss?):)([\s\S]+)$/; | ||
/* eslint-disable no-control-regex */ | ||
var rCheckWhitespaces = /[\u0009\u000A\u000D]/; | ||
/** | ||
* Registry to manage allowed URLs and validate against them. | ||
* | ||
* @namespace | ||
* @since 1.85 | ||
* @alias module:sap/base/security/URLListValidator | ||
* @public | ||
*/ | ||
var oURLListValidator = {}; | ||
/** | ||
* Creates a new URLListValidator.Entry object | ||
* | ||
* @param {string} [protocol] The protocol of the URL, can be falsy to allow all protocols for an entry e.g. "", "http", "mailto" | ||
* @param {string} [host] The host of the URL, can be falsy to allow all hosts. A wildcard asterisk can be set at the beginning, e.g. "examples.com", "*.example.com" | ||
* @param {string} [port] The port of the URL, can be falsy to allow all ports, e.g. "", "8080" | ||
* @param {string} [path] the path of the URL, path of the url, can be falsy to allow all paths. A wildcard asterisk can be set at the end, e.g. "/my-example*", "/my-news" | ||
* @returns {module:sap/base/security/URLListValidator.Entry|object} | ||
* @private | ||
*/ | ||
oURLListValidator._createEntry = function (protocol, host, port, path) { | ||
return new URLListValidatorEntry(protocol, host, port, path); | ||
}; | ||
/** | ||
* Entry object of the URLListValidator. | ||
* | ||
* @public | ||
* @typedef {object} module:sap/base/security/URLListValidator.Entry | ||
* @property {string} [protocol] The protocol of the URL, can be falsy to allow all protocols for an entry e.g. "", "http", "mailto" | ||
* @property {string} [host] The host of the URL, can be falsy to allow all hosts. A wildcard asterisk can be set at the beginning, e.g. "examples.com", "*.example.com" | ||
* @property {string} [port] The port of the URL, can be falsy to allow all ports, e.g. "", "8080" | ||
* @property {string} [path] the path of the URL, path of the url, can be falsy to allow all paths. A wildcard asterisk can be set at the end, e.g. "/my-example*", "/my-news" | ||
*/ | ||
function URLListValidatorEntry(protocol, host, port, path) { | ||
@@ -38,6 +78,35 @@ Object.defineProperties(this, { | ||
} | ||
/** | ||
* The internally managed allowed entries. | ||
* @private | ||
*/ | ||
var aAllowedEntries = []; | ||
/** | ||
* Clears the allowed entries for URL validation. | ||
* This makes all URLs allowed. | ||
* | ||
* @public | ||
*/ | ||
oURLListValidator.clear = function () { | ||
aAllowedEntries = []; | ||
}; | ||
/** | ||
* Adds an allowed entry. | ||
* | ||
* Note: | ||
* Adding the first entry to the list of allowed entries will disallow all URLs but the ones matching the newly added entry. | ||
* | ||
* <b>Note</b>: | ||
* It is strongly recommended to set a path only in combination with an origin (never set a path alone). | ||
* There's almost no case where checking only the path of a URL would allow to ensure its validity. | ||
* | ||
* @param {string} [protocol] The protocol of the URL, can be falsy to allow all protocols for an entry e.g. "", "http", "mailto" | ||
* @param {string} [host] The host of the URL, can be falsy to allow all hosts. A wildcard asterisk can be set at the beginning, e.g. "examples.com", "*.example.com" | ||
* @param {string} [port] The port of the URL, can be falsy to allow all ports, e.g. "", "8080" | ||
* @param {string} [path] the path of the URL, path of the url, can be falsy to allow all paths. A wildcard asterisk can be set at the end, e.g. "/my-example*", "/my-news" | ||
* @public | ||
*/ | ||
oURLListValidator.add = function (protocol, host, port, path) { | ||
@@ -47,9 +116,150 @@ var oEntry = this._createEntry(protocol, host, port, path); | ||
}; | ||
/** | ||
* Deletes an entry from the allowed entries. | ||
* | ||
* Note: | ||
* Deleting the last entry from the list of allowed entries will allow all URLs. | ||
* | ||
* @param {module:sap/base/security/URLListValidator.Entry} oEntry The entry to be deleted | ||
* @private | ||
*/ | ||
oURLListValidator._delete = function (oEntry) { | ||
aAllowedEntries.splice(aAllowedEntries.indexOf(oEntry), 1); | ||
}; | ||
/** | ||
* Gets the list of allowed entries. | ||
* | ||
* @returns {module:sap/base/security/URLListValidator.Entry[]} The allowed entries | ||
* @public | ||
*/ | ||
oURLListValidator.entries = function () { | ||
return aAllowedEntries.slice(); | ||
}; | ||
/** | ||
* Validates a URL. Check if it's not a script or other security issue. | ||
* | ||
* <b>Note</b>: | ||
* It is strongly recommended to validate only absolute URLs. There's almost no case | ||
* where checking only the path of a URL would allow to ensure its validity. | ||
* For compatibility reasons, this API cannot automatically resolve URLs relative to | ||
* <code>document.baseURI</code>, but callers should do so. In that case, and when the | ||
* allow list is not empty, an entry for the origin of <code>document.baseURI</code> | ||
* must be added to the allow list. | ||
* | ||
* <h3>Details</h3> | ||
* Splits the given URL into components and checks for allowed characters according to RFC 3986: | ||
* | ||
* <pre> | ||
* authority = [ userinfo "@" ] host [ ":" port ] | ||
* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) | ||
* host = IP-literal / IPv4address / reg-name | ||
* | ||
* IP-literal = "[" ( IPv6address / IPvFuture ) "]" | ||
* IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) | ||
* IPv6address = 6( h16 ":" ) ls32 | ||
* / "::" 5( h16 ":" ) ls32 | ||
* / [ h16 ] "::" 4( h16 ":" ) ls32 | ||
* / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 | ||
* / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 | ||
* / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 | ||
* / [ *4( h16 ":" ) h16 ] "::" ls32 | ||
* / [ *5( h16 ":" ) h16 ] "::" h16 | ||
* / [ *6( h16 ":" ) h16 ] "::" | ||
* ls32 = ( h16 ":" h16 ) / IPv4address | ||
* ; least-significant 32 bits of address | ||
* h16 = 1*4HEXDIG | ||
* ; 16 bits of address represented in hexadecimal | ||
* | ||
* IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet | ||
* dec-octet = DIGIT ; 0-9 | ||
* / %x31-39 DIGIT ; 10-99 | ||
* / "1" 2DIGIT ; 100-199 | ||
* / "2" %x30-34 DIGIT ; 200-249 | ||
* / "25" %x30-35 ; 250-255 | ||
* | ||
* reg-name = *( unreserved / pct-encoded / sub-delims ) | ||
* | ||
* pct-encoded = "%" HEXDIG HEXDIG | ||
* reserved = gen-delims / sub-delims | ||
* gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" | ||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" | ||
* / "*" / "+" / "," / ";" / "=" | ||
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" | ||
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@" | ||
* | ||
* path = path-abempty ; begins with "/" or is empty | ||
* / path-absolute ; begins with "/" but not "//" | ||
* / path-noscheme ; begins with a non-colon segment | ||
* / path-rootless ; begins with a segment | ||
* / path-empty ; zero characters | ||
* | ||
* path-abempty = *( "/" segment ) | ||
* path-absolute = "/" [ segment-nz *( "/" segment ) ] | ||
* path-noscheme = segment-nz-nc *( "/" segment ) | ||
* path-rootless = segment-nz *( "/" segment ) | ||
* path-empty = 0<pchar> | ||
* segment = *pchar | ||
* segment-nz = 1*pchar | ||
* segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) | ||
* ; non-zero-length segment without any colon ":" | ||
* | ||
* query = *( pchar / "/" / "?" ) | ||
* | ||
* fragment = *( pchar / "/" / "?" ) | ||
* </pre> | ||
* | ||
* For the hostname component, we are checking for valid DNS hostnames according to RFC 952 / RFC 1123: | ||
* | ||
* <pre> | ||
* hname = name *("." name) | ||
* name = let-or-digit ( *( let-or-digit-or-hyphen ) let-or-digit ) | ||
* </pre> | ||
* | ||
* | ||
* When the URI uses the protocol 'mailto:', the address part is additionally checked | ||
* against the most commonly used parts of RFC 6068: | ||
* | ||
* <pre> | ||
* mailtoURI = "mailto:" [ to ] [ hfields ] | ||
* to = addr-spec *("," addr-spec ) | ||
* hfields = "?" hfield *( "&" hfield ) | ||
* hfield = hfname "=" hfvalue | ||
* hfname = *qchar | ||
* hfvalue = *qchar | ||
* addr-spec = local-part "@" domain | ||
* local-part = dot-atom-text // not accepted: quoted-string | ||
* domain = dot-atom-text // not accepted: "[" *dtext-no-obs "]" | ||
* dtext-no-obs = %d33-90 / ; Printable US-ASCII | ||
* %d94-126 ; characters not including | ||
* ; "[", "]", or "\" | ||
* qchar = unreserved / pct-encoded / some-delims | ||
* some-delims = "!" / "$" / "'" / "(" / ")" / "*" | ||
* / "+" / "," / ";" / ":" / "@" | ||
* | ||
* Note: | ||
* A number of characters that can appear in <addr-spec> MUST be | ||
* percent-encoded. These are the characters that cannot appear in | ||
* a URI according to [STD66] as well as "%" (because it is used for | ||
* percent-encoding) and all the characters in gen-delims except "@" | ||
* and ":" (i.e., "/", "?", "#", "[", and "]"). Of the characters | ||
* in sub-delims, at least the following also have to be percent- | ||
* encoded: "&", ";", and "=". Care has to be taken both when | ||
* encoding as well as when decoding to make sure these operations | ||
* are applied only once. | ||
* | ||
* </pre> | ||
* | ||
* When a list of allowed entries has been configured using {@link #add}, | ||
* any URL that passes the syntactic checks above, additionally will be tested against | ||
* the content of this list. | ||
* | ||
* @param {string} sUrl URL to be validated | ||
* @return {boolean} true if valid, false if not valid | ||
* @public | ||
*/ | ||
oURLListValidator.validate = function (sUrl) { | ||
// Test for not allowed whitespaces | ||
if (typeof sUrl === "string") { | ||
@@ -60,4 +270,9 @@ if (rCheckWhitespaces.test(sUrl)) { | ||
} | ||
// for 'special' URLs without a given base URL, the whatwg spec allows any number of slashes. | ||
// As the rBasicUrl regular expression cannot handle 'special' URLs, the URL is modified upfront, | ||
// if it wouldn't be recognized by the regex. | ||
// See https://url.spec.whatwg.org/#scheme-state (case 2.6.) | ||
var result = rSpecialSchemeURLs.exec(sUrl); | ||
if (result && !(/^[\/\\]{2}/).test(result[2])) { | ||
if (result && !/^[\/\\]{2}/.test(result[2])) { | ||
sUrl = result[1] + "//" + result[2]; | ||
@@ -69,7 +284,16 @@ } | ||
} | ||
var sProtocol = result[1], sBody = result[2], sHost = result[3], sPort = result[4], sPath = result[5], sQuery = result[6], sHash = result[7]; | ||
var sProtocol = result[1], | ||
sBody = result[2], | ||
sHost = result[3], | ||
sPort = result[4], | ||
sPath = result[5], | ||
sQuery = result[6], | ||
sHash = result[7]; | ||
// protocol | ||
if (sProtocol) { | ||
sProtocol = sProtocol.toUpperCase(); | ||
if (aAllowedEntries.length <= 0) { | ||
if (!(/^(https?|ftp)/i).test(sProtocol)) { | ||
// no allowed entries -> check for default protocols | ||
if (!/^(https?|ftp)/i.test(sProtocol)) { | ||
return false; | ||
@@ -79,5 +303,8 @@ } | ||
} | ||
// Host -> validity check for IP address or hostname | ||
if (sHost) { | ||
if (rCheckIPv4.test(sHost)) { | ||
if (!rCheckValidIPv4.test(sHost)) { | ||
//invalid ipv4 address | ||
return false; | ||
@@ -87,5 +314,7 @@ } | ||
if (!rCheckValidIPv6.test(sHost)) { | ||
//invalid ipv6 address | ||
return false; | ||
} | ||
} else if (!rCheckHostName.test(sHost)) { | ||
// invalid host name | ||
return false; | ||
@@ -95,2 +324,4 @@ } | ||
} | ||
// Path -> split for "/" and check if forbidden characters exist | ||
if (sPath) { | ||
@@ -101,2 +332,3 @@ if (sProtocol === "MAILTO") { | ||
if (!rCheckMail.test(aAddresses[i])) { | ||
// forbidden character found | ||
return false; | ||
@@ -109,2 +341,3 @@ } | ||
if (!rCheckPath.test(aComponents[i])) { | ||
// forbidden character found | ||
return false; | ||
@@ -115,12 +348,20 @@ } | ||
} | ||
// query | ||
if (sQuery) { | ||
if (!rCheckQuery.test(sQuery)) { | ||
// forbidden character found | ||
return false; | ||
} | ||
} | ||
// hash | ||
if (sHash) { | ||
if (!rCheckFragment.test(sHash)) { | ||
// forbidden character found | ||
return false; | ||
} | ||
} | ||
//filter allowed entries | ||
if (aAllowedEntries.length > 0) { | ||
@@ -130,4 +371,6 @@ var bFound = false; | ||
if (!sProtocol || !aAllowedEntries[i].protocol || sProtocol == aAllowedEntries[i].protocol) { | ||
// protocol OK | ||
var bOk = false; | ||
if (sHost && aAllowedEntries[i].host && (/^\*/).test(aAllowedEntries[i].host)) { | ||
if (sHost && aAllowedEntries[i].host && /^\*/.test(aAllowedEntries[i].host)) { | ||
// check for wildcard search at begin | ||
if (!aAllowedEntries[i]._hostRegexp) { | ||
@@ -145,4 +388,7 @@ var sHostEscaped = aAllowedEntries[i].host.slice(1).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); | ||
if (bOk) { | ||
// host OK | ||
if (!sHost && !sPort || !aAllowedEntries[i].port || sPort == aAllowedEntries[i].port) { | ||
if (aAllowedEntries[i].path && (/\*$/).test(aAllowedEntries[i].path)) { | ||
// port OK | ||
if (aAllowedEntries[i].path && /\*$/.test(aAllowedEntries[i].path)) { | ||
// check for wildcard search at end | ||
if (!aAllowedEntries[i]._pathRegexp) { | ||
@@ -157,2 +403,3 @@ var sPathEscaped = aAllowedEntries[i].path.slice(0, -1).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); | ||
} else if (!aAllowedEntries[i].path || sPath == aAllowedEntries[i].path) { | ||
// path OK | ||
bFound = true; | ||
@@ -173,2 +420,2 @@ } | ||
}; | ||
export default oURLListValidator; | ||
export default oURLListValidator; |
@@ -0,8 +1,33 @@ | ||
/** | ||
* Create hex string and pad to length with zeros. | ||
* @example | ||
* sap.ui.require(["sap/base/strings/toHex"], function(toHex){ | ||
* toHex(10, 2); // "0a" | ||
* toHex(16, 2); // "10" | ||
* }); | ||
* | ||
* @function | ||
* @since 1.58 | ||
* @private | ||
* @alias module:sap/base/strings/toHex | ||
* @param {int} iChar UTF-16 character code | ||
* @param {int} [iLength=0] number of padded zeros | ||
* @returns {string} padded hex representation of the given character code | ||
*/ /*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
/* | ||
* IMPORTANT: This is a private module, its API must not be used and is subject to change. | ||
* Code other than the OpenUI5 libraries must not introduce dependencies to this module. | ||
*/ | ||
var fnToHex = function (iChar, iLength) { | ||
var sHex = iChar.toString(16); | ||
if (iLength) { | ||
sHex = sHex.padStart(iLength, "0"); | ||
sHex = sHex.padStart(iLength, '0'); | ||
} | ||
return sHex; | ||
}; | ||
export default fnToHex; | ||
export default fnToHex; |
@@ -1,2 +0,23 @@ | ||
var fnNow = !(typeof window != "undefined" && window.performance && performance.now && performance.timing) ? Date.now : (function () { | ||
// @evo-todo window.performance does not exist on node.js, but there is a module performance-now. Maybe use it | ||
/** | ||
* Returns a high resolution timestamp in microseconds if supported by the environment, otherwise in milliseconds. | ||
* The timestamp is based on 01/01/1970 00:00:00 (UNIX epoch) as float with microsecond precision or | ||
* with millisecond precision, if high resolution timestamps are not available. | ||
* The fractional part of the timestamp represents fractions of a millisecond. | ||
* Converting to a <code>Date</code> is possible by using <code>require(["sap/base/util/now"], function(now){new Date(now());}</code> | ||
* | ||
* @function | ||
* @since 1.58 | ||
* @public | ||
* @alias module:sap/base/util/now | ||
* @returns {float} timestamp in microseconds if supported by the environment otherwise in milliseconds | ||
*/ /*! | ||
* OpenUI5 | ||
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company. | ||
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt. | ||
*/ | ||
/*global performance */ | ||
var fnNow = !(typeof window != "undefined" && window.performance && performance.now && performance.timing) ? Date.now : function () { | ||
var iNavigationStart = performance.timing.navigationStart; | ||
@@ -6,3 +27,3 @@ return function perfnow() { | ||
}; | ||
})(); | ||
export default fnNow; | ||
}(); | ||
export default fnNow; |
@@ -1,6 +0,7 @@ | ||
"use strict"; | ||
class StaticArea extends HTMLElement { | ||
} | ||
if (!customElements.get("ui5-static-area")) { | ||
customElements.define("ui5-static-area", class extends HTMLElement { | ||
}); | ||
customElements.define("ui5-static-area", StaticArea); | ||
} | ||
export default StaticArea; | ||
//# sourceMappingURL=StaticArea.js.map |
import "./StaticArea.js"; | ||
import type UI5Element from "./UI5Element.js"; | ||
/** | ||
* | ||
* @class | ||
* @author SAP SE | ||
* @private | ||
@@ -14,3 +12,3 @@ */ | ||
/** | ||
* @param {UI5Element} ownerElement the UI5Element instance that owns this static area item | ||
* @param ownerElement the UI5Element instance that owns this static area item | ||
*/ | ||
@@ -22,2 +20,3 @@ setOwnerElement(ownerElement: UI5Element): void; | ||
update(): void; | ||
updateAdditionalProperties(): void; | ||
/** | ||
@@ -31,4 +30,4 @@ * Sets the correct content density based on the owner element's state | ||
/** | ||
* Returns reference to the DOM element where the current fragment is added. | ||
* @protected | ||
* Returns reference to the DOM element where the current fragment is added. | ||
*/ | ||
@@ -35,0 +34,0 @@ getDomRef(): Promise<ShadowRoot | null>; |
@@ -10,5 +10,3 @@ import "./StaticArea.js"; | ||
/** | ||
* | ||
* @class | ||
* @author SAP SE | ||
* @private | ||
@@ -23,3 +21,3 @@ */ | ||
/** | ||
* @param {UI5Element} ownerElement the UI5Element instance that owns this static area item | ||
* @param ownerElement the UI5Element instance that owns this static area item | ||
*/ | ||
@@ -38,8 +36,11 @@ setOwnerElement(ownerElement) { | ||
if (this._rendered) { | ||
this._updateAdditionalAttrs(); | ||
this._updateContentDensity(); | ||
this._updateDirection(); | ||
this.updateAdditionalProperties(); | ||
updateShadowRoot(this.ownerElement, true); | ||
} | ||
} | ||
updateAdditionalProperties() { | ||
this._updateAdditionalAttrs(); | ||
this._updateContentDensity(); | ||
this._updateDirection(); | ||
} | ||
/** | ||
@@ -62,3 +63,3 @@ * Sets the correct content density based on the owner element's state | ||
const dir = getEffectiveDir(this.ownerElement); | ||
if (dir) { | ||
if (dir === "rtl") { | ||
this.setAttribute("dir", dir); | ||
@@ -76,7 +77,7 @@ } | ||
/** | ||
* Returns reference to the DOM element where the current fragment is added. | ||
* @protected | ||
* Returns reference to the DOM element where the current fragment is added. | ||
*/ | ||
async getDomRef() { | ||
this._updateContentDensity(); | ||
this.updateAdditionalProperties(); | ||
if (!this._rendered) { | ||
@@ -83,0 +84,0 @@ this._rendered = true; |
@@ -6,4 +6,5 @@ import { getThemeProperties, getRegisteredPackages, isThemeRegistered } from "../asset-registries/Themes.js"; | ||
import { getFeature } from "../FeaturesRegistry.js"; | ||
import { attachCustomThemeStylesToHead, getThemeRoot } from "../config/ThemeRoots.js"; | ||
import { attachCustomThemeStylesToHead, getThemeRoot } from "../config/ThemeRoot.js"; | ||
import { DEFAULT_THEME } from "../generated/AssetParameters.js"; | ||
import { getCurrentRuntimeIndex } from "../Runtimes.js"; | ||
const BASE_THEME_PACKAGE = "@ui5/webcomponents-theming"; | ||
@@ -20,3 +21,3 @@ const isThemeBaseRegistered = () => { | ||
if (cssData) { | ||
createOrUpdateStyle(cssData, "data-ui5-theme-properties", BASE_THEME_PACKAGE); | ||
createOrUpdateStyle(cssData, "data-ui5-theme-properties", BASE_THEME_PACKAGE, theme); | ||
} | ||
@@ -27,3 +28,3 @@ }; | ||
}; | ||
const loadComponentPackages = async (theme) => { | ||
const loadComponentPackages = async (theme, externalThemeName) => { | ||
const registeredPackages = getRegisteredPackages(); | ||
@@ -34,5 +35,5 @@ const packagesStylesPromises = [...registeredPackages].map(async (packageName) => { | ||
} | ||
const cssData = await getThemeProperties(packageName, theme); | ||
const cssData = await getThemeProperties(packageName, theme, externalThemeName); | ||
if (cssData) { | ||
createOrUpdateStyle(cssData, "data-ui5-theme-properties", packageName); | ||
createOrUpdateStyle(cssData, `data-ui5-component-properties-${getCurrentRuntimeIndex()}`, packageName); | ||
} | ||
@@ -50,3 +51,3 @@ }); | ||
const openUI5Support = getFeature("OpenUI5Support"); | ||
if (openUI5Support) { | ||
if (openUI5Support && openUI5Support.isOpenUI5Detected()) { | ||
const varsLoaded = openUI5Support.cssVariablesLoaded(); | ||
@@ -76,3 +77,3 @@ if (varsLoaded) { | ||
const packagesTheme = isThemeRegistered(theme) ? theme : extTheme && extTheme.baseThemeName; | ||
await loadComponentPackages(packagesTheme || DEFAULT_THEME); | ||
await loadComponentPackages(packagesTheme || DEFAULT_THEME, extTheme && extTheme.themeName === theme ? theme : undefined); | ||
fireThemeLoaded(theme); | ||
@@ -79,0 +80,0 @@ }; |
import { reRenderAllUI5Elements } from "../Render.js"; | ||
import getSharedResource from "../getSharedResource.js"; | ||
import EventProvider from "../EventProvider.js"; | ||
const eventProvider = getSharedResource("CustomStyle.eventProvider", new EventProvider()); | ||
const getEventProvider = () => getSharedResource("CustomStyle.eventProvider", new EventProvider()); | ||
const CUSTOM_CSS_CHANGE = "CustomCSSChange"; | ||
const attachCustomCSSChange = (listener) => { | ||
eventProvider.attachEvent(CUSTOM_CSS_CHANGE, listener); | ||
getEventProvider().attachEvent(CUSTOM_CSS_CHANGE, listener); | ||
}; | ||
const detachCustomCSSChange = (listener) => { | ||
eventProvider.detachEvent(CUSTOM_CSS_CHANGE, listener); | ||
getEventProvider().detachEvent(CUSTOM_CSS_CHANGE, listener); | ||
}; | ||
const fireCustomCSSChange = (tag) => { | ||
return eventProvider.fireEvent(CUSTOM_CSS_CHANGE, tag); | ||
return getEventProvider().fireEvent(CUSTOM_CSS_CHANGE, tag); | ||
}; | ||
const customCSSFor = getSharedResource("CustomStyle.customCSSFor", {}); | ||
const getCustomCSSFor = () => getSharedResource("CustomStyle.customCSSFor", {}); | ||
// Listen to the eventProvider, in case other copies of this CustomStyle module fire this | ||
@@ -26,2 +26,3 @@ // event, and this copy would therefore need to reRender the ui5 webcomponents; but | ||
const addCustomCSS = (tag, css) => { | ||
const customCSSFor = getCustomCSSFor(); | ||
if (!customCSSFor[tag]) { | ||
@@ -44,2 +45,3 @@ customCSSFor[tag] = []; | ||
const getCustomCSS = (tag) => { | ||
const customCSSFor = getCustomCSSFor(); | ||
return customCSSFor[tag] ? customCSSFor[tag].join("") : ""; | ||
@@ -46,0 +48,0 @@ }; |
@@ -1,3 +0,3 @@ | ||
import { ComponentStylesData } from "../types.js"; | ||
import type { ComponentStylesData } from "../types.js"; | ||
declare const getStylesString: (styles: ComponentStylesData) => string; | ||
export default getStylesString; |
@@ -18,2 +18,12 @@ type PromiseResolve = (value: void | PromiseLike<void>) => void; | ||
}; | ||
export type { PromiseResolve, Timeout, Interval, StyleData, StyleDataCSP, ComponentStylesData, ClassMap, PassiveEventListenerObject, }; | ||
type LowercaseString<T> = T extends string ? Lowercase<T> : never; | ||
type AccessibilityInfo = { | ||
role?: LowercaseString<string>; | ||
type?: LowercaseString<string>; | ||
description?: string; | ||
disabled?: boolean; | ||
readonly?: boolean; | ||
required?: boolean; | ||
children?: Array<HTMLElement>; | ||
}; | ||
export type { AccessibilityInfo, PromiseResolve, Timeout, Interval, StyleData, StyleDataCSP, ComponentStylesData, ClassMap, ClassMapValue, PassiveEventListenerObject, }; |
/** | ||
* Different types of AnimationMode. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.AnimationMode | ||
*/ | ||
@@ -13,3 +9,2 @@ declare enum AnimationMode { | ||
* @public | ||
* @type {Full} | ||
*/ | ||
@@ -19,3 +14,2 @@ Full = "full", | ||
* @public | ||
* @type {Basic} | ||
*/ | ||
@@ -25,3 +19,2 @@ Basic = "basic", | ||
* @public | ||
* @type {Minimal} | ||
*/ | ||
@@ -31,3 +24,2 @@ Minimal = "minimal", | ||
* @public | ||
* @type {None} | ||
*/ | ||
@@ -34,0 +26,0 @@ None = "none" |
/** | ||
* Different types of AnimationMode. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.AnimationMode | ||
*/ | ||
@@ -14,3 +10,2 @@ var AnimationMode; | ||
* @public | ||
* @type {Full} | ||
*/ | ||
@@ -20,3 +15,2 @@ AnimationMode["Full"] = "full"; | ||
* @public | ||
* @type {Basic} | ||
*/ | ||
@@ -26,3 +20,2 @@ AnimationMode["Basic"] = "basic"; | ||
* @public | ||
* @type {Minimal} | ||
*/ | ||
@@ -32,3 +25,2 @@ AnimationMode["Minimal"] = "minimal"; | ||
* @public | ||
* @type {None} | ||
*/ | ||
@@ -35,0 +27,0 @@ AnimationMode["None"] = "none"; |
/** | ||
* Different calendar types. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.CalendarType | ||
*/ | ||
@@ -13,3 +9,2 @@ declare enum CalendarType { | ||
* @public | ||
* @type {Gregorian} | ||
*/ | ||
@@ -19,3 +14,2 @@ Gregorian = "Gregorian", | ||
* @public | ||
* @type {Islamic} | ||
*/ | ||
@@ -25,3 +19,2 @@ Islamic = "Islamic", | ||
* @public | ||
* @type {Japanese} | ||
*/ | ||
@@ -31,3 +24,2 @@ Japanese = "Japanese", | ||
* @public | ||
* @type {Buddhist} | ||
*/ | ||
@@ -37,3 +29,2 @@ Buddhist = "Buddhist", | ||
* @public | ||
* @type {Persian} | ||
*/ | ||
@@ -40,0 +31,0 @@ Persian = "Persian" |
/** | ||
* Different calendar types. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.CalendarType | ||
*/ | ||
@@ -14,3 +10,2 @@ var CalendarType; | ||
* @public | ||
* @type {Gregorian} | ||
*/ | ||
@@ -20,3 +15,2 @@ CalendarType["Gregorian"] = "Gregorian"; | ||
* @public | ||
* @type {Islamic} | ||
*/ | ||
@@ -26,3 +20,2 @@ CalendarType["Islamic"] = "Islamic"; | ||
* @public | ||
* @type {Japanese} | ||
*/ | ||
@@ -32,3 +25,2 @@ CalendarType["Japanese"] = "Japanese"; | ||
* @public | ||
* @type {Buddhist} | ||
*/ | ||
@@ -38,3 +30,2 @@ CalendarType["Buddhist"] = "Buddhist"; | ||
* @public | ||
* @type {Persian} | ||
*/ | ||
@@ -41,0 +32,0 @@ CalendarType["Persian"] = "Persian"; |
@@ -6,8 +6,3 @@ import DataType from "./DataType.js"; | ||
* | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @constructor | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.CSSColor | ||
* @public | ||
* @enum {string} | ||
*/ | ||
@@ -14,0 +9,0 @@ declare class CSSColor extends DataType { |
@@ -6,8 +6,3 @@ import DataType from "./DataType.js"; | ||
* | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @constructor | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.CSSColor | ||
* @public | ||
* @enum {string} | ||
*/ | ||
@@ -14,0 +9,0 @@ class CSSColor extends DataType { |
import { PropertyValue } from "../UI5ElementMetadata.js"; | ||
/** | ||
* @class | ||
* Base class for all data types. | ||
* | ||
* @class | ||
* @constructor | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.DataType | ||
* @public | ||
@@ -15,4 +12,2 @@ */ | ||
* @public | ||
* @abstract | ||
* @returns {Boolean} | ||
*/ | ||
@@ -19,0 +14,0 @@ static isValid(value: any): boolean; |
/** | ||
* @class | ||
* Base class for all data types. | ||
* | ||
* @class | ||
* @constructor | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.DataType | ||
* @public | ||
@@ -14,4 +11,2 @@ */ | ||
* @public | ||
* @abstract | ||
* @returns {Boolean} | ||
*/ | ||
@@ -18,0 +13,0 @@ // eslint-disable-next-line |
@@ -5,8 +5,4 @@ import DataType from "./DataType.js"; | ||
* DOM Element reference or ID. | ||
* <b>Note:</b> If an ID is passed, it is expected to be part of the same <code>document</code> element as the consuming component. | ||
* **Note:** If an ID is passed, it is expected to be part of the same `document` element as the consuming component. | ||
* | ||
* @constructor | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.DOMReference | ||
* @public | ||
@@ -13,0 +9,0 @@ */ |
@@ -5,8 +5,4 @@ import DataType from "./DataType.js"; | ||
* DOM Element reference or ID. | ||
* <b>Note:</b> If an ID is passed, it is expected to be part of the same <code>document</code> element as the consuming component. | ||
* **Note:** If an ID is passed, it is expected to be part of the same `document` element as the consuming component. | ||
* | ||
* @constructor | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.DOMReference | ||
* @public | ||
@@ -13,0 +9,0 @@ */ |
@@ -8,7 +8,3 @@ import { PropertyValue } from "../UI5ElementMetadata.js"; | ||
* @constructor | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.Float | ||
* @public | ||
* @enum {number} | ||
*/ | ||
@@ -15,0 +11,0 @@ declare class Float extends DataType { |
@@ -7,7 +7,3 @@ import DataType from "./DataType.js"; | ||
* @constructor | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.Float | ||
* @public | ||
* @enum {number} | ||
*/ | ||
@@ -14,0 +10,0 @@ class Float extends DataType { |
@@ -8,7 +8,3 @@ import { PropertyValue } from "../UI5ElementMetadata.js"; | ||
* @constructor | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.Integer | ||
* @public | ||
* @enum {number} | ||
*/ | ||
@@ -15,0 +11,0 @@ declare class Integer extends DataType { |
@@ -7,7 +7,3 @@ import DataType from "./DataType.js"; | ||
* @constructor | ||
* @extends sap.ui.webc.base.types.DataType | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.Integer | ||
* @public | ||
* @enum {number} | ||
*/ | ||
@@ -14,0 +10,0 @@ class Integer extends DataType { |
/** | ||
* Enumeration for different mode behaviors of the InvisibleMessage. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.InvisibleMessageMode | ||
*/ | ||
declare enum InvisibleMessageMode { | ||
declare const InvisibleMessageMode: { | ||
/** | ||
@@ -15,12 +11,11 @@ * Indicates that updates to the region should be presented at the next graceful opportunity, | ||
* @public | ||
* @type {Polite} | ||
*/ | ||
Polite = "Polite", | ||
readonly Polite: "Polite"; | ||
/** | ||
* Indicates that updates to the region have the highest priority and should be presented to the user immediately. | ||
* @public | ||
* @type {Assertive} | ||
*/ | ||
Assertive = "Assertive" | ||
} | ||
readonly Assertive: "Assertive"; | ||
}; | ||
type InvisibleMessageMode = typeof InvisibleMessageMode[keyof typeof InvisibleMessageMode]; | ||
export default InvisibleMessageMode; |
/** | ||
* Enumeration for different mode behaviors of the InvisibleMessage. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.InvisibleMessageMode | ||
*/ | ||
var InvisibleMessageMode; | ||
(function (InvisibleMessageMode) { | ||
const InvisibleMessageMode = { | ||
/** | ||
@@ -16,13 +11,11 @@ * Indicates that updates to the region should be presented at the next graceful opportunity, | ||
* @public | ||
* @type {Polite} | ||
*/ | ||
InvisibleMessageMode["Polite"] = "Polite"; | ||
Polite: "Polite", | ||
/** | ||
* Indicates that updates to the region have the highest priority and should be presented to the user immediately. | ||
* @public | ||
* @type {Assertive} | ||
*/ | ||
InvisibleMessageMode["Assertive"] = "Assertive"; | ||
})(InvisibleMessageMode || (InvisibleMessageMode = {})); | ||
Assertive: "Assertive", | ||
}; | ||
export default InvisibleMessageMode; | ||
//# sourceMappingURL=InvisibleMessageMode.js.map |
/** | ||
* Different behavior for ItemNavigation. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.ItemNavigationBehavior | ||
*/ | ||
@@ -14,3 +10,2 @@ declare enum ItemNavigationBehavior { | ||
* @public | ||
* @type {Static} | ||
*/ | ||
@@ -21,3 +16,2 @@ Static = "Static", | ||
* @public | ||
* @type {Cyclic} | ||
*/ | ||
@@ -24,0 +18,0 @@ Cyclic = "Cyclic" |
/** | ||
* Different behavior for ItemNavigation. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.ItemNavigationBehavior | ||
*/ | ||
@@ -15,3 +11,2 @@ var ItemNavigationBehavior; | ||
* @public | ||
* @type {Static} | ||
*/ | ||
@@ -22,3 +17,2 @@ ItemNavigationBehavior["Static"] = "Static"; | ||
* @public | ||
* @type {Cyclic} | ||
*/ | ||
@@ -25,0 +19,0 @@ ItemNavigationBehavior["Cyclic"] = "Cyclic"; |
/** | ||
* Different navigation modes for ItemNavigation. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.NavigationMode | ||
*/ | ||
@@ -13,3 +9,2 @@ declare enum NavigationMode { | ||
* @public | ||
* @type {Auto} | ||
*/ | ||
@@ -19,3 +14,2 @@ Auto = "Auto", | ||
* @public | ||
* @type {Vertical} | ||
*/ | ||
@@ -25,3 +19,2 @@ Vertical = "Vertical", | ||
* @public | ||
* @type {Horizontal} | ||
*/ | ||
@@ -31,3 +24,2 @@ Horizontal = "Horizontal", | ||
* @public | ||
* @type {Paging} | ||
*/ | ||
@@ -34,0 +26,0 @@ Paging = "Paging" |
/** | ||
* Different navigation modes for ItemNavigation. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.NavigationMode | ||
*/ | ||
@@ -14,3 +10,2 @@ var NavigationMode; | ||
* @public | ||
* @type {Auto} | ||
*/ | ||
@@ -20,3 +15,2 @@ NavigationMode["Auto"] = "Auto"; | ||
* @public | ||
* @type {Vertical} | ||
*/ | ||
@@ -26,3 +20,2 @@ NavigationMode["Vertical"] = "Vertical"; | ||
* @public | ||
* @type {Horizontal} | ||
*/ | ||
@@ -32,3 +25,2 @@ NavigationMode["Horizontal"] = "Horizontal"; | ||
* @public | ||
* @type {Paging} | ||
*/ | ||
@@ -35,0 +27,0 @@ NavigationMode["Paging"] = "Paging"; |
/** | ||
* Different types of ValueStates. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.ValueState | ||
*/ | ||
declare enum ValueState { | ||
/** | ||
* | ||
* @public | ||
* @type {None} | ||
*/ | ||
None = "None", | ||
/** | ||
* | ||
* @public | ||
* @type {Success} | ||
*/ | ||
Success = "Success", | ||
/** | ||
* | ||
* @public | ||
* @type {Warning} | ||
*/ | ||
Warning = "Warning", | ||
/** | ||
* | ||
* @public | ||
* @type {Error} | ||
*/ | ||
Error = "Error", | ||
/** | ||
* | ||
* @public | ||
* @type {Information} | ||
*/ | ||
@@ -40,0 +26,0 @@ Information = "Information" |
/** | ||
* Different types of ValueStates. | ||
* | ||
* @class | ||
* @enum {string} | ||
* @public | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.types.ValueState | ||
*/ | ||
@@ -13,29 +9,19 @@ var ValueState; | ||
/** | ||
* | ||
* @public | ||
* @type {None} | ||
*/ | ||
ValueState["None"] = "None"; | ||
/** | ||
* | ||
* @public | ||
* @type {Success} | ||
*/ | ||
ValueState["Success"] = "Success"; | ||
/** | ||
* | ||
* @public | ||
* @type {Warning} | ||
*/ | ||
ValueState["Warning"] = "Warning"; | ||
/** | ||
* | ||
* @public | ||
* @type {Error} | ||
*/ | ||
ValueState["Error"] = "Error"; | ||
/** | ||
* | ||
* @public | ||
* @type {Information} | ||
*/ | ||
@@ -42,0 +28,0 @@ ValueState["Information"] = "Information"; |
@@ -0,6 +1,15 @@ | ||
import "@ui5/webcomponents-base/dist/ssr-dom.js"; | ||
import UI5ElementMetadata, { Slot, SlotValue, State, PropertyValue, Metadata } from "./UI5ElementMetadata.js"; | ||
import EventProvider from "./EventProvider.js"; | ||
import StaticAreaItem from "./StaticAreaItem.js"; | ||
import { TemplateFunction, TemplateFunctionResult } from "./renderer/executeTemplate.js"; | ||
import { PromiseResolve, ComponentStylesData, ClassMap } from "./types.js"; | ||
import type { TemplateFunction, TemplateFunctionResult } from "./renderer/executeTemplate.js"; | ||
import type { AccessibilityInfo, PromiseResolve, ComponentStylesData, ClassMap } from "./types.js"; | ||
type Renderer = (templateResult: TemplateFunctionResult, container: HTMLElement | DocumentFragment, styleStrOrHrefsArr: string | Array<string> | undefined, forStaticArea: boolean, options: RendererOptions) => void; | ||
type RendererOptions = { | ||
/** | ||
* An object to use as the `this` value for event listeners. It's often | ||
* useful to set this to the host component rendering a template. | ||
*/ | ||
host?: object; | ||
}; | ||
type ChangeInfo = { | ||
@@ -21,8 +30,5 @@ type: "property" | "slot"; | ||
/** | ||
* @class | ||
* Base class for all UI5 Web Components | ||
* | ||
* @class | ||
* @constructor | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.UI5Element | ||
* @extends HTMLElement | ||
@@ -35,3 +41,4 @@ * @public | ||
_changedState: Array<ChangeInfo>; | ||
_eventProvider: EventProvider<InvalidationInfo, void>; | ||
_invalidationEventProvider: EventProvider<InvalidationInfo, void>; | ||
_componentStateFinalizedEventProvider: EventProvider<void, void>; | ||
_inDOM: boolean; | ||
@@ -46,3 +53,2 @@ _fullyConnected: boolean; | ||
_state: State; | ||
_onComponentStateFinalized?: () => void; | ||
_getRealDomRef?: () => HTMLElement; | ||
@@ -53,5 +59,7 @@ staticAreaItem?: StaticAreaItem; | ||
static _metadata: UI5ElementMetadata; | ||
static render: (templateFunctionResult: TemplateFunctionResult, container: HTMLElement | DocumentFragment, styleStrOrHrefsArr: string | Array<string> | undefined, forStaticArea: boolean, options: { | ||
host: HTMLElement; | ||
}) => void; | ||
/** | ||
* @deprecated | ||
*/ | ||
static render: Renderer; | ||
static renderer?: Renderer; | ||
constructor(); | ||
@@ -65,2 +73,4 @@ /** | ||
get _id(): string; | ||
render(): object; | ||
renderStatic(): object; | ||
/** | ||
@@ -121,3 +131,3 @@ * Do not call this method from derivatives of UI5Element, use "onEnterDOM" only | ||
* | ||
* @param {InvalidationInfo} callback | ||
* @param callback | ||
* @public | ||
@@ -129,3 +139,3 @@ */ | ||
* | ||
* @param {InvalidationInfo} callback | ||
* @param callback | ||
* @public | ||
@@ -137,4 +147,4 @@ */ | ||
* | ||
* @param {sting} slotName the slot in which a child was invalidated | ||
* @param { ChangeInfo } childChangeInfo the changeInfo object for the child in the given slot | ||
* @param slotName the slot in which a child was invalidated | ||
* @param childChangeInfo the changeInfo object for the child in the given slot | ||
* @private | ||
@@ -164,6 +174,5 @@ */ | ||
* @param slotName the name of the slot, where the child is | ||
* @returns {ChildChangeListener} | ||
* @private | ||
*/ | ||
_getChildChangeListener(slotName: string): ChildChangeListener | undefined; | ||
_getChildChangeListener(slotName: string): ChildChangeListener; | ||
/** | ||
@@ -173,3 +182,2 @@ * Returns a singleton slotchange event listener that invalidates the component due to changes in the given slot | ||
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is | ||
* @returns {SlotChangeListener} | ||
* @private | ||
@@ -258,3 +266,3 @@ */ | ||
* Set the focus to the element, returned by "getFocusDomRef()" (marked by "data-sap-focus-ref") | ||
* @param {FocusOptions} focusOptions additional options for the focus | ||
* @param focusOptions additional options for the focus | ||
* @public | ||
@@ -270,3 +278,3 @@ */ | ||
* @param bubbles - true, if the event bubbles | ||
* @returns {boolean} false, if the event was cancelled (preventDefault called), true otherwise | ||
* @returns false, if the event was cancelled (preventDefault called), true otherwise | ||
*/ | ||
@@ -280,4 +288,18 @@ fireEvent<T>(name: string, data?: T, cancelable?: boolean, bubbles?: boolean): boolean; | ||
*/ | ||
getSlottedNodes(slotName: string): Node[]; | ||
getSlottedNodes<T = Node>(slotName: string): Array<T>; | ||
/** | ||
* Attach a callback that will be executed whenever the component's state is finalized | ||
* | ||
* @param callback | ||
* @public | ||
*/ | ||
attachComponentStateFinalized(callback: () => void): void; | ||
/** | ||
* Detach the callback that is executed whenever the component's state is finalized | ||
* | ||
* @param callback | ||
* @public | ||
*/ | ||
detachComponentStateFinalized(callback: () => void): void; | ||
/** | ||
* Determines whether the component should be rendered in RTL mode or not. | ||
@@ -287,3 +309,3 @@ * Returns: "rtl", "ltr" or undefined | ||
* @public | ||
* @returns {String|undefined} | ||
* @default undefined | ||
*/ | ||
@@ -293,4 +315,4 @@ get effectiveDir(): string | undefined; | ||
* Used to duck-type UI5 elements without using instanceof | ||
* @returns {boolean} | ||
* @public | ||
* @default true | ||
*/ | ||
@@ -300,2 +322,7 @@ get isUI5Element(): boolean; | ||
/** | ||
* Returns the component accessibility info. | ||
* @private | ||
*/ | ||
get accessibilityInfo(): AccessibilityInfo; | ||
/** | ||
* Do not override this method in derivatives of UI5Element, use metadata properties instead | ||
@@ -325,13 +352,8 @@ * @private | ||
*/ | ||
static get metadata(): Metadata; | ||
static metadata: Metadata; | ||
/** | ||
* Sets a new metadata object for this UI5 Web Component Class | ||
* @protected | ||
*/ | ||
static set metadata(newMetadata: Metadata); | ||
/** | ||
* Returns the CSS for this UI5 Web Component Class | ||
* @protected | ||
*/ | ||
static get styles(): ComponentStylesData; | ||
static styles: ComponentStylesData; | ||
/** | ||
@@ -350,2 +372,3 @@ * Returns the Static Area CSS for this UI5 Web Component Class | ||
static get dependencies(): Array<typeof UI5Element>; | ||
static cacheUniqueDependencies(this: typeof UI5Element): void; | ||
/** | ||
@@ -356,7 +379,5 @@ * Returns a list of the unique dependencies for this UI5 Web Component | ||
*/ | ||
static getUniqueDependencies(this: typeof UI5Element): (typeof UI5Element)[]; | ||
static getUniqueDependencies(this: typeof UI5Element): Array<typeof UI5Element>; | ||
/** | ||
* Returns a promise that resolves whenever all dependencies for this UI5 Web Component have resolved | ||
* | ||
* @returns {Promise} | ||
*/ | ||
@@ -368,3 +389,2 @@ static whenDependenciesDefined(): Promise<Array<typeof UI5Element>>; | ||
* @protected | ||
* @returns {Promise<void>} | ||
*/ | ||
@@ -375,3 +395,2 @@ static onDefine(): Promise<void>; | ||
* @public | ||
* @returns {Promise<UI5Element>} | ||
*/ | ||
@@ -383,10 +402,7 @@ static define(): Promise<typeof UI5Element>; | ||
* @public | ||
* @returns {UI5ElementMetadata} | ||
*/ | ||
static getMetadata(): UI5ElementMetadata; | ||
static decoratorMetadata: Metadata; | ||
} | ||
/** | ||
* Always use duck-typing to cover all runtimes on the page. | ||
* @returns {boolean} | ||
*/ | ||
@@ -396,2 +412,2 @@ declare const instanceOfUI5Element: (object: any) => object is UI5Element; | ||
export { instanceOfUI5Element }; | ||
export type { ChangeInfo }; | ||
export type { ChangeInfo, Renderer, RendererOptions, }; |
@@ -0,1 +1,3 @@ | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
import "@ui5/webcomponents-base/dist/ssr-dom.js"; | ||
import merge from "./thirdparty/merge.js"; | ||
@@ -8,2 +10,3 @@ import { boot } from "./Boot.js"; | ||
import updateShadowRoot from "./updateShadowRoot.js"; | ||
import { shouldIgnoreCustomElement } from "./IgnoreCustomElements.js"; | ||
import { renderDeferred, renderImmediately, cancelRender } from "./Render.js"; | ||
@@ -20,2 +23,4 @@ import { registerTag, isTagRegistered, recordTagRegistrationFailure } from "./CustomElementsRegistry.js"; | ||
import preloadLinks from "./theming/preloadLinks.js"; | ||
import executeTemplate from "./renderer/executeTemplate.js"; | ||
import { subscribeForFeatureLoad } from "./FeaturesRegistry.js"; | ||
let autoId = 0; | ||
@@ -39,12 +44,24 @@ const elementTimeouts = new Map(); | ||
renderDeferred(this); | ||
this._eventProvider.fireEvent("invalidate", { ...changeInfo, target: this }); | ||
this._invalidationEventProvider.fireEvent("invalidate", { ...changeInfo, target: this }); | ||
} | ||
let metadata = {}; | ||
/** | ||
* looks up a property descsriptor including in the prototype chain | ||
* @param proto the starting prototype | ||
* @param name the property to look for | ||
* @returns the property descriptor if found directly or in the prototype chaing, undefined if not found | ||
*/ | ||
function getPropertyDescriptor(proto, name) { | ||
do { | ||
const descriptor = Object.getOwnPropertyDescriptor(proto, name); | ||
if (descriptor) { | ||
return descriptor; | ||
} | ||
// go up the prototype chain | ||
proto = Object.getPrototypeOf(proto); | ||
} while (proto && proto !== HTMLElement.prototype); | ||
} | ||
/** | ||
* @class | ||
* Base class for all UI5 Web Components | ||
* | ||
* @class | ||
* @constructor | ||
* @author SAP SE | ||
* @alias sap.ui.webc.base.UI5Element | ||
* @extends HTMLElement | ||
@@ -63,3 +80,4 @@ * @public | ||
this._slotChangeListeners = new Map(); // used to store lazy listeners per slot for the slotchange event of all slot children inside that slot | ||
this._eventProvider = new EventProvider(); // used by parent components for listening to changes to child components | ||
this._invalidationEventProvider = new EventProvider(); // used by parent components for listening to changes to child components | ||
this._componentStateFinalizedEventProvider = new EventProvider(); // used by friend classes for synchronization | ||
let deferredResolve; | ||
@@ -89,2 +107,10 @@ this._domRefReadyPromise = new Promise(resolve => { | ||
} | ||
render() { | ||
const template = this.constructor.template; | ||
return executeTemplate(template, this); | ||
} | ||
renderStatic() { | ||
const template = this.constructor.staticAreaTemplate; | ||
return executeTemplate(template, this); | ||
} | ||
/** | ||
@@ -160,10 +186,12 @@ * Do not call this method from derivatives of UI5Element, use "onEnterDOM" only | ||
const ctor = this.constructor; | ||
const shouldObserveChildren = ctor.getMetadata().hasSlots(); | ||
const metadata = ctor.getMetadata(); | ||
const shouldObserveChildren = metadata.hasSlots(); | ||
if (!shouldObserveChildren) { | ||
return; | ||
} | ||
const canSlotText = ctor.getMetadata().canSlotText(); | ||
const canSlotText = metadata.canSlotText(); | ||
const hasClonedSlot = Object.keys(metadata.getSlots()).some(slotName => metadata.getSlots()[slotName].cloned); | ||
const mutationObserverOptions = { | ||
childList: true, | ||
subtree: canSlotText, | ||
subtree: canSlotText || hasClonedSlot, | ||
characterData: canSlotText, | ||
@@ -229,7 +257,7 @@ }; | ||
const localName = child.localName; | ||
const isCustomElement = localName.includes("-"); | ||
if (isCustomElement) { | ||
const isDefined = window.customElements.get(localName); | ||
const shouldWaitForCustomElement = localName.includes("-") && !shouldIgnoreCustomElement(localName); | ||
if (shouldWaitForCustomElement) { | ||
const isDefined = customElements.get(localName); | ||
if (!isDefined) { | ||
const whenDefinedPromise = window.customElements.whenDefined(localName); // Class registered, but instances not upgraded yet | ||
const whenDefinedPromise = customElements.whenDefined(localName); // Class registered, but instances not upgraded yet | ||
let timeoutPromise = elementTimeouts.get(localName); | ||
@@ -242,3 +270,3 @@ if (!timeoutPromise) { | ||
} | ||
window.customElements.upgrade(child); | ||
customElements.upgrade(child); | ||
} | ||
@@ -318,7 +346,7 @@ } | ||
* | ||
* @param {InvalidationInfo} callback | ||
* @param callback | ||
* @public | ||
*/ | ||
attachInvalidate(callback) { | ||
this._eventProvider.attachEvent("invalidate", callback); | ||
this._invalidationEventProvider.attachEvent("invalidate", callback); | ||
} | ||
@@ -328,7 +356,7 @@ /** | ||
* | ||
* @param {InvalidationInfo} callback | ||
* @param callback | ||
* @public | ||
*/ | ||
detachInvalidate(callback) { | ||
this._eventProvider.detachEvent("invalidate", callback); | ||
this._invalidationEventProvider.detachEvent("invalidate", callback); | ||
} | ||
@@ -338,4 +366,4 @@ /** | ||
* | ||
* @param {sting} slotName the slot in which a child was invalidated | ||
* @param { ChangeInfo } childChangeInfo the changeInfo object for the child in the given slot | ||
* @param slotName the slot in which a child was invalidated | ||
* @param childChangeInfo the changeInfo object for the child in the given slot | ||
* @private | ||
@@ -450,3 +478,2 @@ */ | ||
* @param slotName the name of the slot, where the child is | ||
* @returns {ChildChangeListener} | ||
* @private | ||
@@ -464,3 +491,2 @@ */ | ||
* @param slotName the name of the slot, where the slot element (whose slotchange event we're listening to) is | ||
* @returns {SlotChangeListener} | ||
* @private | ||
@@ -541,5 +567,3 @@ */ | ||
// Intended for framework usage only. Currently ItemNavigation updates tab indexes after the component has updated its state but before the template is rendered | ||
if (this._onComponentStateFinalized) { | ||
this._onComponentStateFinalized(); | ||
} | ||
this._componentStateFinalizedEventProvider.fireEvent("componentStateFinalized"); | ||
// resume normal invalidation handling | ||
@@ -644,3 +668,3 @@ this._suppressInvalidation = false; | ||
* Set the focus to the element, returned by "getFocusDomRef()" (marked by "data-sap-focus-ref") | ||
* @param {FocusOptions} focusOptions additional options for the focus | ||
* @param focusOptions additional options for the focus | ||
* @public | ||
@@ -662,3 +686,3 @@ */ | ||
* @param bubbles - true, if the event bubbles | ||
* @returns {boolean} false, if the event was cancelled (preventDefault called), true otherwise | ||
* @returns false, if the event was cancelled (preventDefault called), true otherwise | ||
*/ | ||
@@ -669,3 +693,3 @@ fireEvent(name, data, cancelable = false, bubbles = true) { | ||
if (camelCaseEventName !== name) { | ||
return eventResult && this._fireEvent(camelCaseEventName, data, cancelable); | ||
return eventResult && this._fireEvent(camelCaseEventName, data, cancelable, bubbles); | ||
} | ||
@@ -706,2 +730,20 @@ return eventResult; | ||
/** | ||
* Attach a callback that will be executed whenever the component's state is finalized | ||
* | ||
* @param callback | ||
* @public | ||
*/ | ||
attachComponentStateFinalized(callback) { | ||
this._componentStateFinalizedEventProvider.attachEvent("componentStateFinalized", callback); | ||
} | ||
/** | ||
* Detach the callback that is executed whenever the component's state is finalized | ||
* | ||
* @param callback | ||
* @public | ||
*/ | ||
detachComponentStateFinalized(callback) { | ||
this._componentStateFinalizedEventProvider.detachEvent("componentStateFinalized", callback); | ||
} | ||
/** | ||
* Determines whether the component should be rendered in RTL mode or not. | ||
@@ -711,3 +753,3 @@ * Returns: "rtl", "ltr" or undefined | ||
* @public | ||
* @returns {String|undefined} | ||
* @default undefined | ||
*/ | ||
@@ -720,4 +762,4 @@ get effectiveDir() { | ||
* Used to duck-type UI5 elements without using instanceof | ||
* @returns {boolean} | ||
* @public | ||
* @default true | ||
*/ | ||
@@ -731,2 +773,9 @@ get isUI5Element() { | ||
/** | ||
* Returns the component accessibility info. | ||
* @private | ||
*/ | ||
get accessibilityInfo() { | ||
return {}; | ||
} | ||
/** | ||
* Do not override this method in derivatives of UI5Element, use metadata properties instead | ||
@@ -742,3 +791,3 @@ * @private | ||
static _needsShadowDOM() { | ||
return !!this.template; | ||
return !!this.template || Object.prototype.hasOwnProperty.call(this.prototype, "render"); | ||
} | ||
@@ -749,3 +798,3 @@ /** | ||
static _needsStaticArea() { | ||
return !!this.staticAreaTemplate; | ||
return !!this.staticAreaTemplate || Object.prototype.hasOwnProperty.call(this.prototype, "renderStatic"); | ||
} | ||
@@ -792,4 +841,21 @@ /** | ||
} | ||
const descriptor = getPropertyDescriptor(proto, prop); | ||
// if the decorator is on a setter, proxy the new setter to it | ||
let origSet; | ||
if (descriptor?.set) { | ||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
origSet = descriptor.set; | ||
} | ||
// if the decorator is on a setter, there will be a corresponding getter - proxy the new getter to it | ||
let origGet; | ||
if (descriptor?.get) { | ||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
origGet = descriptor.get; | ||
} | ||
Object.defineProperty(proto, prop, { | ||
get() { | ||
// proxy the getter to the original accessor if there was one | ||
if (origGet) { | ||
return origGet.call(this); | ||
} | ||
if (this._state[prop] !== undefined) { | ||
@@ -819,3 +885,3 @@ return this._state[prop]; | ||
let propertyValidator = propData.validator; | ||
const oldState = this._state[prop]; | ||
const oldState = origGet ? origGet.call(this) : this._state[prop]; | ||
if (propertyType && propertyType.isDataTypeClass) { | ||
@@ -834,3 +900,9 @@ propertyValidator = propertyType; | ||
if (isDifferent) { | ||
this._state[prop] = value; | ||
// if the decorator is on a setter, use it for storage | ||
if (origSet) { | ||
origSet.call(this, value); | ||
} | ||
else { | ||
this._state[prop] = value; | ||
} | ||
_invalidate.call(this, { | ||
@@ -870,23 +942,2 @@ type: "property", | ||
/** | ||
* Returns the metadata object for this UI5 Web Component Class | ||
* @protected | ||
*/ | ||
static get metadata() { | ||
return metadata; | ||
} | ||
/** | ||
* Sets a new metadata object for this UI5 Web Component Class | ||
* @protected | ||
*/ | ||
static set metadata(newMetadata) { | ||
metadata = newMetadata; | ||
} | ||
/** | ||
* Returns the CSS for this UI5 Web Component Class | ||
* @protected | ||
*/ | ||
static get styles() { | ||
return ""; | ||
} | ||
/** | ||
* Returns the Static Area CSS for this UI5 Web Component Class | ||
@@ -908,2 +959,6 @@ * @protected | ||
} | ||
static cacheUniqueDependencies() { | ||
const filtered = this.dependencies.filter((dep, index, deps) => deps.indexOf(dep) === index); | ||
uniqueDependenciesCache.set(this, filtered); | ||
} | ||
/** | ||
@@ -916,4 +971,3 @@ * Returns a list of the unique dependencies for this UI5 Web Component | ||
if (!uniqueDependenciesCache.has(this)) { | ||
const filtered = this.dependencies.filter((dep, index, deps) => deps.indexOf(dep) === index); | ||
uniqueDependenciesCache.set(this, filtered); | ||
this.cacheUniqueDependencies(); | ||
} | ||
@@ -924,4 +978,2 @@ return uniqueDependenciesCache.get(this) || []; | ||
* Returns a promise that resolves whenever all dependencies for this UI5 Web Component have resolved | ||
* | ||
* @returns {Promise} | ||
*/ | ||
@@ -935,3 +987,2 @@ static whenDependenciesDefined() { | ||
* @protected | ||
* @returns {Promise<void>} | ||
*/ | ||
@@ -944,3 +995,2 @@ static async onDefine() { | ||
* @public | ||
* @returns {Promise<UI5Element>} | ||
*/ | ||
@@ -954,2 +1004,6 @@ static async define() { | ||
const tag = this.getMetadata().getTag(); | ||
const features = this.getMetadata().getFeatures(); | ||
features.forEach(feature => { | ||
subscribeForFeatureLoad(feature, this, this.cacheUniqueDependencies.bind(this)); | ||
}); | ||
const definedLocally = isTagRegistered(tag); | ||
@@ -963,3 +1017,3 @@ const definedGlobally = customElements.get(tag); | ||
registerTag(tag); | ||
window.customElements.define(tag, this); | ||
customElements.define(tag, this); | ||
preloadLinks(this); | ||
@@ -973,3 +1027,2 @@ } | ||
* @public | ||
* @returns {UI5ElementMetadata} | ||
*/ | ||
@@ -980,9 +1033,7 @@ static getMetadata() { | ||
} | ||
const effectiveMetadata = Object.keys(this.metadata).length ? this.metadata : this.decoratorMetadata; | ||
const metadataObjects = [effectiveMetadata]; | ||
const metadataObjects = [this.metadata]; | ||
let klass = this; // eslint-disable-line | ||
while (klass !== UI5Element) { | ||
klass = Object.getPrototypeOf(klass); | ||
const effectiveKlassMetadata = Object.keys(klass.metadata).length ? klass.metadata : klass.decoratorMetadata; | ||
metadataObjects.unshift(effectiveKlassMetadata); | ||
metadataObjects.unshift(klass.metadata); | ||
} | ||
@@ -994,6 +1045,14 @@ const mergedMetadata = merge({}, ...metadataObjects); | ||
} | ||
UI5Element.decoratorMetadata = {}; | ||
/** | ||
* Returns the metadata object for this UI5 Web Component Class | ||
* @protected | ||
*/ | ||
UI5Element.metadata = {}; | ||
/** | ||
* Returns the CSS for this UI5 Web Component Class | ||
* @protected | ||
*/ | ||
UI5Element.styles = ""; | ||
/** | ||
* Always use duck-typing to cover all runtimes on the page. | ||
* @returns {boolean} | ||
*/ | ||
@@ -1000,0 +1059,0 @@ const instanceOfUI5Element = (object) => { |
@@ -12,2 +12,3 @@ import DataType from "./types/DataType.js"; | ||
invalidateOnChildChange?: boolean | SlotInvalidation; | ||
cloned?: boolean; | ||
}; | ||
@@ -34,6 +35,6 @@ type SlotValue = Node; | ||
languageAware?: boolean; | ||
features?: Array<string>; | ||
}; | ||
type State = Record<string, PropertyValue | Array<SlotValue>>; | ||
/** | ||
* | ||
* @class | ||
@@ -50,3 +51,3 @@ * @public | ||
* or returns the default value if not. | ||
* <b>Note:</b> Only intended for use by UI5Element.js | ||
* **Note:** Only intended for use by UI5Element.js | ||
* @public | ||
@@ -58,4 +59,4 @@ */ | ||
* or throws an exception if not. | ||
* <b>Note:</b> Only intended for use by UI5Element.js | ||
* @pubic | ||
* **Note:** Only intended for use by UI5Element.js | ||
* @public | ||
*/ | ||
@@ -69,2 +70,7 @@ static validateSlotValue(value: Node, slotData: Slot): Node; | ||
/** | ||
* Returns the tag of the UI5 Element without the scope | ||
* @private | ||
*/ | ||
getFeatures(): Array<string>; | ||
/** | ||
* Returns the tag of the UI5 Element | ||
@@ -78,3 +84,2 @@ * @public | ||
* @param propName | ||
* @returns {boolean} | ||
*/ | ||
@@ -85,14 +90,11 @@ hasAttribute(propName: string): boolean; | ||
* @public | ||
* @returns {string[]} | ||
*/ | ||
getPropertiesList(): string[]; | ||
getPropertiesList(): Array<string>; | ||
/** | ||
* Returns an array with the attributes of the UI5 Element (in kebab-case) | ||
* @public | ||
* @returns {string[]} | ||
*/ | ||
getAttributesList(): string[]; | ||
getAttributesList(): Array<string>; | ||
/** | ||
* Determines whether this UI5 Element has a default slot of type Node, therefore can slot text | ||
* @returns {boolean} | ||
*/ | ||
@@ -137,3 +139,2 @@ canSlotText(): boolean; | ||
* Determines whether this UI5 Element has any translatable texts (needs to be invalidated upon language change) | ||
* @returns {boolean} | ||
*/ | ||
@@ -143,3 +144,2 @@ isLanguageAware(): boolean; | ||
* Determines whether this UI5 Element has any theme dependant carachteristics. | ||
* @returns {boolean} | ||
*/ | ||
@@ -154,3 +154,2 @@ isThemeAware(): boolean; | ||
* @param name the name of the property/slot that changed | ||
* @returns {boolean} | ||
*/ | ||
@@ -157,0 +156,0 @@ shouldInvalidateOnChildChange(slotName: string, type: "property" | "slot", name: string): boolean; |
@@ -5,3 +5,2 @@ import { camelToKebabCase } from "./util/StringHelper.js"; | ||
/** | ||
* | ||
* @class | ||
@@ -32,6 +31,16 @@ * @public | ||
else if (props[propName].multiple) { | ||
initialState[propName] = []; | ||
Object.defineProperty(initialState, propName, { | ||
enumerable: true, | ||
get() { | ||
return []; | ||
}, | ||
}); | ||
} | ||
else if (propType === Object) { | ||
initialState[propName] = "defaultValue" in props[propName] ? props[propName].defaultValue : {}; | ||
Object.defineProperty(initialState, propName, { | ||
enumerable: true, | ||
get() { | ||
return "defaultValue" in props[propName] ? props[propName].defaultValue : {}; | ||
}, | ||
}); | ||
} | ||
@@ -59,3 +68,3 @@ else if (propType === String) { | ||
* or returns the default value if not. | ||
* <b>Note:</b> Only intended for use by UI5Element.js | ||
* **Note:** Only intended for use by UI5Element.js | ||
* @public | ||
@@ -73,4 +82,4 @@ */ | ||
* or throws an exception if not. | ||
* <b>Note:</b> Only intended for use by UI5Element.js | ||
* @pubic | ||
* **Note:** Only intended for use by UI5Element.js | ||
* @public | ||
*/ | ||
@@ -88,2 +97,9 @@ static validateSlotValue(value, slotData) { | ||
/** | ||
* Returns the tag of the UI5 Element without the scope | ||
* @private | ||
*/ | ||
getFeatures() { | ||
return this.metadata.features || []; | ||
} | ||
/** | ||
* Returns the tag of the UI5 Element | ||
@@ -107,3 +123,2 @@ * @public | ||
* @param propName | ||
* @returns {boolean} | ||
*/ | ||
@@ -117,3 +132,2 @@ hasAttribute(propName) { | ||
* @public | ||
* @returns {string[]} | ||
*/ | ||
@@ -126,3 +140,2 @@ getPropertiesList() { | ||
* @public | ||
* @returns {string[]} | ||
*/ | ||
@@ -134,7 +147,5 @@ getAttributesList() { | ||
* Determines whether this UI5 Element has a default slot of type Node, therefore can slot text | ||
* @returns {boolean} | ||
*/ | ||
canSlotText() { | ||
const defaultSlot = this.getSlots().default; | ||
return defaultSlot && defaultSlot.type === Node; | ||
return (this.getSlots().default)?.type === Node; | ||
} | ||
@@ -201,3 +212,2 @@ /** | ||
* Determines whether this UI5 Element has any translatable texts (needs to be invalidated upon language change) | ||
* @returns {boolean} | ||
*/ | ||
@@ -209,3 +219,2 @@ isLanguageAware() { | ||
* Determines whether this UI5 Element has any theme dependant carachteristics. | ||
* @returns {boolean} | ||
*/ | ||
@@ -222,3 +231,2 @@ isThemeAware() { | ||
* @param name the name of the property/slot that changed | ||
* @returns {boolean} | ||
*/ | ||
@@ -283,2 +291,3 @@ shouldInvalidateOnChildChange(slotName, type, name) { | ||
if (!propertyType || propertyType === String) { | ||
// eslint-disable-next-line @typescript-eslint/no-base-to-string -- if an object is passed as a value to a string property, this was an error so displaying [object Object] will indicate the issue to the developer | ||
return (typeof value === "string" || typeof value === "undefined" || value === null) ? value : value.toString(); | ||
@@ -285,0 +294,0 @@ } |
@@ -1,2 +0,1 @@ | ||
import executeTemplate from "./renderer/executeTemplate.js"; | ||
import getConstructableStyle from "./theming/getConstructableStyle.js"; | ||
@@ -6,2 +5,3 @@ import getEffectiveStyle from "./theming/getEffectiveStyle.js"; | ||
import { shouldUseLinks } from "./CSP.js"; | ||
import { isSafari } from "./Device.js"; | ||
/** | ||
@@ -15,6 +15,10 @@ * Updates the shadow root of a UI5Element or its static area item | ||
const ctor = element.constructor; | ||
const propertyName = forStaticArea ? "staticAreaTemplate" : "template"; | ||
const template = ctor[propertyName]; | ||
const shadowRoot = forStaticArea ? element.staticAreaItem.shadowRoot : element.shadowRoot; | ||
const renderResult = executeTemplate(template, element); // this is checked before calling updateShadowRoot | ||
let renderResult; | ||
if (forStaticArea) { | ||
renderResult = element.renderStatic(); // this is checked before calling updateShadowRoot | ||
} | ||
else { | ||
renderResult = element.render(); // this is checked before calling updateShadowRoot | ||
} | ||
if (!shadowRoot) { | ||
@@ -27,3 +31,3 @@ console.warn(`There is no shadow root to update`); // eslint-disable-line | ||
} | ||
else if (document.adoptedStyleSheets) { // Chrome | ||
else if (document.adoptedStyleSheets && !isSafari()) { // Chrome | ||
shadowRoot.adoptedStyleSheets = getConstructableStyle(ctor, forStaticArea); | ||
@@ -34,2 +38,6 @@ } | ||
} | ||
if (ctor.renderer) { | ||
ctor.renderer(renderResult, shadowRoot, styleStrOrHrefsArr, forStaticArea, { host: element }); | ||
return; | ||
} | ||
ctor.render(renderResult, shadowRoot, styleStrOrHrefsArr, forStaticArea, { host: element }); | ||
@@ -36,0 +44,0 @@ }; |
@@ -0,6 +1,15 @@ | ||
import UI5Element from "../UI5Element.js"; | ||
type MutationCallback = () => void; | ||
declare const getEffectiveAriaLabelText: (el: HTMLElement) => string | undefined; | ||
/** | ||
* | ||
* @param {HTMLElement} el Defines the HTMLElement, for which you need to get all related texts | ||
*/ | ||
declare const getAllAccessibleNameRefTexts: (el: HTMLElement) => string; | ||
/** | ||
* @param {HTMLElement} el Defines the HTMLElement, for which you need to get all related "label for" texts | ||
*/ | ||
declare const getAssociatedLabelForTexts: (el: HTMLElement) => string | undefined; | ||
export { getEffectiveAriaLabelText, getAssociatedLabelForTexts, }; | ||
declare const registerUI5Element: (el: UI5Element, callback: MutationCallback) => void; | ||
declare const deregisterUI5Element: (el: UI5Element) => void; | ||
export { getEffectiveAriaLabelText, getAssociatedLabelForTexts, registerUI5Element, deregisterUI5Element, getAllAccessibleNameRefTexts, }; |
@@ -0,1 +1,9 @@ | ||
const associatedElements = new WeakMap(); | ||
const registeredElements = new WeakMap(); | ||
const observerOptions = { | ||
attributes: true, | ||
childList: true, | ||
characterData: true, | ||
subtree: true, | ||
}; | ||
const getEffectiveAriaLabelText = (el) => { | ||
@@ -9,3 +17,3 @@ const accessibleEl = el; | ||
} | ||
return _getAriaLabelledByTexts(el); | ||
return getAllAccessibleNameRefTexts(el); | ||
}; | ||
@@ -16,4 +24,4 @@ /** | ||
*/ | ||
const _getAriaLabelledByTexts = (el) => { | ||
const ids = el.accessibleNameRef.split(" "); | ||
const getAllAccessibleNameRefTexts = (el) => { | ||
const ids = el.accessibleNameRef?.split(" ") ?? []; | ||
const owner = el.getRootNode(); | ||
@@ -23,5 +31,8 @@ let result = ""; | ||
const element = owner.querySelector(`[id='${elementId}']`); | ||
result += `${element && element.textContent ? element.textContent : ""}`; | ||
if (index < ids.length - 1) { | ||
result += " "; | ||
const text = `${element && element.textContent ? element.textContent : ""}`; | ||
if (text) { | ||
result += text; | ||
if (index < ids.length - 1) { | ||
result += " "; | ||
} | ||
} | ||
@@ -31,2 +42,27 @@ }); | ||
}; | ||
const _getAllAssociatedElementsFromDOM = (el) => { | ||
const set = new Set(); | ||
// adding labels with attribute for matching the el.id | ||
const labelsForAssociated = _getAssociatedLabels(el); | ||
labelsForAssociated.forEach(itm => { | ||
set.add(itm); | ||
}); | ||
// adding other elements that id is the same as accessibleNameRef value | ||
const value = el["accessibleNameRef"]; | ||
const ids = value?.split(" ") ?? []; | ||
ids.forEach(id => { | ||
const refEl = _getReferencedElementById(el, id); | ||
if (refEl) { | ||
set.add(refEl); | ||
} | ||
}); | ||
return Array.from(set); | ||
}; | ||
const _getAssociatedLabels = (el) => { | ||
const labels = el.getRootNode().querySelectorAll(`[for="${el.id}"]`); | ||
return Array.from(labels); | ||
}; | ||
const _getReferencedElementById = (el, elementId) => { | ||
return el.getRootNode().querySelector(`[id='${elementId}']`); | ||
}; | ||
/** | ||
@@ -37,3 +73,3 @@ * @param {HTMLElement} el Defines the HTMLElement, for which you need to get all related "label for" texts | ||
const results = []; | ||
const labels = el.getRootNode().querySelectorAll(`[ui5-label][for="${el.id}"],label[for="${el.id}"]`); | ||
const labels = _getAssociatedLabels(el); | ||
labels.forEach((label) => { | ||
@@ -48,3 +84,94 @@ const labelText = label.textContent; | ||
}; | ||
export { getEffectiveAriaLabelText, getAssociatedLabelForTexts, }; | ||
const _createInvalidationCallback = (el) => { | ||
const invalidationCallback = (changeInfo) => { | ||
if (!(changeInfo && changeInfo.type === "property" && changeInfo.name === "accessibleNameRef")) { | ||
return; | ||
} | ||
const registeredElement = registeredElements.get(el); | ||
if (!registeredElement) { | ||
return; | ||
} | ||
const oldAssociatedElements = registeredElement.observedElements; | ||
const newAssociatedElements = _getAllAssociatedElementsFromDOM(el); | ||
oldAssociatedElements.forEach(oldElement => { | ||
if (!newAssociatedElements.includes(oldElement)) { | ||
_removeObservedElementFromRegisteredElement(registeredElement, oldElement); | ||
} | ||
}); | ||
newAssociatedElements.forEach(newElement => { | ||
if (!oldAssociatedElements.includes(newElement)) { | ||
_addObservedElementToRegisteredElement(registeredElement, newElement); | ||
registeredElement.observedElements.push(newElement); | ||
} | ||
}); | ||
registeredElement?.callback(); | ||
}; | ||
return invalidationCallback; | ||
}; | ||
const registerUI5Element = (el, callback) => { | ||
if (registeredElements.has(el)) { | ||
return; | ||
} | ||
const allAssociatedElements = _getAllAssociatedElementsFromDOM(el); | ||
const invalidationCallback = _createInvalidationCallback(el); | ||
const registeredElement = { | ||
host: el, | ||
observedElements: allAssociatedElements, | ||
callback, | ||
invalidationCallback, | ||
}; | ||
registeredElements.set(el, registeredElement); | ||
el.attachInvalidate(invalidationCallback); | ||
allAssociatedElements.forEach((element) => { | ||
_addObservedElementToRegisteredElement(registeredElement, element); | ||
}); | ||
callback(); | ||
}; | ||
const _addObservedElementToRegisteredElement = (registeredElement, element) => { | ||
let associatedElement = associatedElements.get(element); | ||
if (!associatedElement) { | ||
associatedElement = { observer: null, callbacks: [] }; | ||
const observer = new MutationObserver(() => { | ||
const callbacks = associatedElement.callbacks; | ||
callbacks.forEach(callback => { | ||
callback(); | ||
}); | ||
const domEl = document.getElementById(element.id); | ||
// if no longer should be observed from this registeredElement, remove it | ||
if (!(registeredElement.host.id === element.getAttribute("for") || domEl)) { | ||
_removeObservedElementFromRegisteredElement(registeredElement, element); | ||
} | ||
}); | ||
associatedElement.observer = observer; | ||
observer.observe(element, observerOptions); | ||
associatedElements.set(element, associatedElement); | ||
} | ||
if (!associatedElement.callbacks.includes(registeredElement.callback)) { | ||
associatedElement.callbacks.push(registeredElement.callback); | ||
} | ||
}; | ||
const _removeObservedElementFromRegisteredElement = (registeredElement, element) => { | ||
const associatedElement = associatedElements.get(element); | ||
if (associatedElement) { | ||
associatedElement.callbacks = associatedElement.callbacks.filter(itm => itm !== registeredElement.callback); | ||
if (!associatedElement.callbacks.length) { | ||
associatedElement.observer?.disconnect(); | ||
associatedElements.delete(element); | ||
} | ||
} | ||
registeredElement.observedElements = registeredElement.observedElements.filter(itm => itm !== element); | ||
}; | ||
const deregisterUI5Element = (el) => { | ||
const registeredElement = registeredElements.get(el); | ||
if (!registeredElement) { | ||
return; | ||
} | ||
const oldObservedElements = [...registeredElement.observedElements]; | ||
oldObservedElements.forEach(observedElement => { | ||
_removeObservedElementFromRegisteredElement(registeredElement, observedElement); | ||
}); | ||
el.detachInvalidate(registeredElement.invalidationCallback); | ||
registeredElements.delete(el); | ||
}; | ||
export { getEffectiveAriaLabelText, getAssociatedLabelForTexts, registerUI5Element, deregisterUI5Element, getAllAccessibleNameRefTexts, }; | ||
//# sourceMappingURL=AriaLabelHelper.js.map |
@@ -9,5 +9,6 @@ /** | ||
const clamp = (val, min, max) => { | ||
return Math.min(Math.max(val, min), max); | ||
// handles case when max < min | ||
return Math.min(Math.max(val, min), Math.max(min, max)); | ||
}; | ||
export default clamp; | ||
//# sourceMappingURL=clamp.js.map |
@@ -8,153 +8,152 @@ /** | ||
*/ | ||
var CSSColors; | ||
(function (CSSColors) { | ||
CSSColors["aliceblue"] = "f0f8ff"; | ||
CSSColors["antiquewhite"] = "faebd7"; | ||
CSSColors["aqua"] = "00ffff"; | ||
CSSColors["aquamarine"] = "7fffd4"; | ||
CSSColors["azure"] = "f0ffff"; | ||
CSSColors["beige"] = "f5f5dc"; | ||
CSSColors["bisque"] = "ffe4c4"; | ||
CSSColors["black"] = "000000"; | ||
CSSColors["blanchedalmond"] = "ffebcd"; | ||
CSSColors["blue"] = "0000ff"; | ||
CSSColors["blueviolet"] = "8a2be2"; | ||
CSSColors["brown"] = "a52a2a"; | ||
CSSColors["burlywood"] = "deb887"; | ||
CSSColors["cadetblue"] = "5f9ea0"; | ||
CSSColors["chartreuse"] = "7fff00"; | ||
CSSColors["chocolate"] = "d2691e"; | ||
CSSColors["coral"] = "ff7f50"; | ||
CSSColors["cornflowerblue"] = "6495ed"; | ||
CSSColors["cornsilk"] = "fff8dc"; | ||
CSSColors["crimson"] = "dc143c"; | ||
CSSColors["cyan"] = "00ffff"; | ||
CSSColors["darkblue"] = "00008b"; | ||
CSSColors["darkcyan"] = "008b8b"; | ||
CSSColors["darkgoldenrod"] = "b8860b"; | ||
CSSColors["darkgray"] = "a9a9a9"; | ||
CSSColors["darkgrey"] = "a9a9a9"; | ||
CSSColors["darkgreen"] = "006400"; | ||
CSSColors["darkkhaki"] = "bdb76b"; | ||
CSSColors["darkmagenta"] = "8b008b"; | ||
CSSColors["darkolivegreen"] = "556b2f"; | ||
CSSColors["darkorange"] = "ff8c00"; | ||
CSSColors["darkorchid"] = "9932cc"; | ||
CSSColors["darkred"] = "8b0000"; | ||
CSSColors["darksalmon"] = "e9967a"; | ||
CSSColors["darkseagreen"] = "8fbc8f"; | ||
CSSColors["darkslateblue"] = "483d8b"; | ||
CSSColors["darkslategray"] = "2f4f4f"; | ||
CSSColors["darkslategrey"] = "2f4f4f"; | ||
CSSColors["darkturquoise"] = "00ced1"; | ||
CSSColors["darkviolet"] = "9400d3"; | ||
CSSColors["deeppink"] = "ff1493"; | ||
CSSColors["deepskyblue"] = "00bfff"; | ||
CSSColors["dimgray"] = "696969"; | ||
CSSColors["dimgrey"] = "696969"; | ||
CSSColors["dodgerblue"] = "1e90ff"; | ||
CSSColors["firebrick"] = "b22222"; | ||
CSSColors["floralwhite"] = "fffaf0"; | ||
CSSColors["forestgreen"] = "228b22"; | ||
CSSColors["fuchsia"] = "ff00ff"; | ||
CSSColors["gainsboro"] = "dcdcdc"; | ||
CSSColors["ghostwhite"] = "f8f8ff"; | ||
CSSColors["gold"] = "ffd700"; | ||
CSSColors["goldenrod"] = "daa520"; | ||
CSSColors["gray"] = "808080"; | ||
CSSColors["grey"] = "808080"; | ||
CSSColors["green"] = "008000"; | ||
CSSColors["greenyellow"] = "adff2f"; | ||
CSSColors["honeydew"] = "f0fff0"; | ||
CSSColors["hotpink"] = "ff69b4"; | ||
CSSColors["indianred"] = "cd5c5c"; | ||
CSSColors["indigo"] = "4b0082"; | ||
CSSColors["ivory"] = "fffff0"; | ||
CSSColors["khaki"] = "f0e68c"; | ||
CSSColors["lavender"] = "e6e6fa"; | ||
CSSColors["lavenderblush"] = "fff0f5"; | ||
CSSColors["lawngreen"] = "7cfc00"; | ||
CSSColors["lemonchiffon"] = "fffacd"; | ||
CSSColors["lightblue"] = "add8e6"; | ||
CSSColors["lightcoral"] = "f08080"; | ||
CSSColors["lightcyan"] = "e0ffff"; | ||
CSSColors["lightgoldenrodyellow"] = "fafad2"; | ||
CSSColors["lightgray"] = "d3d3d3"; | ||
CSSColors["lightgrey"] = "d3d3d3"; | ||
CSSColors["lightgreen"] = "90ee90"; | ||
CSSColors["lightpink"] = "ffb6c1"; | ||
CSSColors["lightsalmon"] = "ffa07a"; | ||
CSSColors["lightseagreen"] = "20b2aa"; | ||
CSSColors["lightskyblue"] = "87cefa"; | ||
CSSColors["lightslategray"] = "778899"; | ||
CSSColors["lightslategrey"] = "778899"; | ||
CSSColors["lightsteelblue"] = "b0c4de"; | ||
CSSColors["lightyellow"] = "ffffe0"; | ||
CSSColors["lime"] = "00ff00"; | ||
CSSColors["limegreen"] = "32cd32"; | ||
CSSColors["linen"] = "faf0e6"; | ||
CSSColors["magenta"] = "ff00ff"; | ||
CSSColors["maroon"] = "800000"; | ||
CSSColors["mediumaquamarine"] = "66cdaa"; | ||
CSSColors["mediumblue"] = "0000cd"; | ||
CSSColors["mediumorchid"] = "ba55d3"; | ||
CSSColors["mediumpurple"] = "9370db"; | ||
CSSColors["mediumseagreen"] = "3cb371"; | ||
CSSColors["mediumslateblue"] = "7b68ee"; | ||
CSSColors["mediumspringgreen"] = "00fa9a"; | ||
CSSColors["mediumturquoise"] = "48d1cc"; | ||
CSSColors["mediumvioletred"] = "c71585"; | ||
CSSColors["midnightblue"] = "191970"; | ||
CSSColors["mintcream"] = "f5fffa"; | ||
CSSColors["mistyrose"] = "ffe4e1"; | ||
CSSColors["moccasin"] = "ffe4b5"; | ||
CSSColors["navajowhite"] = "ffdead"; | ||
CSSColors["navy"] = "000080"; | ||
CSSColors["oldlace"] = "fdf5e6"; | ||
CSSColors["olive"] = "808000"; | ||
CSSColors["olivedrab"] = "6b8e23"; | ||
CSSColors["orange"] = "ffa500"; | ||
CSSColors["orangered"] = "ff4500"; | ||
CSSColors["orchid"] = "da70d6"; | ||
CSSColors["palegoldenrod"] = "eee8aa"; | ||
CSSColors["palegreen"] = "98fb98"; | ||
CSSColors["paleturquoise"] = "afeeee"; | ||
CSSColors["palevioletred"] = "db7093"; | ||
CSSColors["papayawhip"] = "ffefd5"; | ||
CSSColors["peachpuff"] = "ffdab9"; | ||
CSSColors["peru"] = "cd853f"; | ||
CSSColors["pink"] = "ffc0cb"; | ||
CSSColors["plum"] = "dda0dd"; | ||
CSSColors["powderblue"] = "b0e0e6"; | ||
CSSColors["purple"] = "800080"; | ||
CSSColors["red"] = "ff0000"; | ||
CSSColors["rosybrown"] = "bc8f8f"; | ||
CSSColors["royalblue"] = "4169e1"; | ||
CSSColors["saddlebrown"] = "8b4513"; | ||
CSSColors["salmon"] = "fa8072"; | ||
CSSColors["sandybrown"] = "f4a460"; | ||
CSSColors["seagreen"] = "2e8b57"; | ||
CSSColors["seashell"] = "fff5ee"; | ||
CSSColors["sienna"] = "a0522d"; | ||
CSSColors["silver"] = "c0c0c0"; | ||
CSSColors["skyblue"] = "87ceeb"; | ||
CSSColors["slateblue"] = "6a5acd"; | ||
CSSColors["slategray"] = "708090"; | ||
CSSColors["slategrey"] = "708090"; | ||
CSSColors["snow"] = "fffafa"; | ||
CSSColors["springgreen"] = "00ff7f"; | ||
CSSColors["steelblue"] = "4682b4"; | ||
CSSColors["tan"] = "d2b48c"; | ||
CSSColors["teal"] = "008080"; | ||
CSSColors["thistle"] = "d8bfd8"; | ||
CSSColors["tomato"] = "ff6347"; | ||
CSSColors["turquoise"] = "40e0d0"; | ||
CSSColors["violet"] = "ee82ee"; | ||
CSSColors["wheat"] = "f5deb3"; | ||
CSSColors["white"] = "ffffff"; | ||
CSSColors["whitesmoke"] = "f5f5f5"; | ||
CSSColors["yellow"] = "ffff00"; | ||
CSSColors["yellowgreen"] = "9acd32"; | ||
CSSColors["transparent"] = "00000000"; | ||
})(CSSColors || (CSSColors = {})); | ||
const CSSColors = new Map([ | ||
["aliceblue", "f0f8ff"], | ||
["antiquewhite", "faebd7"], | ||
["aqua", "00ffff"], | ||
["aquamarine", "7fffd4"], | ||
["azure", "f0ffff"], | ||
["beige", "f5f5dc"], | ||
["bisque", "ffe4c4"], | ||
["black", "000000"], | ||
["blanchedalmond", "ffebcd"], | ||
["blue", "0000ff"], | ||
["blueviolet", "8a2be2"], | ||
["brown", "a52a2a"], | ||
["burlywood", "deb887"], | ||
["cadetblue", "5f9ea0"], | ||
["chartreuse", "7fff00"], | ||
["chocolate", "d2691e"], | ||
["coral", "ff7f50"], | ||
["cornflowerblue", "6495ed"], | ||
["cornsilk", "fff8dc"], | ||
["crimson", "dc143c"], | ||
["cyan", "00ffff"], | ||
["darkblue", "00008b"], | ||
["darkcyan", "008b8b"], | ||
["darkgoldenrod", "b8860b"], | ||
["darkgray", "a9a9a9"], | ||
["darkgrey", "a9a9a9"], | ||
["darkgreen", "006400"], | ||
["darkkhaki", "bdb76b"], | ||
["darkmagenta", "8b008b"], | ||
["darkolivegreen", "556b2f"], | ||
["darkorange", "ff8c00"], | ||
["darkorchid", "9932cc"], | ||
["darkred", "8b0000"], | ||
["darksalmon", "e9967a"], | ||
["darkseagreen", "8fbc8f"], | ||
["darkslateblue", "483d8b"], | ||
["darkslategray", "2f4f4f"], | ||
["darkslategrey", "2f4f4f"], | ||
["darkturquoise", "00ced1"], | ||
["darkviolet", "9400d3"], | ||
["deeppink", "ff1493"], | ||
["deepskyblue", "00bfff"], | ||
["dimgray", "696969"], | ||
["dimgrey", "696969"], | ||
["dodgerblue", "1e90ff"], | ||
["firebrick", "b22222"], | ||
["floralwhite", "fffaf0"], | ||
["forestgreen", "228b22"], | ||
["fuchsia", "ff00ff"], | ||
["gainsboro", "dcdcdc"], | ||
["ghostwhite", "f8f8ff"], | ||
["gold", "ffd700"], | ||
["goldenrod", "daa520"], | ||
["gray", "808080"], | ||
["grey", "808080"], | ||
["green", "008000"], | ||
["greenyellow", "adff2f"], | ||
["honeydew", "f0fff0"], | ||
["hotpink", "ff69b4"], | ||
["indianred", "cd5c5c"], | ||
["indigo", "4b0082"], | ||
["ivory", "fffff0"], | ||
["khaki", "f0e68c"], | ||
["lavender", "e6e6fa"], | ||
["lavenderblush", "fff0f5"], | ||
["lawngreen", "7cfc00"], | ||
["lemonchiffon", "fffacd"], | ||
["lightblue", "add8e6"], | ||
["lightcoral", "f08080"], | ||
["lightcyan", "e0ffff"], | ||
["lightgoldenrodyellow", "fafad2"], | ||
["lightgray", "d3d3d3"], | ||
["lightgrey", "d3d3d3"], | ||
["lightgreen", "90ee90"], | ||
["lightpink", "ffb6c1"], | ||
["lightsalmon", "ffa07a"], | ||
["lightseagreen", "20b2aa"], | ||
["lightskyblue", "87cefa"], | ||
["lightslategray", "778899"], | ||
["lightslategrey", "778899"], | ||
["lightsteelblue", "b0c4de"], | ||
["lightyellow", "ffffe0"], | ||
["lime", "00ff00"], | ||
["limegreen", "32cd32"], | ||
["linen", "faf0e6"], | ||
["magenta", "ff00ff"], | ||
["maroon", "800000"], | ||
["mediumaquamarine", "66cdaa"], | ||
["mediumblue", "0000cd"], | ||
["mediumorchid", "ba55d3"], | ||
["mediumpurple", "9370db"], | ||
["mediumseagreen", "3cb371"], | ||
["mediumslateblue", "7b68ee"], | ||
["mediumspringgreen", "00fa9a"], | ||
["mediumturquoise", "48d1cc"], | ||
["mediumvioletred", "c71585"], | ||
["midnightblue", "191970"], | ||
["mintcream", "f5fffa"], | ||
["mistyrose", "ffe4e1"], | ||
["moccasin", "ffe4b5"], | ||
["navajowhite", "ffdead"], | ||
["navy", "000080"], | ||
["oldlace", "fdf5e6"], | ||
["olive", "808000"], | ||
["olivedrab", "6b8e23"], | ||
["orange", "ffa500"], | ||
["orangered", "ff4500"], | ||
["orchid", "da70d6"], | ||
["palegoldenrod", "eee8aa"], | ||
["palegreen", "98fb98"], | ||
["paleturquoise", "afeeee"], | ||
["palevioletred", "db7093"], | ||
["papayawhip", "ffefd5"], | ||
["peachpuff", "ffdab9"], | ||
["peru", "cd853f"], | ||
["pink", "ffc0cb"], | ||
["plum", "dda0dd"], | ||
["powderblue", "b0e0e6"], | ||
["purple", "800080"], | ||
["red", "ff0000"], | ||
["rosybrown", "bc8f8f"], | ||
["royalblue", "4169e1"], | ||
["saddlebrown", "8b4513"], | ||
["salmon", "fa8072"], | ||
["sandybrown", "f4a460"], | ||
["seagreen", "2e8b57"], | ||
["seashell", "fff5ee"], | ||
["sienna", "a0522d"], | ||
["silver", "c0c0c0"], | ||
["skyblue", "87ceeb"], | ||
["slateblue", "6a5acd"], | ||
["slategray", "708090"], | ||
["slategrey", "708090"], | ||
["snow", "fffafa"], | ||
["springgreen", "00ff7f"], | ||
["steelblue", "4682b4"], | ||
["tan", "d2b48c"], | ||
["teal", "008080"], | ||
["thistle", "d8bfd8"], | ||
["tomato", "ff6347"], | ||
["turquoise", "40e0d0"], | ||
["violet", "ee82ee"], | ||
["wheat", "f5deb3"], | ||
["white", "ffffff"], | ||
["whitesmoke", "f5f5f5"], | ||
["yellow", "ffff00"], | ||
["yellowgreen", "9acd32"], | ||
["transparent", "00000000"], | ||
]); | ||
const getRGBColor = (color) => { | ||
@@ -178,4 +177,4 @@ if (color.startsWith("rgba")) { | ||
// Css Color | ||
if (color in CSSColors) { | ||
color = CSSColors[color]; | ||
if (CSSColors.has(color)) { | ||
color = CSSColors.get(color); | ||
} | ||
@@ -220,57 +219,63 @@ return HEXToRGB(color); | ||
// Formula taken from https://www.rapidtables.com/convert/color/hsl-to-rgb.html | ||
const C = (1 - Math.abs((2 * color.l) - 1)) * color.s, X = C * (1 - Math.abs(((color.h / 60) % 2) - 1)), m = color.l - C / 2; | ||
let tempColor; | ||
switch (Math.round(color.h / 60)) { | ||
// 0 ≤ H < 60 | ||
let saturation = color.s * 100, lightness = color.l * 100, red, green, blue; | ||
if (saturation > 100) { | ||
saturation = 1; | ||
} | ||
else if (saturation < 0) { | ||
saturation = 0; | ||
} | ||
else { | ||
saturation /= 100; | ||
} | ||
if (lightness > 100) { | ||
lightness = 1; | ||
} | ||
else if (lightness < 0) { | ||
lightness = 0; | ||
} | ||
else { | ||
lightness /= 100; | ||
} | ||
const hue = color.h, d = saturation * (1 - Math.abs(2 * lightness - 1)), m = 255 * (lightness - 0.5 * d), x = d * (1 - Math.abs(((hue / 60) % 2) - 1)), i = Math.floor(hue / 60), m255x = m + 255 * x, m255d = m + 255 * d; | ||
switch (i) { | ||
case 0: | ||
tempColor = { | ||
r: C, | ||
g: X, | ||
b: 0, | ||
}; | ||
red = m255d; | ||
green = m255x; | ||
blue = m; | ||
break; | ||
// 60 ≤ H < 120 | ||
case 1: | ||
tempColor = { | ||
r: X, | ||
g: C, | ||
b: 0, | ||
}; | ||
red = m255x; | ||
green = m255d; | ||
blue = m; | ||
break; | ||
// 120 ≤ H < 180 | ||
case 2: | ||
tempColor = { | ||
r: 0, | ||
g: C, | ||
b: X, | ||
}; | ||
red = m; | ||
green = m255d; | ||
blue = m255x; | ||
break; | ||
// 180 ≤ H < 240 | ||
case 3: | ||
tempColor = { | ||
r: 0, | ||
g: X, | ||
b: C, | ||
}; | ||
red = m; | ||
green = m255x; | ||
blue = m255d; | ||
break; | ||
// 240 ≤ H < 300 | ||
case 4: | ||
tempColor = { | ||
r: X, | ||
g: 0, | ||
b: C, | ||
}; | ||
red = m255x; | ||
green = m; | ||
blue = m255d; | ||
break; | ||
// 300 ≤ H < 360 | ||
case 5: | ||
red = m255d; | ||
green = m; | ||
blue = m255x; | ||
break; | ||
default: | ||
tempColor = { | ||
r: C, | ||
g: 0, | ||
b: X, | ||
}; | ||
red = 0; | ||
green = 0; | ||
blue = 0; | ||
break; | ||
} | ||
return { | ||
r: Math.floor((tempColor.r + m) * 255), | ||
g: Math.floor((tempColor.g + m) * 255), | ||
b: Math.floor((tempColor.b + m) * 255), | ||
r: Math.round(red), | ||
g: Math.round(green), | ||
b: Math.round(blue), | ||
}; | ||
@@ -277,0 +282,0 @@ }; |
/** | ||
* Creates a <link> tag in the <head> tag | ||
* Creates a `<link>` tag in the `<head>` tag | ||
* @param href - the CSS | ||
@@ -4,0 +4,0 @@ * @param attributes - optional attributes to add to the tag |
/** | ||
* Creates a <link> tag in the <head> tag | ||
* Creates a `<link>` tag in the `<head>` tag | ||
* @param href - the CSS | ||
@@ -4,0 +4,0 @@ * @param attributes - optional attributes to add to the tag |
/** | ||
* Creates a <style> tag in the <head> tag | ||
* Creates a `<style>` tag in the `<head>` tag | ||
* @param cssText - the CSS | ||
@@ -4,0 +4,0 @@ * @param attributes - optional attributes to add to the tag |
/** | ||
* Creates a <style> tag in the <head> tag | ||
* Creates a `<style>` tag in the `<head>` tag | ||
* @param cssText - the CSS | ||
@@ -4,0 +4,0 @@ * @param attributes - optional attributes to add to the tag |
@@ -1,2 +0,2 @@ | ||
declare const _default: () => string; | ||
export default _default; | ||
declare const detectNavigatorLanguage: () => string; | ||
export default detectNavigatorLanguage; |
import { DEFAULT_LANGUAGE } from "../generated/AssetParameters.js"; | ||
export default () => { | ||
const isSSR = typeof document === "undefined"; | ||
const detectNavigatorLanguage = () => { | ||
if (isSSR) { | ||
return DEFAULT_LANGUAGE; | ||
} | ||
const browserLanguages = navigator.languages; | ||
@@ -10,2 +14,3 @@ const navigatorLanguage = () => { | ||
}; | ||
export default detectNavigatorLanguage; | ||
//# sourceMappingURL=detectNavigatorLanguage.js.map |
@@ -61,6 +61,7 @@ import isElementHidden from "./isElementHidden.js"; | ||
// If the child element is not part of the currently assigned element, | ||
// we have to check the next element assigned to the slot or continue with the next sibling of the slot, | ||
// otherwise, the nextSibling is the next element inside the light DOM | ||
// we have to check the next/previous element assigned to the slot or continue with the next/previous sibling of the slot, | ||
// otherwise, the nextSibling/previousSibling is the next element inside the light DOM | ||
if (assignedElements && !assignedElements[currentIndex].contains(child)) { | ||
child = assignedElements[++currentIndex]; | ||
currentIndex = forward ? currentIndex + 1 : currentIndex - 1; | ||
child = assignedElements[currentIndex]; | ||
} | ||
@@ -67,0 +68,0 @@ } |
@@ -7,5 +7,6 @@ import type UI5Element from "../UI5Element.js"; | ||
_changedState: import("../UI5Element.js").ChangeInfo[]; | ||
_eventProvider: import("../EventProvider.js").default<import("../UI5Element.js").ChangeInfo & { | ||
_invalidationEventProvider: import("../EventProvider.js").default<import("../UI5Element.js").ChangeInfo & { | ||
target: UI5Element; | ||
}, void>; | ||
_componentStateFinalizedEventProvider: import("../EventProvider.js").default<void, void>; | ||
_inDOM: boolean; | ||
@@ -22,6 +23,7 @@ _fullyConnected: boolean; | ||
_state: import("../UI5ElementMetadata.js").State; | ||
_onComponentStateFinalized?: (() => void) | undefined; | ||
_getRealDomRef?: (() => HTMLElement) | undefined; | ||
staticAreaItem?: import("../StaticAreaItem.js").default | undefined; | ||
readonly _id: string; | ||
render(): object; | ||
renderStatic(): object; | ||
connectedCallback(): Promise<void>; | ||
@@ -49,5 +51,5 @@ disconnectedCallback(): void; | ||
_upgradeAllProperties(): void; | ||
_getChildChangeListener(slotName: string): ((param: import("../UI5Element.js").ChangeInfo & { | ||
_getChildChangeListener(slotName: string): (param: import("../UI5Element.js").ChangeInfo & { | ||
target: UI5Element; | ||
}) => void) | undefined; | ||
}) => void; | ||
_getSlotChangeListener(slotName: string): (this: HTMLSlotElement, ev: Event) => void; | ||
@@ -69,6 +71,9 @@ _attachSlotChange(child: HTMLSlotElement, slotName: string): void; | ||
_fireEvent<T_1>(name: string, data?: T_1 | undefined, cancelable?: boolean, bubbles?: boolean): boolean; | ||
getSlottedNodes(slotName: string): Node[]; | ||
getSlottedNodes<T_2 = Node>(slotName: string): T_2[]; | ||
attachComponentStateFinalized(callback: () => void): void; | ||
detachComponentStateFinalized(callback: () => void): void; | ||
readonly effectiveDir: string | undefined; | ||
readonly isUI5Element: boolean; | ||
readonly classes: import("../types.js").ClassMap; | ||
readonly accessibilityInfo: import("../types.js").AccessibilityInfo; | ||
getStaticAreaItemDomRef(): Promise<ShadowRoot | null>; | ||
@@ -90,2 +95,3 @@ accessKey: string; | ||
outerText: string; | ||
popover: string | null; | ||
spellcheck: boolean; | ||
@@ -96,2 +102,5 @@ title: string; | ||
click(): void; | ||
hidePopover(): void; | ||
showPopover(): void; | ||
togglePopover(force?: boolean | undefined): void; | ||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; | ||
@@ -125,5 +134,8 @@ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; | ||
attachShadow(init: ShadowRootInit): ShadowRoot; | ||
checkVisibility(options?: CheckVisibilityOptions | undefined): boolean; | ||
closest<K_2 extends keyof HTMLElementTagNameMap>(selector: K_2): HTMLElementTagNameMap[K_2] | null; | ||
closest<K_3 extends keyof SVGElementTagNameMap>(selector: K_3): SVGElementTagNameMap[K_3] | null; | ||
closest<K_4 extends keyof MathMLElementTagNameMap>(selector: K_4): MathMLElementTagNameMap[K_4] | null; | ||
closest<E extends Element = Element>(selectors: string): E | null; | ||
computedStyleMap(): StylePropertyMapReadOnly; | ||
getAttribute(qualifiedName: string): string | null; | ||
@@ -137,7 +149,10 @@ getAttributeNS(namespace: string | null, localName: string): string | null; | ||
getElementsByClassName(classNames: string): HTMLCollectionOf<Element>; | ||
getElementsByTagName<K_4 extends keyof HTMLElementTagNameMap>(qualifiedName: K_4): HTMLCollectionOf<HTMLElementTagNameMap[K_4]>; | ||
getElementsByTagName<K_5 extends keyof SVGElementTagNameMap>(qualifiedName: K_5): HTMLCollectionOf<SVGElementTagNameMap[K_5]>; | ||
getElementsByTagName<K_5 extends keyof HTMLElementTagNameMap>(qualifiedName: K_5): HTMLCollectionOf<HTMLElementTagNameMap[K_5]>; | ||
getElementsByTagName<K_6 extends keyof SVGElementTagNameMap>(qualifiedName: K_6): HTMLCollectionOf<SVGElementTagNameMap[K_6]>; | ||
getElementsByTagName<K_7 extends keyof MathMLElementTagNameMap>(qualifiedName: K_7): HTMLCollectionOf<MathMLElementTagNameMap[K_7]>; | ||
getElementsByTagName<K_8 extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K_8): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K_8]>; | ||
getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>; | ||
getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>; | ||
getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>; | ||
getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1998/Math/MathML", localName: string): HTMLCollectionOf<MathMLElement>; | ||
getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>; | ||
@@ -185,3 +200,3 @@ hasAttribute(qualifiedName: string): boolean; | ||
textContent: string | null; | ||
appendChild<T_2 extends Node>(node: T_2): T_2; | ||
appendChild<T_3 extends Node>(node: T_3): T_3; | ||
cloneNode(deep?: boolean | undefined): Node; | ||
@@ -192,3 +207,3 @@ compareDocumentPosition(other: Node): number; | ||
hasChildNodes(): boolean; | ||
insertBefore<T_3 extends Node>(node: T_3, child: Node | null): T_3; | ||
insertBefore<T_4 extends Node>(node: T_4, child: Node | null): T_4; | ||
isDefaultNamespace(namespace: string | null): boolean; | ||
@@ -200,22 +215,22 @@ isEqualNode(otherNode: Node | null): boolean; | ||
normalize(): void; | ||
removeChild<T_4 extends Node>(child: T_4): T_4; | ||
replaceChild<T_5 extends Node>(node: Node, child: T_5): T_5; | ||
readonly ATTRIBUTE_NODE: number; | ||
readonly CDATA_SECTION_NODE: number; | ||
readonly COMMENT_NODE: number; | ||
readonly DOCUMENT_FRAGMENT_NODE: number; | ||
readonly DOCUMENT_NODE: number; | ||
readonly DOCUMENT_POSITION_CONTAINED_BY: number; | ||
readonly DOCUMENT_POSITION_CONTAINS: number; | ||
readonly DOCUMENT_POSITION_DISCONNECTED: number; | ||
readonly DOCUMENT_POSITION_FOLLOWING: number; | ||
readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: number; | ||
readonly DOCUMENT_POSITION_PRECEDING: number; | ||
readonly DOCUMENT_TYPE_NODE: number; | ||
readonly ELEMENT_NODE: number; | ||
readonly ENTITY_NODE: number; | ||
readonly ENTITY_REFERENCE_NODE: number; | ||
readonly NOTATION_NODE: number; | ||
readonly PROCESSING_INSTRUCTION_NODE: number; | ||
readonly TEXT_NODE: number; | ||
removeChild<T_5 extends Node>(child: T_5): T_5; | ||
replaceChild<T_6 extends Node>(node: Node, child: T_6): T_6; | ||
readonly ELEMENT_NODE: 1; | ||
readonly ATTRIBUTE_NODE: 2; | ||
readonly TEXT_NODE: 3; | ||
readonly CDATA_SECTION_NODE: 4; | ||
readonly ENTITY_REFERENCE_NODE: 5; | ||
readonly ENTITY_NODE: 6; | ||
readonly PROCESSING_INSTRUCTION_NODE: 7; | ||
readonly COMMENT_NODE: 8; | ||
readonly DOCUMENT_NODE: 9; | ||
readonly DOCUMENT_TYPE_NODE: 10; | ||
readonly DOCUMENT_FRAGMENT_NODE: 11; | ||
readonly NOTATION_NODE: 12; | ||
readonly DOCUMENT_POSITION_DISCONNECTED: 1; | ||
readonly DOCUMENT_POSITION_PRECEDING: 2; | ||
readonly DOCUMENT_POSITION_FOLLOWING: 4; | ||
readonly DOCUMENT_POSITION_CONTAINS: 8; | ||
readonly DOCUMENT_POSITION_CONTAINED_BY: 16; | ||
readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32; | ||
dispatchEvent(event: Event): boolean; | ||
@@ -228,3 +243,2 @@ ariaAtomic: string | null; | ||
ariaColIndex: string | null; | ||
ariaColIndexText: string | null; | ||
ariaColSpan: string | null; | ||
@@ -253,3 +267,2 @@ ariaCurrent: string | null; | ||
ariaRowIndex: string | null; | ||
ariaRowIndexText: string | null; | ||
ariaRowSpan: string | null; | ||
@@ -264,2 +277,5 @@ ariaSelected: string | null; | ||
role: string | null; | ||
ariaBraileLabel: string | null; | ||
ariaBraileRoleDescription: string | null; | ||
ariaDescription: string | null; | ||
animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions | undefined): Animation; | ||
@@ -280,13 +296,15 @@ getAnimations(options?: GetAnimationsOptions | undefined): Animation[]; | ||
prepend(...nodes: (string | Node)[]): void; | ||
querySelector<K_6 extends keyof HTMLElementTagNameMap>(selectors: K_6): HTMLElementTagNameMap[K_6] | null; | ||
querySelector<K_7 extends keyof SVGElementTagNameMap>(selectors: K_7): SVGElementTagNameMap[K_7] | null; | ||
querySelector<K_9 extends keyof HTMLElementTagNameMap>(selectors: K_9): HTMLElementTagNameMap[K_9] | null; | ||
querySelector<K_10 extends keyof SVGElementTagNameMap>(selectors: K_10): SVGElementTagNameMap[K_10] | null; | ||
querySelector<K_11 extends keyof MathMLElementTagNameMap>(selectors: K_11): MathMLElementTagNameMap[K_11] | null; | ||
querySelector<K_12 extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K_12): HTMLElementDeprecatedTagNameMap[K_12] | null; | ||
querySelector<E_1 extends Element = Element>(selectors: string): E_1 | null; | ||
querySelectorAll<K_8 extends keyof HTMLElementTagNameMap>(selectors: K_8): NodeListOf<HTMLElementTagNameMap[K_8]>; | ||
querySelectorAll<K_9 extends keyof SVGElementTagNameMap>(selectors: K_9): NodeListOf<SVGElementTagNameMap[K_9]>; | ||
querySelectorAll<K_13 extends keyof HTMLElementTagNameMap>(selectors: K_13): NodeListOf<HTMLElementTagNameMap[K_13]>; | ||
querySelectorAll<K_14 extends keyof SVGElementTagNameMap>(selectors: K_14): NodeListOf<SVGElementTagNameMap[K_14]>; | ||
querySelectorAll<K_15 extends keyof MathMLElementTagNameMap>(selectors: K_15): NodeListOf<MathMLElementTagNameMap[K_15]>; | ||
querySelectorAll<K_16 extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K_16): NodeListOf<HTMLElementDeprecatedTagNameMap[K_16]>; | ||
querySelectorAll<E_2 extends Element = Element>(selectors: string): NodeListOf<E_2>; | ||
replaceChildren(...nodes: (string | Node)[]): void; | ||
readonly assignedSlot: HTMLSlotElement | null; | ||
oncopy: ((this: DocumentAndElementEventHandlers, ev: ClipboardEvent) => any) | null; | ||
oncut: ((this: DocumentAndElementEventHandlers, ev: ClipboardEvent) => any) | null; | ||
onpaste: ((this: DocumentAndElementEventHandlers, ev: ClipboardEvent) => any) | null; | ||
readonly attributeStyleMap: StylePropertyMap; | ||
readonly style: CSSStyleDeclaration; | ||
@@ -312,3 +330,5 @@ contentEditable: string; | ||
oncontextmenu: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null; | ||
oncopy: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null; | ||
oncuechange: ((this: GlobalEventHandlers, ev: Event) => any) | null; | ||
oncut: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null; | ||
ondblclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null; | ||
@@ -346,2 +366,3 @@ ondrag: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null; | ||
onmouseup: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null; | ||
onpaste: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null; | ||
onpause: ((this: GlobalEventHandlers, ev: Event) => any) | null; | ||
@@ -363,2 +384,3 @@ onplay: ((this: GlobalEventHandlers, ev: Event) => any) | null; | ||
onscroll: ((this: GlobalEventHandlers, ev: Event) => any) | null; | ||
onscrollend: ((this: GlobalEventHandlers, ev: Event) => any) | null; | ||
onsecuritypolicyviolation: ((this: GlobalEventHandlers, ev: SecurityPolicyViolationEvent) => any) | null; | ||
@@ -400,5 +422,4 @@ onseeked: ((this: GlobalEventHandlers, ev: Event) => any) | null; | ||
_metadata: import("../UI5ElementMetadata.js").default; | ||
render: (templateFunctionResult: object, container: HTMLElement | DocumentFragment, styleStrOrHrefsArr: string | string[] | undefined, forStaticArea: boolean, options: { | ||
host: HTMLElement; | ||
}) => void; | ||
render: import("../UI5Element.js").Renderer; | ||
renderer?: import("../UI5Element.js").Renderer | undefined; | ||
readonly observedAttributes: string[]; | ||
@@ -409,5 +430,6 @@ _needsShadowDOM(): boolean; | ||
metadata: import("../UI5ElementMetadata.js").Metadata; | ||
readonly styles: import("../types.js").ComponentStylesData; | ||
styles: import("../types.js").ComponentStylesData; | ||
readonly staticAreaStyles: import("../types.js").ComponentStylesData; | ||
readonly dependencies: (typeof UI5Element)[]; | ||
cacheUniqueDependencies(this: typeof UI5Element): void; | ||
getUniqueDependencies(this: typeof UI5Element): (typeof UI5Element)[]; | ||
@@ -418,4 +440,3 @@ whenDependenciesDefined(): Promise<(typeof UI5Element)[]>; | ||
getMetadata(): import("../UI5ElementMetadata.js").default; | ||
decoratorMetadata: import("../UI5ElementMetadata.js").Metadata; | ||
}; | ||
export default getClassCopy; |
@@ -1,2 +0,2 @@ | ||
declare const _default: (value: string) => string[] | null; | ||
export default _default; | ||
declare const designTimePropertyAsArray: (value: string) => string[] | null; | ||
export default designTimePropertyAsArray; |
@@ -1,5 +0,6 @@ | ||
export default (value) => { | ||
const designTimePropertyAsArray = (value) => { | ||
const m = /\$([-a-z0-9A-Z._]+)(?::([^$]*))?\$/.exec(value); | ||
return m && m[2] ? m[2].split(/,/) : null; | ||
}; | ||
export default designTimePropertyAsArray; | ||
//# sourceMappingURL=getDesigntimePropertyAsArray.js.map |
@@ -1,2 +0,11 @@ | ||
declare const getSingletonElementInstance: (tag: string, parentElement?: HTMLElement) => Element; | ||
/** | ||
* Returns a singleton HTML element, inserted in given parent element of HTML page, | ||
* used mostly to store and share global resources between multiple UI5 Web Components runtimes. | ||
* | ||
* @param { string } tag the element tag/selector | ||
* @param { HTMLElement } parentElement the parent element to insert the singleton element instance | ||
* @param { Function } createEl a factory function for the element instantiation, by default document.createElement is used | ||
* @returns { Element } | ||
*/ | ||
declare const getSingletonElementInstance: (tag: string, parentElement?: HTMLElement, createEl?: () => Element) => Element; | ||
export default getSingletonElementInstance; |
@@ -1,2 +0,11 @@ | ||
const getSingletonElementInstance = (tag, parentElement = document.body) => { | ||
/** | ||
* Returns a singleton HTML element, inserted in given parent element of HTML page, | ||
* used mostly to store and share global resources between multiple UI5 Web Components runtimes. | ||
* | ||
* @param { string } tag the element tag/selector | ||
* @param { HTMLElement } parentElement the parent element to insert the singleton element instance | ||
* @param { Function } createEl a factory function for the element instantiation, by default document.createElement is used | ||
* @returns { Element } | ||
*/ | ||
const getSingletonElementInstance = (tag, parentElement = document.body, createEl) => { | ||
let el = document.querySelector(tag); | ||
@@ -6,3 +15,3 @@ if (el) { | ||
} | ||
el = document.createElement(tag); | ||
el = createEl ? createEl() : document.createElement(tag); | ||
return parentElement.insertBefore(el, parentElement.firstChild); | ||
@@ -9,0 +18,0 @@ }; |
@@ -64,3 +64,3 @@ import getSharedResource from "../getSharedResource.js"; | ||
const openUI5Support = getFeature("OpenUI5Support"); | ||
if (openUI5Support && openUI5Support.isLoaded()) { // use OpenUI5 for getting z-index values, if loaded | ||
if (openUI5Support && openUI5Support.isOpenUI5Detected()) { // use OpenUI5 for getting z-index values, if loaded | ||
return openUI5Support.getNextZIndex(); | ||
@@ -67,0 +67,0 @@ } |
@@ -16,8 +16,5 @@ const getMetaTagValue = (metaTagName) => { | ||
const validateThemeRoot = (themeRoot) => { | ||
let themeRootURL, resultUrl; | ||
let resultUrl; | ||
try { | ||
themeRootURL = new URL(themeRoot); | ||
const origin = themeRootURL.origin; | ||
themeRootURL = themeRootURL.toString(); | ||
if (themeRootURL.startsWith(".") || themeRootURL.startsWith("/")) { | ||
if (themeRoot.startsWith(".") || themeRoot.startsWith("/")) { | ||
// Handle relative url | ||
@@ -27,12 +24,16 @@ // new URL("/newExmPath", "http://example.com/exmPath") => http://example.com/newExmPath | ||
// new URL("../newExmPath", "http://example.com/exmPath") => http://example.com/newExmPath | ||
resultUrl = new URL(themeRootURL, window.location.href).toString(); | ||
resultUrl = new URL(themeRoot, window.location.href).toString(); | ||
} | ||
else if (origin && validateThemeOrigin(origin)) { | ||
// If origin is allowed, use it | ||
resultUrl = themeRootURL.toString(); | ||
} | ||
else { | ||
// If origin is not allow and the URL is not relative, we have to replace the origin | ||
// with current location | ||
resultUrl = buildCorrectUrl(themeRootURL, window.location.href); | ||
const themeRootURL = new URL(themeRoot); | ||
const origin = themeRootURL.origin; | ||
if (origin && validateThemeOrigin(origin)) { | ||
// If origin is allowed, use it | ||
resultUrl = themeRootURL.toString(); | ||
} | ||
else { | ||
// If origin is not allow and the URL is not relative, we have to replace the origin | ||
// with current location | ||
resultUrl = buildCorrectUrl(themeRootURL.toString(), window.location.href); | ||
} | ||
} | ||
@@ -39,0 +40,0 @@ if (!resultUrl.endsWith("/")) { |
226
index.js
@@ -0,4 +1,228 @@ | ||
// animations/ | ||
import scroll from "./dist/animations/scroll.js"; | ||
import slideDown from "./dist/animations/slideDown.js"; | ||
import slideUp from "./dist/animations/slideUp.js"; | ||
// config/ | ||
import { getAnimationMode, setAnimationMode } from "./dist/config/AnimationMode.js"; | ||
import { getCalendarType } from "./dist/config/CalendarType.js"; | ||
import { getFirstDayOfWeek, getLegacyDateCalendarCustomizing } from "./dist/config/FormatSettings.js"; | ||
import { | ||
setDefaultIconCollection, | ||
getDefaultIconCollection, | ||
} from "./dist/config/Icons.js"; | ||
import { RegisteredIconCollection } from "./dist/asset-registries/util/IconCollectionsByTheme.js"; | ||
import getEffectiveIconCollection from "./dist/asset-registries/util/getIconCollectionByTheme.js"; | ||
import { | ||
getLanguage, | ||
setLanguage, | ||
getDefaultLanguage, | ||
setFetchDefaultLanguage, | ||
getFetchDefaultLanguage, | ||
} from "./dist/config/Language.js"; | ||
import { getNoConflict, setNoConflict } from "./dist/config/NoConflict.js"; | ||
import { | ||
getTheme, | ||
setTheme, | ||
getDefaultTheme, | ||
} from "./dist/config/Theme.js"; | ||
// decorators/ | ||
import customElement from "./dist/decorators/customElement.js"; | ||
import event from "./dist/decorators/event.js"; | ||
import property from "./dist/decorators/property.js"; | ||
import slot from "./dist/decorators/slot.js"; | ||
// delegate/ | ||
import ItemNavigation from "./dist/delegate/ItemNavigation.js"; | ||
import ResizeHandler from "./dist/delegate/ResizeHandler.js"; | ||
import ScrollEnablement from "./dist/delegate/ScrollEnablement.js"; | ||
// locale/ | ||
import applyDirection from "./dist/locale/applyDirection.js"; | ||
import { attachDirectionChange, detachDirectionChange } from "./dist/locale/directionChange.js"; | ||
import getEffectiveDir from "./dist/locale/getEffectiveDir.js"; | ||
import { attachLanguageChange, detachLanguageChange } from "./dist/locale/languageChange.js"; | ||
// util/ | ||
import { URLListValidator, sanitizeHTML } from "./dist/util/HTMLSanitizer.js"; | ||
// Assets.ts | ||
import { registerI18nLoader } from "./dist/asset-registries/i18n.js"; | ||
import { registerLocaleDataLoader } from "./dist/asset-registries/LocaleData.js"; | ||
import { registerThemePropertiesLoader } from "./dist/asset-registries/Themes.js"; | ||
import { registerIconLoader } from "./dist/asset-registries/Icons.js"; | ||
// Boot.ts | ||
import { attachBoot } from "./dist/Boot.js"; | ||
// CSP.ts | ||
import { | ||
setPackageCSSRoot, | ||
setUseLinks, | ||
setPreloadLinks, | ||
} from "./dist/CSP.js"; | ||
// CustomElementsScope.ts | ||
import { | ||
setCustomElementsScopingSuffix, | ||
getCustomElementsScopingSuffix, | ||
setCustomElementsScopingRules, | ||
getCustomElementsScopingRules, | ||
getEffectiveScopingSuffixForTag, | ||
} from "./dist/CustomElementsScope.js"; | ||
// Device.ts | ||
import { | ||
supportsTouch, | ||
isIE, | ||
isSafari, | ||
isChrome, | ||
isFirefox, | ||
isPhone, | ||
isTablet, | ||
isDesktop, | ||
isCombi, | ||
isIOS, | ||
isAndroid, | ||
} from "./dist/Device.js"; | ||
// EventProvider.ts | ||
import EventProvider from "./dist/EventProvider.js"; | ||
// i18nBundle.ts | ||
import I18nBundle, { getI18nBundle, registerCustomI18nBundleGetter } from "./dist/i18nBundle.js"; | ||
// MediaRange.ts | ||
import MediaRange from "./dist/MediaRange.js"; | ||
// PropertiesFileFormat.ts | ||
import parseProperties from "./dist/PropertiesFileFormat.js"; | ||
// Render.ts | ||
import { | ||
renderDeferred, | ||
renderImmediately, | ||
cancelRender, | ||
renderFinished, | ||
} from "./dist/Render.js"; | ||
// Theming.ts | ||
import { addCustomCSS, attachThemeLoaded, detachThemeLoaded } from "./dist/Theming.js"; | ||
// UI5Element.ts | ||
import UI5Element from "./dist/UI5Element.js"; | ||
export default UI5Element; | ||
export { UI5Element }; | ||
export { | ||
// animations/ | ||
scroll, | ||
slideDown, | ||
slideUp, | ||
// config/ | ||
getAnimationMode, | ||
setAnimationMode, | ||
getCalendarType, | ||
getFirstDayOfWeek, | ||
getLegacyDateCalendarCustomizing, | ||
setDefaultIconCollection, | ||
getDefaultIconCollection, | ||
getEffectiveIconCollection, | ||
RegisteredIconCollection, | ||
getLanguage, | ||
setLanguage, | ||
getDefaultLanguage, | ||
setFetchDefaultLanguage, | ||
getFetchDefaultLanguage, | ||
getNoConflict, | ||
setNoConflict, | ||
getTheme, | ||
setTheme, | ||
getDefaultTheme, | ||
// decorators/ | ||
customElement, | ||
event, | ||
property, | ||
slot, | ||
// delegate/ | ||
ItemNavigation, | ||
ResizeHandler, | ||
ScrollEnablement, | ||
// locale/ | ||
applyDirection, | ||
attachDirectionChange, | ||
detachDirectionChange, | ||
getEffectiveDir, | ||
attachLanguageChange, | ||
detachLanguageChange, | ||
// util/ | ||
URLListValidator, | ||
sanitizeHTML, | ||
// Assets.ts | ||
registerI18nLoader, | ||
registerLocaleDataLoader, | ||
registerThemePropertiesLoader, | ||
registerIconLoader, | ||
// Boot.ts | ||
attachBoot, | ||
// CSP.ts | ||
setPackageCSSRoot, | ||
setUseLinks, | ||
setPreloadLinks, | ||
// CustomElementsScope.ts | ||
setCustomElementsScopingSuffix, | ||
getCustomElementsScopingSuffix, | ||
setCustomElementsScopingRules, | ||
getCustomElementsScopingRules, | ||
getEffectiveScopingSuffixForTag, | ||
// Device.ts | ||
supportsTouch, | ||
isIE, | ||
isSafari, | ||
isChrome, | ||
isFirefox, | ||
isPhone, | ||
isTablet, | ||
isDesktop, | ||
isCombi, | ||
isIOS, | ||
isAndroid, | ||
// EventProvider.ts | ||
EventProvider, | ||
// i18nBundle.ts | ||
I18nBundle, | ||
getI18nBundle, | ||
registerCustomI18nBundleGetter, | ||
// MediaRange.ts | ||
MediaRange, | ||
// PropertiesFileFormat.ts | ||
parseProperties, | ||
// Render.ts | ||
renderDeferred, | ||
renderImmediately, | ||
cancelRender, | ||
renderFinished, | ||
// Theming.ts | ||
addCustomCSS, | ||
attachThemeLoaded, | ||
detachThemeLoaded, | ||
// UI5Element.ts | ||
UI5Element, | ||
}; |
@@ -1,3 +0,3 @@ | ||
const fs = require('fs').promises; | ||
const assets = require('@ui5/webcomponents-tools/assets-meta.js'); | ||
import fs from "fs/promises"; | ||
import assets from "@ui5/webcomponents-tools/assets-meta.js"; | ||
@@ -7,2 +7,3 @@ const fileContent = `const assetParameters = ${JSON.stringify(assets)}; | ||
const DEFAULT_THEME = assetParameters.themes.default; | ||
const SUPPORTED_THEMES = assetParameters.themes.all; | ||
const DEFAULT_LANGUAGE = assetParameters.languages.default; | ||
@@ -14,2 +15,3 @@ const DEFAULT_LOCALE = assetParameters.locales.default; | ||
DEFAULT_THEME, | ||
SUPPORTED_THEMES, | ||
DEFAULT_LANGUAGE, | ||
@@ -21,4 +23,4 @@ DEFAULT_LOCALE, | ||
const generate = async () => { | ||
await fs.mkdir("dist/generated/", { recursive: true }); | ||
return fs.writeFile("dist/generated/AssetParameters.js", fileContent); | ||
await fs.mkdir("src/generated/", { recursive: true }); | ||
return fs.writeFile("src/generated/AssetParameters.ts", fileContent); | ||
} | ||
@@ -25,0 +27,0 @@ |
@@ -1,4 +0,4 @@ | ||
const fs = require('fs').promises; | ||
const path = require('path'); | ||
const CleanCSS = require('clean-css'); | ||
import fs from 'fs/promises'; | ||
import path from "path"; | ||
import CleanCSS from "clean-css"; | ||
@@ -5,0 +5,0 @@ const generate = async () => { |
@@ -1,2 +0,2 @@ | ||
const fs = require('fs').promises; | ||
import fs from "fs/promises"; | ||
@@ -26,4 +26,4 @@ const generate = async () => { | ||
await fs.mkdir("dist/generated/", { recursive: true }); | ||
await fs.writeFile("dist/generated/VersionInfo.js", fileContent); | ||
await fs.mkdir("src/generated/", { recursive: true }); | ||
await fs.writeFile("src/generated/VersionInfo.ts", fileContent); | ||
} | ||
@@ -30,0 +30,0 @@ |
{ | ||
"name": "@ui5/webcomponents-base", | ||
"version": "0.0.0-7d5f73b20", | ||
"version": "0.0.0-7d8c57f70", | ||
"description": "UI5 Web Components: webcomponents.base", | ||
"author": "SAP SE (https://www.sap.com)", | ||
"license": "Apache-2.0", | ||
"type": "module", | ||
"module": "index.js", | ||
@@ -19,2 +20,7 @@ "keywords": [ | ||
"exports": { | ||
"./dist/ssr-dom.js": { | ||
"browser": "./dist/ssr-dom.js", | ||
"node": "./dist/ssr-dom-shim.js", | ||
"default": "./dist/ssr-dom.js" | ||
}, | ||
".": "./index.js", | ||
@@ -31,13 +37,16 @@ "./dist/*": "./dist/*", | ||
"build": "nps build", | ||
"generate": "nps generate", | ||
"generateAPI": "nps generateAPI", | ||
"bundle": "nps build.bundle", | ||
"test": "nps test", | ||
"prepublishOnly": "npm run clean && npm run build" | ||
"prepublishOnly": "tsc -b" | ||
}, | ||
"dependencies": { | ||
"@lit-labs/ssr-dom-shim": "^1.1.2", | ||
"lit-html": "^2.0.1" | ||
}, | ||
"devDependencies": { | ||
"@buxlabs/amd-to-es6": "0.16.1", | ||
"@openui5/sap.ui.core": "1.109.0", | ||
"@ui5/webcomponents-tools": "0.0.0-7d5f73b20", | ||
"chromedriver": "109.0.0", | ||
"@ui5/webcomponents-tools": "0.0.0-7d8c57f70", | ||
"chromedriver": "^126.0.2", | ||
"@openui5/sap.ui.core": "1.120.17", | ||
"clean-css": "^5.2.2", | ||
@@ -44,0 +53,0 @@ "copy-and-watch": "^0.1.5", |
![UI5 icon](https://raw.githubusercontent.com/SAP/ui5-webcomponents/main/docs/images/UI5_logo_wide.png) | ||
# UI5 Web Components - Base | ||
@@ -40,2 +41,6 @@ | ||
### `IgnoreCustomElements.js` | ||
- `ignoreCustomElements` | ||
### `CSP.js` | ||
@@ -65,3 +70,3 @@ - `setPackageCSSRoot` | ||
## Support | ||
We welcome all comments, suggestions, questions, and bug reports. Please follow our [Support Guidelines](https://github.com/SAP/ui5-webcomponents/blob/main/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/). | ||
We welcome all comments, suggestions, questions, and bug reports. Please follow our [Support Guidelines](https://github.com/SAP/ui5-webcomponents/blob/main/SUPPORT.md#-content) on how to report an issue, or chat with us in the `#webcomponents` channel of the [OpenUI5 Community Slack](https://ui5-slack-invite.cfapps.eu10.hana.ondemand.com/). | ||
@@ -68,0 +73,0 @@ ## Contribute |
{ | ||
"include": ["src/**/*", "src/global.d.ts"], | ||
// ssr-dom is imported with bare specifier so that conditional exports are used, but this treats it as input and output | ||
"exclude": ["src/ssr-dom*.d.ts"], | ||
"compilerOptions": { | ||
"target": "ES2021", | ||
"lib": ["DOM", "DOM.Iterable", "ES2023"], | ||
// Generate d.ts files | ||
@@ -10,5 +13,9 @@ "declaration": true, | ||
"sourceMap": true, | ||
"inlineSources": true, | ||
"strict": true, | ||
"moduleResolution": "node", | ||
"composite": true, | ||
"rootDir": "src", | ||
"tsBuildInfoFile": "dist/.tsbuildinfo", | ||
}, | ||
} |
# Needed files from OpenUI5 | ||
# ./ui5loader-autoconfig.js | ||
sap/base/util/now.js | ||
sap/base/util/uid.js | ||
sap/base/Log.js | ||
# sap/base/config.js | ||
sap/base/config/MemoryConfigurationProvider.js | ||
sap/base/assert.js | ||
@@ -6,0 +10,0 @@ sap/base/security/URLListValidator.js |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
1699326
10
22897
77
3
Yes
2
513
+ Added@lit-labs/ssr-dom-shim@1.2.1(transitive)