UNPKG

jsf.js_next_gen

Version:

A next generation typescript reimplementation of jsf.js

264 lines 11.8 kB
"use strict"; /*! Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to you under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ExtLang = void 0; const mona_dish_1 = require("mona-dish"); const Messages_1 = require("../i18n/Messages"); const Const_1 = require("../core/Const"); const RequestDataResolver_1 = require("../xhrCore/RequestDataResolver"); const mona_dish_2 = require("mona-dish"); var ExtLang; (function (ExtLang) { let installedLocale; let nameSpace = "impl/util/Lang/"; function getLanguage() { //TODO global config override var _a, _b; let language = (_b = (_a = navigator.languages) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : navigator === null || navigator === void 0 ? void 0 : navigator.language; language = language.split("-")[0]; return language; } ExtLang.getLanguage = getLanguage; //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those /** * helper function to safely resolve anything * this is not an elvis operator, it resolves * a value without exception in a tree and if * it is not resolvable then an optional of * a default value is restored or Optional\.empty * if none is given * * usage * <code> * let var: Optional<string> = saveResolve(() => a.b.c.d.e, "foobaz") * </code> * * @param resolverProducer a lambda which can produce the value * @param defaultValue an optional default value if the producer fails to produce anything * @returns an Optional of the produced value */ function failSaveResolve(resolverProducer, defaultValue = null) { return mona_dish_1.Lang.saveResolve(resolverProducer, defaultValue); } ExtLang.failSaveResolve = failSaveResolve; /** * under some conditions it makes sense to swallow errors and return a default value in the error case * classical example the optional resolution of values in a chain (thankfully now covered by Typescript itself) * another example which we have in our system is that some operations fail only under test due to test framework * limitations while they cannot fail in the real world. * * @param resolverProducer a producer function which produces a value in the non error case * @param defaultValue the default value in case of a fail of the function */ function failSaveExecute(resolverProducer, defaultValue = null) { mona_dish_1.Lang.saveResolve(resolverProducer, defaultValue); } ExtLang.failSaveExecute = failSaveExecute; /** * returns a given localized message upon a given key * basic java log like templating functionality is included * * @param key the key for the message * @param defaultMessage optional default message if none was found * * Additionally, you can pass additional arguments, which are used * in the same way java log templates use the params * * @param templateParams the param list to be filled in */ function getMessage(key, defaultMessage, ...templateParams) { var _a, _b; installedLocale = installedLocale !== null && installedLocale !== void 0 ? installedLocale : new Messages_1.Messages(); let msg = (_b = (_a = installedLocale[key]) !== null && _a !== void 0 ? _a : defaultMessage) !== null && _b !== void 0 ? _b : key; templateParams.forEach((param, cnt) => { msg = msg.replace(new RegExp(["\\{", cnt, "\\}"].join(Const_1.EMPTY_STR), "g"), param); }); return msg; } ExtLang.getMessage = getMessage; /** * transforms a key value pair into a string * @param key the key * @param val the value * @param delimiter the delimiter */ function keyValToStr(key, val, delimiter = "\n") { return [key, val].join(delimiter); } ExtLang.keyValToStr = keyValToStr; /** * creates an exception with additional internal parameters * for extra information * * @param error * @param title the exception title * @param name the exception name * @param callerCls the caller class * @param callFunc the caller function * @param message the message for the exception */ function makeException(error, title, name, callerCls, callFunc, message) { var _a; return new Error((_a = message + (callerCls !== null && callerCls !== void 0 ? callerCls : nameSpace) + callFunc) !== null && _a !== void 0 ? _a : (Const_1.EMPTY_STR + arguments.caller.toString())); } ExtLang.makeException = makeException; /** * fetches a global config entry * @param configName the name of the configuration entry * @param defaultValue * * @return either the config entry or if none is given the default value */ function getGlobalConfig(configName, defaultValue) { var _a, _b, _c; /** * note we could use exists but this is a heavy operation, since the config name usually * given this function here is called very often * is a single entry without . in between we can do the lighter shortcut */ return (_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.myfaces) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b[configName]) !== null && _c !== void 0 ? _c : defaultValue; } ExtLang.getGlobalConfig = getGlobalConfig; /** * fetches the form in a fuzzy manner depending * on an element or event target. * * The idea is that according to the jsf spec * the enclosing form of the issuing element needs to be fetched. * * This is fine, but since then html5 came into the picture with the form attribute the element * can be anywhere referencing its parent form. * * Also, theoretically you can have the case of an issuing element enclosing a set of forms * (not really often used, but theoretically it could be input button allows to embed html for instance) * * So the idea is not to limit the issuing form determination to the spec case * but also cover the theoretical and html5 corner case. * * @param elem * @param event */ function getForm(elem, event) { let queryElem = new mona_dish_1.DQ(elem); let eventTarget = (event) ? new mona_dish_1.DQ((0, RequestDataResolver_1.getEventTarget)(event)) : mona_dish_1.DomQuery.absent; if (queryElem.isTag(Const_1.HTML_TAG_FORM)) { return queryElem; } //html 5 for handling if (queryElem.attr(Const_1.HTML_TAG_FORM).isPresent()) { let formId = queryElem.attr(Const_1.HTML_TAG_FORM).value; let foundForm = mona_dish_1.DQ.byId(formId, true); if (foundForm.isPresent()) { return foundForm; } } //no direct form is found we look for parent/child relationships as fallback //(90% case) let form = queryElem.firstParent(Const_1.HTML_TAG_FORM) .orElseLazy(() => queryElem.byTagName(Const_1.HTML_TAG_FORM, true)) .orElseLazy(() => eventTarget.firstParent(Const_1.HTML_TAG_FORM)) .orElseLazy(() => eventTarget.byTagName(Const_1.HTML_TAG_FORM)) .first(); //either a form is found within parent child - nearest form (aka first) //or we look for a single form form = form.orElseLazy(() => mona_dish_1.DQ.byTagName(Const_1.HTML_TAG_FORM)); //the end result must be a found form otherwise - Exception assertOnlyOneFormExists(form); return form; } ExtLang.getForm = getForm; /** * gets the local or global options with local ones having higher priority * if no local or global one was found then the default value is given back * * @param configName the name of the configuration entry * @param localOptions the local options root for the configuration myfaces as default marker is added * implicitly * * @param defaultValue * * @return either the config entry or if none is given the default value */ function getLocalOrGlobalConfig(localOptions, configName, defaultValue) { var _a, _b, _c, _d, _e, _f, _g; return (_g = (_d = (_c = (_b = (_a = localOptions.value) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.config) === null || _c === void 0 ? void 0 : _c[configName]) !== null && _d !== void 0 ? _d : (_f = (_e = window === null || window === void 0 ? void 0 : window.myfaces) === null || _e === void 0 ? void 0 : _e.config) === null || _f === void 0 ? void 0 : _f[configName]) !== null && _g !== void 0 ? _g : defaultValue; } ExtLang.getLocalOrGlobalConfig = getLocalOrGlobalConfig; /** * expands an associative array into an array of key value tuples * @param value */ function ofAssoc(value) { return new mona_dish_2.Es2019Array(...Object.keys(value)) .map(key => [key, value[key]]); } ExtLang.ofAssoc = ofAssoc; function collectAssoc(target, item) { target[item[0]] = item[1]; return target; } ExtLang.collectAssoc = collectAssoc; /** * The active timeout for the "debounce". * Since we only use it in the XhrController * we can use a local module variable here */ let activeTimeouts = {}; /** * a simple debounce function * which waits until a timeout is reached and * if something comes in in between debounces * * @param runnable a runnable which should go under debounce control * @param timeout a timeout for the debounce window */ function debounce(key, runnable, timeout) { function clearActiveTimeout() { clearTimeout(activeTimeouts[key]); delete activeTimeouts[key]; } if (!!(activeTimeouts === null || activeTimeouts === void 0 ? void 0 : activeTimeouts[key])) { clearActiveTimeout(); } if (timeout > 0) { activeTimeouts[key] = setTimeout(() => { try { runnable(); } finally { clearActiveTimeout(); } }, timeout); } else { runnable(); } } ExtLang.debounce = debounce; /** * assert that the form exists and only one form exists and throw an exception in the case it does not * * @param forms the form to check for */ function assertOnlyOneFormExists(forms) { if (forms.isAbsent() || forms.length > 1) { throw makeException(new Error(), null, null, "Impl", "getForm", getMessage("ERR_FORM")); } } })(ExtLang || (exports.ExtLang = ExtLang = {})); //# sourceMappingURL=Lang.js.map