diff --git a/packages/corelib/dist/index.d.ts b/packages/corelib/dist/index.d.ts index 4657621f47..3a270c4648 100644 --- a/packages/corelib/dist/index.d.ts +++ b/packages/corelib/dist/index.d.ts @@ -1684,6 +1684,20 @@ export interface PropertyItemsData { * @returns The hash or null if no such known registration */ export declare function getScriptDataHash(name: string, reload?: boolean): string; +/** + * Hook for script data related operations + */ +export declare const scriptDataHooks: { + /** + * Provides a hook to override the default fetchScriptData implementation, + * it falls back to the default implementation if undefined is returned. + * It is recommended to use this hook mainly for test purposes. + * If the sync parameter is true (legacy/compat), then the result should be returned synchronously. + * DynJS parameter is true if the script is requested to be loaded via a dynamic script, + * and not a JSON request. This parameter is only true for the legacy/compat sync mode. + */ + fetchScriptData: (name: string, sync?: boolean, dynJS?: boolean) => TData | Promise; +}; /** * Fetches a script data with given name via ~/DynamicData endpoint * @param name Dynamic script name diff --git a/packages/corelib/src/base/scriptdata.ts b/packages/corelib/src/base/scriptdata.ts index 32918d124a..b660c691c2 100644 --- a/packages/corelib/src/base/scriptdata.ts +++ b/packages/corelib/src/base/scriptdata.ts @@ -44,6 +44,21 @@ export function getScriptDataHash(name: string, reload?: boolean): string { return scriptDataHash[name]; } +/** + * Hook for script data related operations + */ +export const scriptDataHooks = { + /** + * Provides a hook to override the default fetchScriptData implementation, + * it falls back to the default implementation if undefined is returned. + * It is recommended to use this hook mainly for test purposes. + * If the sync parameter is true (legacy/compat), then the result should be returned synchronously. + * DynJS parameter is true if the script is requested to be loaded via a dynamic script, + * and not a JSON request. This parameter is only true for the legacy/compat sync mode. + */ + fetchScriptData: void 0 as (name: string, sync?: boolean, dynJS?: boolean) => TData | Promise +} + let fetchPromises: { [key: string]: Promise } = {} /** @@ -52,6 +67,12 @@ let fetchPromises: { [key: string]: Promise } = {} * @returns A promise that will return data if successfull */ export function fetchScriptData(name: string): Promise { + + const hookResult = scriptDataHooks.fetchScriptData?.(name); + if (hookResult != void 0) { + return Promise.resolve(hookResult); + } + let key = name + '?' + (getScriptDataHash(name) ?? ''); var promise: Promise = fetchPromises[key]; diff --git a/packages/corelib/src/q/scriptdata-compat.ts b/packages/corelib/src/q/scriptdata-compat.ts index 4874d4a231..2660de69e2 100644 --- a/packages/corelib/src/q/scriptdata-compat.ts +++ b/packages/corelib/src/q/scriptdata-compat.ts @@ -1,7 +1,7 @@ import { Lookup, getColumnsScript, getFormScript, getGlobalObject, getLookupAsync, getRemoteDataAsync, getScriptData, getScriptDataHash, handleScriptDataError, peekScriptData, reloadLookupAsync, requestFinished, requestStarting, - resolveUrl, setScriptData, type PropertyItem, type PropertyItemsData + resolveUrl, scriptDataHooks, setScriptData, type PropertyItem, type PropertyItemsData } from "../base"; export namespace ScriptData { @@ -24,6 +24,12 @@ export namespace ScriptData { if (data != null) return data; + data = scriptDataHooks.fetchScriptData?.(name, true, dynJS); + if (data !== void 0) { + set(name, data); + return data; + } + var url = resolveUrl(dynJS ? '~/DynJS.axd/' : '~/DynamicData/') + name + (dynJS ? '.js' : '') + '?v=' + (getScriptDataHash(name) ?? new Date().getTime()); var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); @@ -39,14 +45,13 @@ export namespace ScriptData { script.text = xhr.responseText; document.head.appendChild(script).parentNode.removeChild(script); data = peekScriptData(name); - if (data == null) - handleScriptDataError(name); } - - data = JSON.parse(xhr.responseText); + else { + data = JSON.parse(xhr.responseText); + } if (data == null) handleScriptDataError(name); - if (name.startsWith("Lookup.")) + if (!dynJS && name.startsWith("Lookup.")) data = new Lookup(data.Params, data.Items); set(name, data); return data;