diff --git a/dist/jaxon.core.js b/dist/jaxon.core.js index f33c09f..0a695fe 100644 --- a/dist/jaxon.core.js +++ b/dist/jaxon.core.js @@ -43,9 +43,9 @@ var jaxon = { event: {}, }, - call: { + parser: { attr: {}, - json: {}, + call: {}, query: {}, }, @@ -976,7 +976,7 @@ window.jaxon = jaxon; /** - * Class: jaxon.call.attr + * Class: jaxon.parser.attr * * Process Jaxon custom HTML attributes */ @@ -1090,27 +1090,16 @@ window.jaxon = jaxon; */ self.node = (sComponentName, sComponentItem = sDefaultComponentItem) => xComponentNodes[`${sComponentName}_${sComponentItem}`] ?? null; -})(jaxon.call.attr, jaxon.cmd.event); +})(jaxon.parser.attr, jaxon.cmd.event); /** - * Class: jaxon.call.json + * Class: jaxon.parser.call * * Execute calls from json expressions. */ (function(self, query, dialog, dom, form, types) { - /** - * @var {object} - */ - const xErrors = { - comparator: () => false, // The default comparison operator. - command: (xCall) => { - console.error('Unexpected command: ' + JSON.stringify({ call: xCall })); - return undefined; - }, - }; - /** * The comparison operators. * @@ -1127,49 +1116,6 @@ window.jaxon = jaxon; le: (xLeftArg, xRightArg) => xLeftArg <= xRightArg, }; - /** - * Check if an argument is an expression. - * - * @param {mixed} xArg - * - * @returns {boolean} - */ - const isValidCall = xArg => types.isObject(xArg) && (xArg._type); - - /** - * Get the value of a single argument. - * - * @param {mixed} xArg - * @param {mixed} xCurrValue The current expression value. - * - * @returns {mixed} - */ - const getValue = (xArg, xCurrValue) => { - if (!isValidCall(xArg)) { - return xArg; - } - const { _type: sType, _name: sName } = xArg; - switch(sType) { - case 'form': return form.getValues(sName); - case 'html': return dom.$(sName).innerHTML; - case 'input': return dom.$(sName).value; - case 'checked': return dom.$(sName).checked; - case 'expr': return execExpression(xArg, { target: window }); - case '_': return sName === 'this' ? xCurrValue : undefined; - default: return undefined; - } - }; - - /** - * Get the values of an array of arguments. - * - * @param {array} aArgs - * @param {mixed} xCurrValue The current expression value. - * - * @returns {array} - */ - const getArgs = (aArgs, xCurrValue) => aArgs.map(xArg => getValue(xArg, xCurrValue)); - /** * The call commands * @@ -1222,6 +1168,62 @@ window.jaxon = jaxon; }, }; + /** + * The function to call if one of the above is not found. + * + * @var {object} + */ + const xErrors = { + comparator: () => false, // The default comparison operator. + command: (xCall) => { + console.error('Unexpected command: ' + JSON.stringify({ call: xCall })); + return undefined; + }, + }; + + /** + * Check if an argument is an expression. + * + * @param {mixed} xArg + * + * @returns {boolean} + */ + const isValidCall = xArg => types.isObject(xArg) && !!xArg._type; + + /** + * Get the value of a single argument. + * + * @param {mixed} xArg + * @param {mixed} xCurrValue The current expression value. + * + * @returns {mixed} + */ + const getValue = (xArg, xCurrValue) => { + if (!isValidCall(xArg)) { + return xArg; + } + const { _type: sType, _name: sName } = xArg; + switch(sType) { + case 'form': return form.getValues(sName); + case 'html': return dom.$(sName).innerHTML; + case 'input': return dom.$(sName).value; + case 'checked': return dom.$(sName).checked; + case 'expr': return execExpression(xArg, { target: window }); + case '_': return sName === 'this' ? xCurrValue : undefined; + default: return undefined; + } + }; + + /** + * Get the values of an array of arguments. + * + * @param {array} aArgs + * @param {mixed} xCurrValue The current expression value. + * + * @returns {array} + */ + const getArgs = (aArgs, xCurrValue) => aArgs.map(xArg => getValue(xArg, xCurrValue)); + /** * Execute a single call. * @@ -1248,23 +1250,15 @@ window.jaxon = jaxon; /** * Execute the javascript code represented by an expression object. + * If a call returns "undefined", it will be the final return value. * * @param {array} aCalls The calls to execute * @param {object} oCallContext The context to execute calls in. * * @returns {mixed} */ - const execCalls = (aCalls, oCallContext) => { - let xCurrValue = undefined; - const nLength = aCalls.length; - for (let i = 0; i < nLength; i++) { - xCurrValue = execCall(aCalls[i], oCallContext, xCurrValue); - if (xCurrValue === undefined) { - return xCurrValue; // Exit the loop if a call returns an undefined value. - } - } - return xCurrValue; - }; + const execCalls = (aCalls, oCallContext) => aCalls.reduce((xValue, xCall) => + xValue === undefined ? undefined : execCall(xCall, oCallContext, xValue), null); /** * Replace placeholders in a given string with values @@ -1275,12 +1269,8 @@ window.jaxon = jaxon; * * @returns {string} */ - self.makePhrase = ({ str: sStr, args: aArgs }) => { - const oArgs = {}; - let nIndex = 1; - aArgs.forEach(xArg => oArgs[nIndex++] = getValue(xArg)); - return sStr.supplant(oArgs); - }; + self.makePhrase = ({ str, args }) => str.supplant(args.reduce((oArgs, xArg, nIndex) => + ({ ...oArgs, [nIndex + 1]: getValue(xArg) }), {})); /** * Show an alert message @@ -1289,46 +1279,34 @@ window.jaxon = jaxon; * * @returns {void} */ - const showMessage = (message) => { - if ((message)) { - const { - lib: sLibName, - type: sType, - content: { title: sTitle, phrase }, - } = message; - const xLib = dialog.get(sLibName); - xLib.alert(sType, self.makePhrase(phrase), sTitle); - } - }; + const showMessage = (message) => !!message && + dialog.alert({ ...message, text: self.makePhrase(message.phrase) }); /** + * @param {object} question The confirmation question + * @param {object} message The message to show if the user anwsers no to the question * @param {array} aCalls The calls to execute - * @param {array} aCondition The condition to chek - * @param {object} oMessage The message to show if the condition is not met * @param {object} oCallContext The context to execute calls in. * * @returns {boolean} */ - const execWithCondition = (aCalls, aCondition, oMessage, oCallContext) => { - const [sOperator, xLeftArg, xRightArg] = aCondition; - const xComparator = xComparators[sOperator] ?? xErrors.comparator; - xComparator(getValue(xLeftArg), getValue(xRightArg)) ? - execCalls(aCalls, oCallContext) : showMessage(oMessage); - }; + const execWithConfirmation = (question, message, aCalls, oCallContext) => + dialog.confirm({ ...question, text: self.makePhrase(question.phrase) }, + () => execCalls(aCalls, oCallContext), () => showMessage(message)); /** + * @param {array} aCondition The condition to chek + * @param {object} oMessage The message to show if the condition is not met * @param {array} aCalls The calls to execute - * @param {object} oQuestion The confirmation question - * @param {object} oMessage The message to show if the user anwsers no to the question * @param {object} oCallContext The context to execute calls in. * * @returns {boolean} */ - const execWithConfirmation = (aCalls, oQuestion, oMessage, oCallContext) => { - const { lib: sLibName, phrase } = oQuestion; - const xLib = dialog.get(sLibName); - xLib.confirm(self.makePhrase(phrase), '', - () => execCalls(aCalls, oCallContext), () => showMessage(oMessage)); + const execWithCondition = (aCondition, oMessage, aCalls, oCallContext) => { + const [sOperator, xLeftArg, xRightArg] = aCondition; + const xComparator = xComparators[sOperator] ?? xErrors.comparator; + xComparator(getValue(xLeftArg), getValue(xRightArg)) ? + execCalls(aCalls, oCallContext) : showMessage(oMessage); }; /** @@ -1342,11 +1320,11 @@ window.jaxon = jaxon; const execExpression = (xExpression, oCallContext) => { const { calls, question, condition, message } = xExpression; if((question)) { - execWithConfirmation(calls, question, message, oCallContext); + execWithConfirmation(question, message, calls, oCallContext); return; } if((condition)) { - execWithCondition(calls, condition, message, oCallContext); + execWithCondition(condition, message, calls, oCallContext); return; } return execCalls(calls, oCallContext); @@ -1358,16 +1336,16 @@ window.jaxon = jaxon; * @param {object} xExpression An object representing a command * @param {object=} oCallContext The context to execute calls in. * - * @returns {mixed} + * @returns {void} */ - self.execExpr = (xExpression, oCallContext) => !types.isObject(xExpression) ? null : + self.execExpr = (xExpression, oCallContext) => types.isObject(xExpression) && execExpression(xExpression, { target: window, ...oCallContext }); -})(jaxon.call.json, jaxon.call.query, jaxon.dialog.lib, jaxon.utils.dom, +})(jaxon.parser.call, jaxon.parser.query, jaxon.dialog.lib, jaxon.utils.dom, jaxon.utils.form, jaxon.utils.types); /** - * Class: jaxon.call.query + * Class: jaxon.parser.query */ (function(self, jq) { @@ -1391,7 +1369,200 @@ window.jaxon = jaxon; // Todo: Allow the use of an alternative library instead of jQuery. return !xContext ? self.jq(xSelector) : self.jq(xSelector, xContext); }; -})(jaxon.call.query, window.jQuery); +})(jaxon.parser.query, window.jQuery); + + +/** + * Class: jaxon.dialog.cmd + */ + +(function(self, lib, parser) { + /** + * Find a library to execute a given function. + * + * @param {string} sLibName The dialog library name + * @param {string} sFunc The dialog library function + * + * @returns {object} + */ + const getLib = (sLibName, sFunc) => { + !lib.has(sLibName) && + console.warn(`Unable to find a Jaxon dialog library with name "${sLibName}".`); + + const xLib = lib.get(sLibName); + !xLib[sFunc] && + console.error(`The chosen Jaxon dialog library doesn't implement the "${sFunc}" function.`); + + return xLib; + }; + + /** + * Add an event handler to the specified target. + * + * @param {object} command The Response command object. + * @param {string} command.lib The message library name + * @param {object} command.type The message type + * @param {string} command.title The message title + * @param {object} command.phrase The message content + * + * @returns {true} The operation completed successfully. + */ + self.showMessage = ({ lib: sLibName, type: sType, title: sTitle, phrase }) => { + const xLib = getLib(sLibName, 'alert'); + xLib.alert && xLib.alert(sType, parser.makePhrase(phrase), sTitle); + return true; + }; + + /** + * Remove an event handler from an target. + * + * @param {object} command The Response command object. + * @param {string} command.lib The dialog library name + * @param {object} command.dialog The dialog content + * @param {string} command.dialog.title The dialog title + * @param {string} command.dialog.content The dialog HTML content + * @param {array} command.dialog.buttons The dialog buttons + * @param {array} command.dialog.options The dialog options + * + * @returns {true} The operation completed successfully. + */ + self.showModal = ({ lib: sLibName, dialog: { title, content, buttons, options } }) => { + const xLib = getLib(sLibName, 'show'); + xLib.show && xLib.show(title, content, buttons, options); + return true; + }; + + /** + * Set an event handler with arguments to the specified target. + * + * @param {object} command The Response command object. + * @param {string} command.lib The dialog library name + * + * @returns {true} The operation completed successfully. + */ + self.hideModal = ({ lib: sLibName }) => { + const xLib = getLib(sLibName, 'hide'); + xLib.hide && xLib.hide(); + return true; + }; +})(jaxon.dialog.cmd, jaxon.dialog.lib, jaxon.parser.call); + + +/** + * Class: jaxon.dialog.lib + */ + +(function(self, types, dom, js, jq) { + /** + * Labels for confirm question. + * + * @var {object} + */ + const labels = { + yes: 'Yes', + no: 'No', + }; + + /** + * Dialog libraries. + * + * @var {object} + */ + const libs = {}; + + /** + * Check if a dialog library is defined. + * + * @param {string} sName The library name + * + * @returns {bool} + */ + self.has = (sName) => !!libs[sName]; + + /** + * Get a dialog library. + * + * @param {string=default} sName The library name + * + * @returns {object|null} + */ + self.get = (sName) => libs[sName] ?? libs.default; + + /** + * Show a message using a dialog library. + * + * @param {object} oMessage The message in the command + * @param {string} oMessage.lib The dialog library to use for the message + * @param {string} oMessage.type The message type + * @param {string} oMessage.text The message text + * @param {string=} oMessage.title The message title + * + * @returns {void} + */ + self.alert = ({ lib: sLibName, type: sType, title: sTitle = '', text: sMessage }) => + self.get(sLibName).alert(sType, sMessage, sTitle); + + /** + * Call a function after user confirmation. + * + * @param {object} oQuestion The question in the command + * @param {string} oQuestion.lib The dialog library to use for the question + * @param {string} oQuestion.text The question text + * @param {string=} oQuestion.title The question title + * @param {function} fYesCb The function to call if the question is confirmed + * @param {function} fNoCb The function to call if the question is not confirmed + * + * @returns {void} + */ + self.confirm = ({ lib: sLibName, title: sTitle = '', text: sQuestion }, fYesCb, fNoCb) => + self.get(sLibName).confirm(sQuestion, sTitle, fYesCb, fNoCb); + + /** + * Register a dialog library. + * + * @param {string} sName The library name + * @param {callback} xCallback The library definition callback + * + * @returns {void} + */ + self.register = (sName, xCallback) => { + // Create an object for the library + libs[sName] = {}; + // Define the library functions + xCallback(libs[sName], { types, dom, js, jq, labels }); + }; + + /** + * Default dialog plugin, based on js alert and confirm functions + */ + self.register('default', (lib) => { + /** + * Show an alert message + * + * @param {string} type The message type + * @param {string} text The message text + * @param {string} title The message title + * + * @returns {void} + */ + lib.alert = (type, text, title) => alert(!title ? text : `${title}
${text}`); + + /** + * Ask a confirm question to the user. + * + * @param {string} question The question to ask + * @param {string} title The question title + * @param {callback} yesCallback The function to call if the answer is yes + * @param {callback} noCallback The function to call if the answer is no + * + * @returns {void} + */ + lib.confirm = (question, title, yesCallback, noCallback) => { + confirm(!title ? question : `${title}
${question}`) ? + yesCallback() : (noCallback && noCallback()); + }; + }); +})(jaxon.dialog.lib, jaxon.utils.types, jaxon.dom, jaxon.parser.call, window.jQuery); /** @@ -1554,7 +1725,7 @@ window.jaxon = jaxon; * Class: jaxon.ajax.handler */ -(function(self, config, rsp, json, attr, queue, dom, dialog) { +(function(self, config, rsp, call, attr, queue, dom, dialog) { /** * An array that is used internally in the jaxon.fn.handler object to keep track * of command handlers that have been registered. @@ -1718,22 +1889,27 @@ window.jaxon = jaxon; * @param {integer} args.count The number of commands to skip. * @param {object} args.question The question to ask. * @param {string} args.question.lib The dialog library to use. + * @param {object} args.question.title The question title. * @param {object} args.question.phrase The question content. * @param {object} command The Response command object. * @param {object} command.commandQueue The command queue. * * @returns {true} The queue processing is temporarily paused. */ - self.confirm = ({ count: skipCount, question: { lib: sLibName, phrase } }, { commandQueue }) => { + self.confirm = ({ + count: skipCount, + question: { lib: sLibName, title: sTitle, phrase }, + }, { commandQueue }) => { // The command queue is paused, and will be restarted after the confirm question is answered. - commandQueue.paused = true; const xLib = dialog.get(sLibName); - xLib.confirm(json.makePhrase(phrase), '', () => restartProcessing(commandQueue), + commandQueue.paused = true; + xLib.confirm(call.makePhrase(phrase), sTitle, + () => restartProcessing(commandQueue), () => restartProcessing(commandQueue, skipCount)); return true; }; -})(jaxon.ajax.handler, jaxon.config, jaxon.ajax.response, jaxon.call.json, - jaxon.call.attr, jaxon.utils.queue, jaxon.utils.dom, jaxon.dialog.lib); +})(jaxon.ajax.handler, jaxon.config, jaxon.ajax.response, jaxon.parser.call, + jaxon.parser.attr, jaxon.utils.queue, jaxon.utils.dom, jaxon.dialog.lib); /** @@ -2532,7 +2708,7 @@ window.jaxon = jaxon; * Class: jaxon.cmd.event */ -(function(self, json, dom, str) { +(function(self, call, dom, str) { /** * Add an event handler to the specified target. * @@ -2574,9 +2750,8 @@ window.jaxon = jaxon; * * @returns {void} */ - const callEventHandler = (event, target, func) => { - json.execExpr({ _type: 'expr', ...func }, { event, target }); - }; + const callEventHandler = (event, target, func) => + call.execExpr({ _type: 'expr', ...func }, { event, target }); /** * Add an event handler with arguments to the specified target. @@ -2611,14 +2786,14 @@ window.jaxon = jaxon; target[str.addOnPrefix(sEvent)] = (evt) => callEventHandler(evt, target, func); return true; }; -})(jaxon.cmd.event, jaxon.call.json, jaxon.utils.dom, jaxon.utils.string); +})(jaxon.cmd.event, jaxon.parser.call, jaxon.utils.dom, jaxon.utils.string); /** * Class: jaxon.cmd.script */ -(function(self, json, parameters, types) { +(function(self, call, parameters, types) { /** * Call a javascript function with a series of parameters using the current script context. * @@ -2631,7 +2806,7 @@ window.jaxon = jaxon; * @returns {true} The operation completed successfully. */ self.call = ({ func, args }, { context = {} }) => { - json.execCall({ _type: 'func', _name: func, args }, context); + call.execCall({ _type: 'func', _name: func, args }, context); return true; }; @@ -2644,7 +2819,7 @@ window.jaxon = jaxon; * @returns {true} The operation completed successfully. */ self.exec = ({ expr }) => { - json.execExpr(expr); + call.execExpr(expr); return true; }; @@ -2688,7 +2863,7 @@ window.jaxon = jaxon; * @returns {true} The operation completed successfully. */ self.jquery = ({ selector }) => { - json.execExpr(selector); + call.execExpr(selector); return true; }; @@ -2717,178 +2892,14 @@ window.jaxon = jaxon; self.paginate = ({ target, func: oCall }) => { const aLinks = target.querySelectorAll(`li.enabled > a`); const { args: aArgs } = oCall; - aLinks.forEach(oLink => oLink.addEventListener('click', () => json.execCall({ + aLinks.forEach(oLink => oLink.addEventListener('click', () => call.execCall({ ...oCall, _type: 'func', args: getCallArgs(aArgs, oLink), }))); return true; }; -})(jaxon.cmd.script, jaxon.call.json, jaxon.ajax.parameters, jaxon.utils.types); - - -/** - * Class: jaxon.dialog.cmd - */ - -(function(self, lib, json) { - /** - * Find a library to execute a given function. - * - * @param {string} sLibName The dialog library name - * @param {string} sFunc The dialog library function - * - * @returns {object|null} - */ - const getLib = (sLibName, sFunc) => { - if(!lib.has(sLibName)) { - console.warn(`Unable to find a Jaxon dialog library with name "${sLibName}".`); - } - - const xLib = lib.get(sLibName); - if(!xLib[sFunc]) { - console.error(`The chosen Jaxon dialog library doesn't implement the "${sFunc}" function.`); - return null; - } - return xLib; - }; - - /** - * Add an event handler to the specified target. - * - * @param {object} command The Response command object. - * @param {string} command.lib The message library name - * @param {object} command.type The message type - * @param {string} command.content The message content - * @param {string} command.content.title The message title - * @param {string} command.content.phrase.str The message text with placeholders - * @param {array} command.content.phrase.args The arguments for placeholders - * - * @returns {true} The operation completed successfully. - */ - self.showMessage = ({ lib: sLibName, type: sType, content }) => { - const { title: sTitle, phrase } = content; - const xLib = getLib(sLibName, 'alert'); - xLib && xLib.alert(sType, json.makePhrase(phrase), sTitle); - return true; - }; - - /** - * Remove an event handler from an target. - * - * @param {object} command The Response command object. - * @param {string} command.lib The dialog library name - * @param {object} command.dialog The dialog content - * @param {string} command.dialog.title The dialog title - * @param {string} command.dialog.content The dialog HTML content - * @param {array} command.dialog.buttons The dialog buttons - * @param {array} command.dialog.options The dialog options - * - * @returns {true} The operation completed successfully. - */ - self.showModal = ({ lib: sLibName, dialog: { title, content, buttons, options } }) => { - const xLib = getLib(sLibName, 'show'); - xLib && xLib.show(title, content, buttons, options); - return true; - }; - - /** - * Set an event handler with arguments to the specified target. - * - * @param {object} command The Response command object. - * @param {string} command.lib The dialog library name - * - * @returns {true} The operation completed successfully. - */ - self.hideModal = ({ lib: sLibName }) => { - const xLib = getLib(sLibName, 'hide'); - xLib && xLib.hide(); - return true; - }; -})(jaxon.dialog.cmd, jaxon.dialog.lib, jaxon.call.json); - - -/** - * Class: jaxon.dialog.lib - */ - -(function(self, types, dom, js, jq) { - const labels = { - yes: 'Yes', - no: 'No', - }; - - self.default = {}; - - /** - * Check if a dialog library is defined. - * - * @param {string} sName The library name - * - * @returns {bool} - */ - self.has = (sName) => !!self[sName]; - - /** - * Get a dialog library. - * - * @param {string=default} sName The library name - * - * @returns {object|null} - */ - self.get = (sName) => self[sName] ?? self.default; - - /** - * Register a dialog library. - * - * @param {string} sName The library name - * @param {callback} xCallback The library definition callback - * - * @returns {void} - */ - self.register = (sName, xCallback) => { - // Create an object for the library - self[sName] = {}; - // Define the library functions - xCallback(self[sName], { types, dom, js, jq, labels }); - }; - - /** - * Default dialog plugin, based on js alert and confirm functions - * Class: jaxon.dialog.lib.default - */ - - self.register('default', (lib) => { - /** - * Show an alert message - * - * @param {string} type The message type - * @param {string} text The message text - * @param {string} title The message title - * - * @returns {void} - */ - lib.alert = (type, text, title) => alert(!title ? text : `${title}
${text}`); - - /** - * Ask a confirm question to the user. - * - * @param {string} question The question to ask - * @param {string} title The question title - * @param {callback} yesCallback The function to call if the answer is yes - * @param {callback} noCallback The function to call if the answer is no - * - * @returns {void} - */ - lib.confirm = (question, title, yesCallback, noCallback) => { - if(confirm(!title ? question : `${title}
${question}`)) { - yesCallback(); - return; - } - noCallback && noCallback(); - }; - }); -})(jaxon.dialog.lib, jaxon.utils.types, jaxon.dom, jaxon.call.json, window.jQuery); +})(jaxon.cmd.script, jaxon.parser.call, jaxon.ajax.parameters, jaxon.utils.types); /* @@ -2919,12 +2930,22 @@ jaxon.$ = jaxon.utils.dom.$; /** * Shortcut to the JQuery selector function>. */ -jaxon.jq = jaxon.call.query.jq; +jaxon.jq = jaxon.parser.query.jq; + +/** + * Shortcut to . + */ +jaxon.exec = jaxon.parser.call.execExpr; + +/** + * Shortcut to . + */ +jaxon.confirm = jaxon.dialog.lib.confirm; /** - * Shortcut to . + * Shortcut to . */ -jaxon.exec = jaxon.call.json.execExpr; +jaxon.alert = jaxon.dialog.lib.alert; /** * Shortcut to . @@ -2942,9 +2963,9 @@ jaxon.getFormValues = jaxon.utils.form.getValues; jaxon.setBag = jaxon.ajax.parameters.setBag; /** - * Shortcut to . + * Shortcut to . */ -jaxon.processCustomAttrs = () => jaxon.call.attr.process(); +jaxon.processCustomAttrs = () => jaxon.parser.attr.process(); /** * Indicates if jaxon module is loaded. diff --git a/dist/jaxon.core.min.js b/dist/jaxon.core.min.js index c3ee4c8..1cbe471 100644 --- a/dist/jaxon.core.min.js +++ b/dist/jaxon.core.min.js @@ -6,4 +6,4 @@ @copyright Copyright (c) 2017 by Thierry Feuzeu, Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson @license https://opensource.org/license/bsd-3-clause/ BSD License */ -var jaxon={version:{major:"5",minor:"0",patch:"0rc-10"},debug:{verbose:{}},ajax:{callback:{},handler:{},parameters:{},request:{},response:{}},cmd:{body:{},script:{},event:{}},call:{attr:{},json:{},query:{}},utils:{dom:{},form:{},queue:{},types:{},string:{},upload:{}},dom:{},dialog:{cmd:{},lib:{}},config:{}};!function(e){e.commonHeaders={"If-Modified-Since":"Sat, 1 Jan 2000 00:00:00 GMT"},e.postHeaders={},e.getHeaders={},e.waitCursor=!1,e.statusMessages=!1,e.baseDocument=document,e.requestURI=document.URL,e.defaultMode="asynchronous",e.defaultHttpVersion="HTTP/1.1",e.defaultContentType="application/x-www-form-urlencoded",e.defaultResponseDelayTime=1e3,e.convertResponseToJson=!0,e.defaultExpirationTime=1e4,e.defaultMethod="POST",e.defaultRetry=5,e.defaultReturnValue=!1,e.maxObjectDepth=20,e.maxObjectSize=2e3,e.commandQueueSize=1e3,e.requestQueueSize=1e3,e.httpRequestOptions={mode:"cors",cache:"no-cache",credentials:"same-origin",redirect:"manual"},e.setRequestOptions=t=>{if(void 0===e.requestURI)throw{code:10005};["commonHeaders","postHeaders","getHeaders"].forEach((n=>t[n]={...e[n],...t[n]}));const n={statusMessages:e.statusMessages,waitCursor:e.waitCursor,mode:e.defaultMode,method:e.defaultMethod,URI:e.requestURI,httpVersion:e.defaultHttpVersion,contentType:e.defaultContentType,convertResponseToJson:e.convertResponseToJson,retry:e.defaultRetry,returnValue:e.defaultReturnValue,maxObjectDepth:e.maxObjectDepth,maxObjectSize:e.maxObjectSize,context:window,upload:!1,aborted:!1};Object.keys(n).forEach((e=>t[e]=t[e]??n[e])),t.method=t.method.toUpperCase(),"GET"!==t.method&&(t.method="POST"),t.requestRetry=t.retry},e.status={update:{onRequest:()=>console.log("Sending Request..."),onWaiting:()=>console.log("Waiting for Response..."),onProcessing:()=>console.log("Processing..."),onComplete:()=>console.log("Done.")},dontUpdate:{onRequest:()=>{},onWaiting:()=>{},onProcessing:()=>{},onComplete:()=>{}}},e.cursor={update:{onWaiting:()=>{jaxon.config.baseDocument.body&&(jaxon.config.baseDocument.body.style.cursor="wait")},onComplete:()=>{jaxon.config.baseDocument.body&&(jaxon.config.baseDocument.body.style.cursor="auto")}},dontUpdate:{onWaiting:()=>{},onComplete:()=>{}}}}(jaxon.config),window.jaxon=jaxon,function(e,t,n){e.$=e=>e?t.isString(e)?n.getElementById(e):e:null;e.getBrowserHTML=t=>{const o=(()=>{const t=e.$("jaxon_temp_workspace");if(t)return t;if(!n.body)return null;const o=n.createElement("div");return o.setAttribute("id","jaxon_temp_workspace"),o.style.display="none",o.style.visibility="hidden",n.body.appendChild(o),o})();o.innerHTML=t;const r=o.innerHTML;return o.innerHTML="",r},e.willChange=(t,n,o)=>!!(t=e.$(t))&&o!=t[n],e.removeElement=t=>{(t=e.$(t))&&t.parentNode&&t.parentNode.removeChild&&t.parentNode.removeChild(t)},e.findFunction=(e,n=window)=>{if("toInt"===e&&n===window)return t.toInt;const o=e.split("."),r=o.length;for(let e=0;e{const n=e.split(".");e=n.pop();const o=n.length;for(let e=0;e{t.forEach((t=>{const{childNodes:o,type:r}=t;void 0!==o&&"select-one"!==r&&"select-multiple"!==r&&n(e,o),((e,{type:t,name:n,tagName:o,checked:r,disabled:a,value:s,options:c})=>{if(!n||"PARAM"===o)return;if(!e.disabled&&a)return;const{prefix:i}=e;if(i.length>0&&i!==n.substring(0,i.length))return;if(("radio"===t||"checkbox"===t)&&!r)return;if("file"===t)return;const l="select-multiple"!==t?s:c.filter((({selected:e})=>e)).map((({value:e})=>e)),u=n.indexOf("[");if(u<0)return void(e.values[n]=l);let d=n.substring(0,u),p=n.substring(u);void 0===e.values[d]&&(e.values[d]={});let m=e.values;for(;p.length>0;){const e=p.substring(0,p.indexOf("]")+1),n=d,o=m;p=p.substring(p.indexOf("]")+1),m=m[d],d=e.substring(1,e.length-1),""===d&&("select-multiple"===t?(d=n,m=o):d=m.length),void 0===d&&(d=Object.keys(o[n]).length),m[d]=m[d]||{}}m[d]=l})(e,t)}))};e.getValues=(e,o=!1,r="")=>{const a={disabled:!0===o,prefix:r??"",values:{}},s=t.$(e);return s&&s.childNodes&&n(a,s.childNodes),a.values}}(jaxon.utils.form,jaxon.utils.dom),function(e){e.create=e=>({start:0,count:0,size:e,end:0,elements:[],paused:!1}),e.empty=e=>e.count<=0,e.full=e=>e.count>=e.size,e.push=(t,n)=>{if(e.full(t))throw{code:10003};return t.elements[t.end]=n,++t.end>=t.size&&(t.end=0),++t.count},e.pushFront=(t,n)=>{if(e.full(t))throw{code:10003};return e.empty(t)?e.push(t,n):(--t.start<0&&(t.start=t.size-1),t.elements[t.start]=n,++t.count)},e.pop=t=>{if(e.empty(t))return null;let n=t.elements[t.start];return delete t.elements[t.start],++t.start>=t.size&&(t.start=0),t.count--,n},e.peek=t=>e.empty(t)?null:t.elements[t.start]}(jaxon.utils.queue),function(e){"use strict";let t=[],n=!1,o=!1;const r=()=>{n||(n=!0,t.forEach((e=>e.fn.call(window,e.ctx))),t=[])};e.ready=function(e,a){n?setTimeout((function(){e(a)}),1):(t.push({fn:e,ctx:a}),"complete"===document.readyState||!document.attachEvent&&"interactive"===document.readyState?setTimeout(r,1):o||(document.addEventListener("DOMContentLoaded",r,!1),window.addEventListener("load",r,!1),o=!0))}}(jaxon.utils.dom),function(e){e.doubleQuotes=e=>void 0!==e&&e.replace(new RegExp("'","g"),'"'),e.singleQuotes=e=>void 0!==e&&e.replace(new RegExp('"',"g"),"'"),e.stripOnPrefix=e=>0===(e=e.toLowerCase()).indexOf("on")?e.replace(/on/,""):e,e.addOnPrefix=e=>0!==(e=e.toLowerCase()).indexOf("on")?"on"+e:e,String.prototype.supplant||(String.prototype.supplant=function(e){return this.replace(/\{([^{}]*)\}/g,((t,n)=>{const o=e[n],r=typeof o;return"string"===r||"number"===r?o:t}))})}(jaxon.utils.string),function(e){e.of=e=>Object.prototype.toString.call(e).slice(8,-1).toLowerCase(),e.isObject=t=>"object"===e.of(t),e.isArray=t=>"array"===e.of(t),e.isString=t=>"string"===e.of(t),e.isFunction=t=>"function"===e.of(t),e.toInt=e=>parseInt(e),Array.prototype.top||(Array.prototype.top=function(){return this.length>0?this[this.length-1]:void 0})}(jaxon.utils.types),function(e,t,n){e.initialize=e=>{(e=>{if(!e.upload)return!1;e.upload={id:e.upload,input:null,form:null};const o=t.$(e.upload.id);return o?"file"!==o.type?(n.log("The upload input field with id "+e.upload.id+" is not of type file"),!1):0===o.files.length?(n.log("There is no file selected for upload in input field with id "+e.upload.id),!1):void 0===o.name?(n.log("The upload input field with id "+e.upload.id+" has no name attribute"),!1):(e.upload.input=o,e.upload.form=o.form,!0):(n.log("Unable to find input field for file upload with id "+e.upload.id),!1)})(e)||(e.postHeaders["content-type"]=e.contentType)}}(jaxon.utils.upload,jaxon.utils.dom,console),function(e,t){const n={},o="main",r=["dom.assign","dom.append","dom.prepend","dom.replace"],a=["innerHTML","outerHTML"];e.changed=(e,t,n)=>e&&a.some((e=>e===n))&&r.some((e=>e===t));e.process=(e=document)=>{e.querySelectorAll(":scope [jxn-on]").forEach((e=>{e.hasAttribute("jxn-func")&&(e=>{const n=e.getAttribute("jxn-on"),o=JSON.parse(e.getAttribute("jxn-func"));if(!e.hasAttribute("jxn-select"))return void t.setEventHandler({target:e,event:n,func:o});const r=e.getAttribute("jxn-select");e.querySelectorAll(`:scope ${r}`).forEach((e=>{t.setEventHandler({target:e,event:n,func:o})}))})(e),e.removeAttribute("jxn-on"),e.removeAttribute("jxn-func"),e.removeAttribute("jxn-select")}));e.querySelectorAll(":scope [jxn-component]").forEach((e=>{const t=e.getAttribute("jxn-component"),r=e.getAttribute("jxn-item")??o;n[`${t}_${r}`]=e,e.removeAttribute("jxn-component")}))},e.node=(e,t=o)=>n[`${e}_${t}`]??null}(jaxon.call.attr,jaxon.cmd.event),function(e,t,n,o,r,a){const s={comparator:()=>!1,command:e=>{console.error("Unexpected command: "+JSON.stringify({call:e}))}},c={eq:(e,t)=>e==t,teq:(e,t)=>e===t,ne:(e,t)=>e!=t,nte:(e,t)=>e!==t,gt:(e,t)=>e>t,ge:(e,t)=>e>=t,lt:(e,t)=>ee<=t},i=e=>a.isObject(e)&&e._type,l=(e,t)=>{if(!i(e))return e;const{_type:n,_name:a}=e;switch(n){case"form":return r.getValues(a);case"html":return o.$(a).innerHTML;case"input":return o.$(a).value;case"checked":return o.$(a).checked;case"expr":return f(e,{target:window});case"_":return"this"===a?t:void 0;default:return}},u=(e,t)=>e.map((e=>l(e,t))),d={select:({_name:e,context:n=null},o)=>{switch(e){case"this":return t.select(o.target);case"event":return o.event;case"window":return window;default:return t.select(e,n)}},event:({_name:e,func:t},n,o)=>(o.on(e,(e=>f(t,{...n,event:e,target:e.currentTarget}))),o),func:({_name:e,args:t=[]},n,r)=>{const a=o.findFunction(e);return a?a.apply(n,u(t,r)):void 0},method:({_name:e,args:t=[]},n,r)=>{const s=o.findFunction(e,r);return s?s.apply(r,u(t,r)):"toInt"===e?a.toInt(r):void 0},attr:({_name:e,value:t},n,r)=>{const a=o.getInnerObject(e,r||n.target);if(a)return void 0!==t&&(a.node[a.attr]=l(t,r)),a.node[a.attr]}},p=(e,t,n)=>(i(e)?d[e._type]:s.command)(e,t,n);e.execCall=(e,t)=>p(e,{target:window,...t});const m=(e,t)=>{let n;const o=e.length;for(let r=0;r{const n={};let o=1;return t.forEach((e=>n[o++]=l(e))),e.supplant(n)};const x=t=>{if(t){const{lib:o,type:r,content:{title:a,phrase:s}}=t;n.get(o).alert(r,e.makePhrase(s),a)}},f=(t,o)=>{const{calls:r,question:a,condition:i,message:u}=t;if(a)((t,o,r,a)=>{const{lib:s,phrase:c}=o;n.get(s).confirm(e.makePhrase(c),"",(()=>m(t,a)),(()=>x(r)))})(r,a,u,o);else{if(!i)return m(r,o);((e,t,n,o)=>{const[r,a,i]=t;(c[r]??s.comparator)(l(a),l(i))?m(e,o):x(n)})(r,i,u,o)}};e.execExpr=(e,t)=>a.isObject(e)?f(e,{target:window,...t}):null}(jaxon.call.json,jaxon.call.query,jaxon.dialog.lib,jaxon.utils.dom,jaxon.utils.form,jaxon.utils.types),function(e,t){e.jq=t,e.select=(t,n=null)=>n?e.jq(t,n):e.jq(t)}(jaxon.call.query,window.jQuery),function(e,t,n){const o=e=>({timer:null,delay:e}),r=["onInitialize","onProcessParams","onPrepare","onRequest","onResponseDelay","onExpiration","beforeResponseProcessing","onFailure","onRedirect","onSuccess","onComplete"];e.create=(e,t)=>{const a={timers:{onResponseDelay:o(e??n.defaultResponseDelayTime),onExpiration:o(t??n.defaultExpirationTime)}};return r.forEach((e=>a[e]=null)),a},e.callback=e.create(),e.initCallbacks=n=>{if(t.isObject(n.callback)&&(n.callback=[n.callback]),t.isArray(n.callback))return void n.callback.forEach((e=>{void 0===e.timers&&(e.timers={})}));let o=!1;const a=e.create();r.forEach((e=>{void 0!==n[e]&&(a[e]=n[e],o=!0,delete n[e])})),n.callback=o?[a]:[]};const a=({callback:t=[]})=>[e.callback,...t];e.execute=(e,n)=>a(e).forEach((o=>((e,n,o)=>{const r=e[n];if(!r||!t.isFunction(r))return;const a=e.timers[n];a?a.timer=setTimeout((()=>r(o)),a.delay):r(o)})(o,n,e)));e.clearTimer=(e,t)=>a(e).forEach((e=>((e,t)=>{const n=e.timers[t];void 0!==n&&null!==n.timer&&clearTimeout(n.timer)})(e,t)))}(jaxon.ajax.callback,jaxon.utils.types,jaxon.config),function(e,t,n,o,r,a,s,c){const i={};e.q={send:a.create(t.requestQueueSize),recv:a.create(2*t.requestQueueSize)},e.register=(e,t,n="")=>i[e]={desc:n,func:t},e.unregister=e=>{const t=i[e];return t?(delete i[e],t.func):null},e.isRegistered=({name:e})=>void 0!==e&&void 0!==i[e];e.execute=t=>{const{name:n,args:o={}}=t;if(!e.isRegistered({name:n}))return!0;const a=o.component?.name;a&&(o.target=r.node(a,o.component.item));const c=o.id;!o.target&&c&&(o.target=s.$(c));const l=((e,t,n)=>{const{func:o,desc:r}=i[e];return o(t,{...n,desc:r})})(n,o,t);return r.changed(o.target,n,o.attr)&&r.process(o.target),l},e.popAsyncRequest=e=>a.empty(e)||"synchronous"===a.peek(e).mode?null:a.pop(e),e.sleep=({duration:e},{commandQueue:t})=>(t.paused=!0,setTimeout((()=>{t.paused=!1,n.processCommands(t)}),100*e),!0);const l=(e,t=0)=>{for(;t>0&&e.count>1&&null!==a.pop(e);)--t;e.paused=!1,n.processCommands(e)};e.confirm=({count:e,question:{lib:t,phrase:n}},{commandQueue:r})=>{r.paused=!0;return c.get(t).confirm(o.makePhrase(n),"",(()=>l(r)),(()=>l(r,e))),!0}}(jaxon.ajax.handler,jaxon.config,jaxon.ajax.response,jaxon.call.json,jaxon.call.attr,jaxon.utils.queue,jaxon.utils.dom,jaxon.dialog.lib),function(e,t,n){const o={};e.setBag=(e,t)=>o[e]=t,e.setBags=t=>Object.keys(t).forEach((n=>e.setBag(n,t[n]))),e.clearBag=e=>delete o[e];const r=({func:e,parameters:r,bags:a=[]},s)=>{const c=new Date;var i;s("jxnr",c.getTime()),s("jxnv",`${n.major}.${n.minor}.${n.patch}`),Object.keys(e).forEach((t=>s(t,encodeURIComponent(e[t])))),[...r].forEach((e=>s("jxnargs[]",(e=>{if(null==e)return"*";const n=t.of(e);if("object"===n||"array"===n)try{return encodeURIComponent(JSON.stringify(e))}catch(t){e=""}return e=encodeURIComponent(e),"string"===n?"S"+e:"boolean"===n?"B"+e:"number"===n?"N"+e:e})(e)))),a.length>0&&s("jxnbags",encodeURIComponent((i=a,JSON.stringify(i.reduce(((e,t)=>({...e,[t]:o[t]??"*"})),{})))))};e.process=e=>{e.requestURI=e.URI,e.requestData=(({upload:e})=>e&&e.ajax&&e.input)(e)?(e=>{const t=new FormData;r(e,((e,n)=>t.append(e,n)));const n=e.upload.input;return n.files&&n.files.forEach((e=>t.append(n.name,e))),t})(e):(e=>{const t=[];return r(e,((e,n)=>t.push(e+"="+n))),"POST"===e.method?t.join("&"):(e.requestURI+=(-1===e.requestURI.indexOf("?")?"?":"&")+t.join("&"),"")})(e)}}(jaxon.ajax.parameters,jaxon.utils.types,jaxon.version),function(e,t,n,o,r,a,s,c){const i=e=>{--e.requestRetry,r.execute(e,"onPrepare"),e.httpRequestOptions={...t.httpRequestOptions,method:e.method,headers:{...e.commonHeaders,..."POST"===e.method?e.postHeaders:e.getHeaders},body:e.requestData},e.responseConverter=t=>(e.response=t,e.convertResponseToJson?t.json():t.text()),e.responseHandler=t=>{e.responseContent=t,c.empty(a.q.send)||"synchronous"===e.mode?o.received(e):c.push(a.q.recv,e)},e.errorHandler=t=>{throw r.execute(e,"onFailure"),t},e.responseProcessor||(e.responseProcessor=o.jsonProcessor)},l=e=>(e.status.onRequest(),r.execute(e,"onResponseDelay"),r.execute(e,"onExpiration"),r.execute(e,"onRequest"),e.cursor.onWaiting(),e.status.onWaiting(),fetch(e.requestURI,e.httpRequestOptions).then(e.responseConverter).then(e.responseHandler).catch(e.errorHandler),e.returnValue);e.complete=e=>{if(r.execute(e,"onComplete"),e.cursor.onComplete(),e.status.onComplete(),(e=>{delete e.func,delete e.URI,delete e.requestURI,delete e.requestData,delete e.requestRetry,delete e.httpRequestOptions,delete e.responseHandler,delete e.responseConverter,delete e.responseContent,delete e.response,delete e.errorHandler})(e),"synchronous"===e.mode){for(c.pop(a.q.send),c.pop(a.q.recv);null!==(recvRequest=a.popAsyncRequest(a.q.recv));)o.received(recvRequest);for(;null!==(nextRequest=a.popAsyncRequest(a.q.send));)l(nextRequest);null!==(nextRequest=c.peek(a.q.send))&&l(nextRequest)}},e.abort=t=>{t.aborted=!0,e.complete(t)},e.execute=(e,o)=>{if(void 0===e)return!1;const u=o??{};for(u.func=e,(e=>{t.setRequestOptions(e),r.initCallbacks(e),r.execute(e,"onInitialize"),e.status=e.statusMessages?t.status.update:t.status.dontUpdate,e.cursor=e.waitCursor?t.cursor.update:t.cursor.dontUpdate,s.initialize(e),e.submit=c.empty(a.q.send),"synchronous"===e.mode&&(c.push(a.q.send,e),c.push(a.q.recv,e)),e.submit||c.push(a.q.send,e)})(u),r.execute(u,"onProcessParams"),n.process(u);u.requestRetry>0;)try{return i(u),u.submit?l(u):null}catch(e){if(r.execute(u,"onFailure"),u.requestRetry<=0)throw e}return!0}}(jaxon.ajax.request,jaxon.config,jaxon.ajax.parameters,jaxon.ajax.response,jaxon.ajax.callback,jaxon.ajax.handler,jaxon.utils.upload,jaxon.utils.queue),function(e,t,n,o,r,a,s){const c=[0,200],i=[400,401,402,403,404,500,501,502,503],l=[301,302,307],u=e=>{try{return n.execute(e)}catch(e){console.log(e)}return!0};e.processCommands=e=>{let t=null;for(;!e.paused&&null!==(t=a.pop(e));)if(!u(t))return!1;return!0},e.jsonProcessor=t=>c.indexOf(t.response.status)>=0?(r.execute(t,"onSuccess"),(e=>{if(!s.isObject(e.responseContent))return;const{debug:{message:t}={},jxn:{value:n,commands:o=[]}={}}=e.responseContent;e.status.onProcessing(),n&&(e.returnValue=n),t&&console.log(t);let r=0;o.forEach((t=>a.push(e.commandQueue,{fullName:"*unknown*",...t,sequence:r++,commandQueue:e.commandQueue,request:e,context:e.context}))),a.push(e.commandQueue,{name:"response.complete",fullName:"Response Complete",sequence:r,commandQueue:e.commandQueue,request:e,context:e.context})})(t),e.processCommands(t.commandQueue),t.returnValue):l.indexOf(t.response.status)>=0?(r.execute(t,"onRedirect"),o.complete(t),window.location=t.response.headers.get("location"),t.returnValue):i.indexOf(t.response.status)>=0?(r.execute(t,"onFailure"),o.complete(t),t.returnValue):t.returnValue,e.received=e=>e.aborted?null:(e.commandQueue=a.create(t.commandQueueSize),r.clearTimer(e,"onExpiration"),r.clearTimer(e,"onResponseDelay"),r.execute(e,"beforeResponseProcessing"),e.responseProcessor(e))}(jaxon.ajax.response,jaxon.config,jaxon.ajax.handler,jaxon.ajax.request,jaxon.ajax.callback,jaxon.utils.queue,jaxon.utils.types),function(e,t,n,o){e.assign=({target:e,attr:n,value:o})=>{const r=t.getInnerObject(n,e);return null!==r&&(r.node[r.attr]=o),!0},e.append=({target:e,attr:n,value:o})=>{const r=t.getInnerObject(n,e);return null!==r&&(r.node[r.attr]=r.node[r.attr]+o),!0},e.prepend=({target:e,attr:n,value:o})=>{const r=t.getInnerObject(n,e);return null!==r&&(r.node[r.attr]=o+r.node[r.attr]),!0};e.replace=({target:e,attr:o,search:r,replace:a})=>{const s=t.getInnerObject(o,e);return null!==s&&((e,o,r)=>{const a=n.isFunction(e.node[e.attr]),s=(a?e.node[e.attr].join(""):e.node[e.attr]).replaceAll(o,r);(a||t.willChange(e.node,e.attr,s))&&(e.node[e.attr]=s)})(s,"innerHTML"===o?t.getBrowserHTML(r):r,a),!0},e.clear=({target:t,attr:n})=>(e.assign({target:t,attr:n,value:""}),!0),e.remove=({target:e})=>(t.removeElement(e),!0);const r=(e,t)=>{const n=o.createElement(e);return n.setAttribute("id",t),n};e.create=({target:e,tag:{id:t,name:n}})=>(e&&e.appendChild(r(n,t)),!0),e.insert=({target:e,tag:{id:t,name:n}})=>(e&&e.parentNode&&e.parentNode.insertBefore(r(n,t),e),!0),e.insertAfter=({target:e,tag:{id:t,name:n}})=>(e&&e.parentNode&&e.parentNode.insertBefore(r(n,t),e.nextSibling),!0)}(jaxon.cmd.body,jaxon.utils.dom,jaxon.utils.types,jaxon.config.baseDocument),function(e,t,n,o){e.addHandler=({target:e,event:t,func:r})=>(e.addEventListener(o.stripOnPrefix(t),n.findFunction(r),!1),!0),e.removeHandler=({target:e,event:t,func:r})=>(e.removeEventListener(o.stripOnPrefix(t),n.findFunction(r),!1),!0);const r=(e,n,o)=>{t.execExpr({_type:"expr",...o},{event:e,target:n})};e.addEventHandler=({target:e,event:t,func:n,options:a})=>(e.addEventListener(o.stripOnPrefix(t),(t=>r(t,e,n)),a??!1),!0),e.setEventHandler=({target:e,event:t,func:n})=>(e[o.addOnPrefix(t)]=t=>r(t,e,n),!0)}(jaxon.cmd.event,jaxon.call.json,jaxon.utils.dom,jaxon.utils.string),function(e,t,n,o){e.call=({func:e,args:n},{context:o={}})=>(t.execCall({_type:"func",_name:e,args:n},o),!0),e.exec=({expr:e})=>(t.execExpr(e),!0),e.redirect=({url:e,delay:t})=>t<=0?(window.location=e,!0):(window.setTimeout((()=>window.location=e),1e3*t),!0),e.setDatabag=({values:e})=>(n.setBags(e),!0),e.jquery=({selector:e})=>(t.execExpr(e),!0);const r=(e,t)=>e.map((e=>o.isObject(e)&&"page"===e._type?parseInt(t.parentNode.getAttribute("data-page")):e));e.paginate=({target:e,func:n})=>{const o=e.querySelectorAll("li.enabled > a"),{args:a}=n;return o.forEach((e=>e.addEventListener("click",(()=>t.execCall({...n,_type:"func",args:r(a,e)}))))),!0}}(jaxon.cmd.script,jaxon.call.json,jaxon.ajax.parameters,jaxon.utils.types),function(e,t,n){const o=(e,n)=>{t.has(e)||console.warn(`Unable to find a Jaxon dialog library with name "${e}".`);const o=t.get(e);return o[n]?o:(console.error(`The chosen Jaxon dialog library doesn't implement the "${n}" function.`),null)};e.showMessage=({lib:e,type:t,content:r})=>{const{title:a,phrase:s}=r,c=o(e,"alert");return c&&c.alert(t,n.makePhrase(s),a),!0},e.showModal=({lib:e,dialog:{title:t,content:n,buttons:r,options:a}})=>{const s=o(e,"show");return s&&s.show(t,n,r,a),!0},e.hideModal=({lib:e})=>{const t=o(e,"hide");return t&&t.hide(),!0}}(jaxon.dialog.cmd,jaxon.dialog.lib,jaxon.call.json),function(e,t,n,o,r){const a={yes:"Yes",no:"No"};e.default={},e.has=t=>!!e[t],e.get=t=>e[t]??e.default,e.register=(s,c)=>{e[s]={},c(e[s],{types:t,dom:n,js:o,jq:r,labels:a})},e.register("default",(e=>{e.alert=(e,t,n)=>alert(n?`${n}
${t}`:t),e.confirm=(e,t,n,o)=>{confirm(t?`${t}
${e}`:e)?n():o&&o()}}))}(jaxon.dialog.lib,jaxon.utils.types,jaxon.dom,jaxon.call.json,window.jQuery),jaxon.request=jaxon.ajax.request.execute,jaxon.register=jaxon.ajax.handler.register,jaxon.$=jaxon.utils.dom.$,jaxon.jq=jaxon.call.query.jq,jaxon.exec=jaxon.call.json.execExpr,jaxon.dom.ready=jaxon.utils.dom.ready,jaxon.getFormValues=jaxon.utils.form.getValues,jaxon.setBag=jaxon.ajax.parameters.setBag,jaxon.processCustomAttrs=()=>jaxon.call.attr.process(),jaxon.isLoaded=!0,function(e,t,n,o){e("response.complete",((e,{request:t})=>(n.request.complete(t),!0)),"Response complete"),e("dom.assign",t.body.assign,"Dom::Assign"),e("dom.append",t.body.append,"Dom::Append"),e("dom.prepend",t.body.prepend,"Dom::Prepend"),e("dom.replace",t.body.replace,"Dom::Replace"),e("dom.clear",t.body.clear,"Dom::Clear"),e("dom.remove",t.body.remove,"Dom::Remove"),e("dom.create",t.body.create,"Dom::Create"),e("dom.insert.before",t.body.insert,"Dom::InsertBefore"),e("dom.insert.after",t.body.insertAfter,"Dom::InsertAfter"),e("script.call",t.script.call,"Script::CallJsFunction"),e("script.exec",t.script.exec,"Script::ExecJsonExpression"),e("script.redirect",t.script.redirect,"Script::Redirect"),e("script.sleep",n.handler.sleep,"Handler::Sleep"),e("script.confirm",n.handler.confirm,"Handler::Confirm"),e("handler.event.set",t.event.setEventHandler,"Script::SetEventHandler"),e("handler.event.add",t.event.addEventHandler,"Script::AddEventHandler"),e("handler.add",t.event.addHandler,"Script::AddHandler"),e("handler.remove",t.event.removeHandler,"Script::RemoveHandler"),e("script.debug",(({message:e})=>(console.log(e),!0)),"Debug message"),e("jquery.call",t.script.jquery,"JQuery::CallSelector"),e("pg.paginate",t.script.paginate,"Paginator::Paginate"),e("databag.set",t.script.setDatabag,"Databag:SetValues"),e("databag.clear",t.script.clearDatabag,"Databag:ClearValue"),e("dialog.message",o.cmd.showMessage,"Dialog:ShowMessage"),e("dialog.modal.show",o.cmd.showModal,"Dialog:ShowModal"),e("dialog.modal.hide",o.cmd.hideModal,"Dialog:HideModal")}(jaxon.register,jaxon.cmd,jaxon.ajax,jaxon.dialog); \ No newline at end of file +var jaxon={version:{major:"5",minor:"0",patch:"0rc-10"},debug:{verbose:{}},ajax:{callback:{},handler:{},parameters:{},request:{},response:{}},cmd:{body:{},script:{},event:{}},parser:{attr:{},call:{},query:{}},utils:{dom:{},form:{},queue:{},types:{},string:{},upload:{}},dom:{},dialog:{cmd:{},lib:{}},config:{}};!function(e){e.commonHeaders={"If-Modified-Since":"Sat, 1 Jan 2000 00:00:00 GMT"},e.postHeaders={},e.getHeaders={},e.waitCursor=!1,e.statusMessages=!1,e.baseDocument=document,e.requestURI=document.URL,e.defaultMode="asynchronous",e.defaultHttpVersion="HTTP/1.1",e.defaultContentType="application/x-www-form-urlencoded",e.defaultResponseDelayTime=1e3,e.convertResponseToJson=!0,e.defaultExpirationTime=1e4,e.defaultMethod="POST",e.defaultRetry=5,e.defaultReturnValue=!1,e.maxObjectDepth=20,e.maxObjectSize=2e3,e.commandQueueSize=1e3,e.requestQueueSize=1e3,e.httpRequestOptions={mode:"cors",cache:"no-cache",credentials:"same-origin",redirect:"manual"},e.setRequestOptions=t=>{if(void 0===e.requestURI)throw{code:10005};["commonHeaders","postHeaders","getHeaders"].forEach((n=>t[n]={...e[n],...t[n]}));const n={statusMessages:e.statusMessages,waitCursor:e.waitCursor,mode:e.defaultMode,method:e.defaultMethod,URI:e.requestURI,httpVersion:e.defaultHttpVersion,contentType:e.defaultContentType,convertResponseToJson:e.convertResponseToJson,retry:e.defaultRetry,returnValue:e.defaultReturnValue,maxObjectDepth:e.maxObjectDepth,maxObjectSize:e.maxObjectSize,context:window,upload:!1,aborted:!1};Object.keys(n).forEach((e=>t[e]=t[e]??n[e])),t.method=t.method.toUpperCase(),"GET"!==t.method&&(t.method="POST"),t.requestRetry=t.retry},e.status={update:{onRequest:()=>console.log("Sending Request..."),onWaiting:()=>console.log("Waiting for Response..."),onProcessing:()=>console.log("Processing..."),onComplete:()=>console.log("Done.")},dontUpdate:{onRequest:()=>{},onWaiting:()=>{},onProcessing:()=>{},onComplete:()=>{}}},e.cursor={update:{onWaiting:()=>{jaxon.config.baseDocument.body&&(jaxon.config.baseDocument.body.style.cursor="wait")},onComplete:()=>{jaxon.config.baseDocument.body&&(jaxon.config.baseDocument.body.style.cursor="auto")}},dontUpdate:{onWaiting:()=>{},onComplete:()=>{}}}}(jaxon.config),window.jaxon=jaxon,function(e,t,n){e.$=e=>e?t.isString(e)?n.getElementById(e):e:null;e.getBrowserHTML=t=>{const o=(()=>{const t=e.$("jaxon_temp_workspace");if(t)return t;if(!n.body)return null;const o=n.createElement("div");return o.setAttribute("id","jaxon_temp_workspace"),o.style.display="none",o.style.visibility="hidden",n.body.appendChild(o),o})();o.innerHTML=t;const r=o.innerHTML;return o.innerHTML="",r},e.willChange=(t,n,o)=>!!(t=e.$(t))&&o!=t[n],e.removeElement=t=>{(t=e.$(t))&&t.parentNode&&t.parentNode.removeChild&&t.parentNode.removeChild(t)},e.findFunction=(e,n=window)=>{if("toInt"===e&&n===window)return t.toInt;const o=e.split("."),r=o.length;for(let e=0;e{const n=e.split(".");e=n.pop();const o=n.length;for(let e=0;e{t.forEach((t=>{const{childNodes:o,type:r}=t;void 0!==o&&"select-one"!==r&&"select-multiple"!==r&&n(e,o),((e,{type:t,name:n,tagName:o,checked:r,disabled:a,value:s,options:i})=>{if(!n||"PARAM"===o)return;if(!e.disabled&&a)return;const{prefix:c}=e;if(c.length>0&&c!==n.substring(0,c.length))return;if(("radio"===t||"checkbox"===t)&&!r)return;if("file"===t)return;const l="select-multiple"!==t?s:i.filter((({selected:e})=>e)).map((({value:e})=>e)),u=n.indexOf("[");if(u<0)return void(e.values[n]=l);let d=n.substring(0,u),p=n.substring(u);void 0===e.values[d]&&(e.values[d]={});let m=e.values;for(;p.length>0;){const e=p.substring(0,p.indexOf("]")+1),n=d,o=m;p=p.substring(p.indexOf("]")+1),m=m[d],d=e.substring(1,e.length-1),""===d&&("select-multiple"===t?(d=n,m=o):d=m.length),void 0===d&&(d=Object.keys(o[n]).length),m[d]=m[d]||{}}m[d]=l})(e,t)}))};e.getValues=(e,o=!1,r="")=>{const a={disabled:!0===o,prefix:r??"",values:{}},s=t.$(e);return s&&s.childNodes&&n(a,s.childNodes),a.values}}(jaxon.utils.form,jaxon.utils.dom),function(e){e.create=e=>({start:0,count:0,size:e,end:0,elements:[],paused:!1}),e.empty=e=>e.count<=0,e.full=e=>e.count>=e.size,e.push=(t,n)=>{if(e.full(t))throw{code:10003};return t.elements[t.end]=n,++t.end>=t.size&&(t.end=0),++t.count},e.pushFront=(t,n)=>{if(e.full(t))throw{code:10003};return e.empty(t)?e.push(t,n):(--t.start<0&&(t.start=t.size-1),t.elements[t.start]=n,++t.count)},e.pop=t=>{if(e.empty(t))return null;let n=t.elements[t.start];return delete t.elements[t.start],++t.start>=t.size&&(t.start=0),t.count--,n},e.peek=t=>e.empty(t)?null:t.elements[t.start]}(jaxon.utils.queue),function(e){"use strict";let t=[],n=!1,o=!1;const r=()=>{n||(n=!0,t.forEach((e=>e.fn.call(window,e.ctx))),t=[])};e.ready=function(e,a){n?setTimeout((function(){e(a)}),1):(t.push({fn:e,ctx:a}),"complete"===document.readyState||!document.attachEvent&&"interactive"===document.readyState?setTimeout(r,1):o||(document.addEventListener("DOMContentLoaded",r,!1),window.addEventListener("load",r,!1),o=!0))}}(jaxon.utils.dom),function(e){e.doubleQuotes=e=>void 0!==e&&e.replace(new RegExp("'","g"),'"'),e.singleQuotes=e=>void 0!==e&&e.replace(new RegExp('"',"g"),"'"),e.stripOnPrefix=e=>0===(e=e.toLowerCase()).indexOf("on")?e.replace(/on/,""):e,e.addOnPrefix=e=>0!==(e=e.toLowerCase()).indexOf("on")?"on"+e:e,String.prototype.supplant||(String.prototype.supplant=function(e){return this.replace(/\{([^{}]*)\}/g,((t,n)=>{const o=e[n],r=typeof o;return"string"===r||"number"===r?o:t}))})}(jaxon.utils.string),function(e){e.of=e=>Object.prototype.toString.call(e).slice(8,-1).toLowerCase(),e.isObject=t=>"object"===e.of(t),e.isArray=t=>"array"===e.of(t),e.isString=t=>"string"===e.of(t),e.isFunction=t=>"function"===e.of(t),e.toInt=e=>parseInt(e),Array.prototype.top||(Array.prototype.top=function(){return this.length>0?this[this.length-1]:void 0})}(jaxon.utils.types),function(e,t,n){e.initialize=e=>{(e=>{if(!e.upload)return!1;e.upload={id:e.upload,input:null,form:null};const o=t.$(e.upload.id);return o?"file"!==o.type?(n.log("The upload input field with id "+e.upload.id+" is not of type file"),!1):0===o.files.length?(n.log("There is no file selected for upload in input field with id "+e.upload.id),!1):void 0===o.name?(n.log("The upload input field with id "+e.upload.id+" has no name attribute"),!1):(e.upload.input=o,e.upload.form=o.form,!0):(n.log("Unable to find input field for file upload with id "+e.upload.id),!1)})(e)||(e.postHeaders["content-type"]=e.contentType)}}(jaxon.utils.upload,jaxon.utils.dom,console),function(e,t){const n={},o="main",r=["dom.assign","dom.append","dom.prepend","dom.replace"],a=["innerHTML","outerHTML"];e.changed=(e,t,n)=>e&&a.some((e=>e===n))&&r.some((e=>e===t));e.process=(e=document)=>{e.querySelectorAll(":scope [jxn-on]").forEach((e=>{e.hasAttribute("jxn-func")&&(e=>{const n=e.getAttribute("jxn-on"),o=JSON.parse(e.getAttribute("jxn-func"));if(!e.hasAttribute("jxn-select"))return void t.setEventHandler({target:e,event:n,func:o});const r=e.getAttribute("jxn-select");e.querySelectorAll(`:scope ${r}`).forEach((e=>{t.setEventHandler({target:e,event:n,func:o})}))})(e),e.removeAttribute("jxn-on"),e.removeAttribute("jxn-func"),e.removeAttribute("jxn-select")}));e.querySelectorAll(":scope [jxn-component]").forEach((e=>{const t=e.getAttribute("jxn-component"),r=e.getAttribute("jxn-item")??o;n[`${t}_${r}`]=e,e.removeAttribute("jxn-component")}))},e.node=(e,t=o)=>n[`${e}_${t}`]??null}(jaxon.parser.attr,jaxon.cmd.event),function(e,t,n,o,r,a){const s={eq:(e,t)=>e==t,teq:(e,t)=>e===t,ne:(e,t)=>e!=t,nte:(e,t)=>e!==t,gt:(e,t)=>e>t,ge:(e,t)=>e>=t,lt:(e,t)=>ee<=t},i={select:({_name:e,context:n=null},o)=>{switch(e){case"this":return t.select(o.target);case"event":return o.event;case"window":return window;default:return t.select(e,n)}},event:({_name:e,func:t},n,o)=>(o.on(e,(e=>f(t,{...n,event:e,target:e.currentTarget}))),o),func:({_name:e,args:t=[]},n,r)=>{const a=o.findFunction(e);return a?a.apply(n,d(t,r)):void 0},method:({_name:e,args:t=[]},n,r)=>{const s=o.findFunction(e,r);return s?s.apply(r,d(t,r)):"toInt"===e?a.toInt(r):void 0},attr:({_name:e,value:t},n,r)=>{const a=o.getInnerObject(e,r||n.target);if(a)return void 0!==t&&(a.node[a.attr]=u(t,r)),a.node[a.attr]}},c={comparator:()=>!1,command:e=>{console.error("Unexpected command: "+JSON.stringify({call:e}))}},l=e=>a.isObject(e)&&!!e._type,u=(e,t)=>{if(!l(e))return e;const{_type:n,_name:a}=e;switch(n){case"form":return r.getValues(a);case"html":return o.$(a).innerHTML;case"input":return o.$(a).value;case"checked":return o.$(a).checked;case"expr":return f(e,{target:window});case"_":return"this"===a?t:void 0;default:return}},d=(e,t)=>e.map((e=>u(e,t))),p=(e,t,n)=>(l(e)?i[e._type]:c.command)(e,t,n);e.execCall=(e,t)=>p(e,{target:window,...t});const m=(e,t)=>e.reduce(((e,n)=>void 0===e?void 0:p(n,t,e)),null);e.makePhrase=({str:e,args:t})=>e.supplant(t.reduce(((e,t,n)=>({...e,[n+1]:u(t)})),{}));const x=t=>!!t&&n.alert({...t,text:e.makePhrase(t.phrase)}),f=(t,o)=>{const{calls:r,question:a,condition:i,message:l}=t;if(a)((t,o,r,a)=>{n.confirm({...t,text:e.makePhrase(t.phrase)},(()=>m(r,a)),(()=>x(o)))})(a,l,r,o);else{if(!i)return m(r,o);((e,t,n,o)=>{const[r,a,i]=e;(s[r]??c.comparator)(u(a),u(i))?m(n,o):x(t)})(i,l,r,o)}};e.execExpr=(e,t)=>a.isObject(e)&&f(e,{target:window,...t})}(jaxon.parser.call,jaxon.parser.query,jaxon.dialog.lib,jaxon.utils.dom,jaxon.utils.form,jaxon.utils.types),function(e,t){e.jq=t,e.select=(t,n=null)=>n?e.jq(t,n):e.jq(t)}(jaxon.parser.query,window.jQuery),function(e,t,n){const o=(e,n)=>{!t.has(e)&&console.warn(`Unable to find a Jaxon dialog library with name "${e}".`);const o=t.get(e);return!o[n]&&console.error(`The chosen Jaxon dialog library doesn't implement the "${n}" function.`),o};e.showMessage=({lib:e,type:t,title:r,phrase:a})=>{const s=o(e,"alert");return s.alert&&s.alert(t,n.makePhrase(a),r),!0},e.showModal=({lib:e,dialog:{title:t,content:n,buttons:r,options:a}})=>{const s=o(e,"show");return s.show&&s.show(t,n,r,a),!0},e.hideModal=({lib:e})=>{const t=o(e,"hide");return t.hide&&t.hide(),!0}}(jaxon.dialog.cmd,jaxon.dialog.lib,jaxon.parser.call),function(e,t,n,o,r){const a={yes:"Yes",no:"No"},s={};e.has=e=>!!s[e],e.get=e=>s[e]??s.default,e.alert=({lib:t,type:n,title:o="",text:r})=>e.get(t).alert(n,r,o),e.confirm=({lib:t,title:n="",text:o},r,a)=>e.get(t).confirm(o,n,r,a),e.register=(e,i)=>{s[e]={},i(s[e],{types:t,dom:n,js:o,jq:r,labels:a})},e.register("default",(e=>{e.alert=(e,t,n)=>alert(n?`${n}
${t}`:t),e.confirm=(e,t,n,o)=>{confirm(t?`${t}
${e}`:e)?n():o&&o()}}))}(jaxon.dialog.lib,jaxon.utils.types,jaxon.dom,jaxon.parser.call,window.jQuery),function(e,t,n){const o=e=>({timer:null,delay:e}),r=["onInitialize","onProcessParams","onPrepare","onRequest","onResponseDelay","onExpiration","beforeResponseProcessing","onFailure","onRedirect","onSuccess","onComplete"];e.create=(e,t)=>{const a={timers:{onResponseDelay:o(e??n.defaultResponseDelayTime),onExpiration:o(t??n.defaultExpirationTime)}};return r.forEach((e=>a[e]=null)),a},e.callback=e.create(),e.initCallbacks=n=>{if(t.isObject(n.callback)&&(n.callback=[n.callback]),t.isArray(n.callback))return void n.callback.forEach((e=>{void 0===e.timers&&(e.timers={})}));let o=!1;const a=e.create();r.forEach((e=>{void 0!==n[e]&&(a[e]=n[e],o=!0,delete n[e])})),n.callback=o?[a]:[]};const a=({callback:t=[]})=>[e.callback,...t];e.execute=(e,n)=>a(e).forEach((o=>((e,n,o)=>{const r=e[n];if(!r||!t.isFunction(r))return;const a=e.timers[n];a?a.timer=setTimeout((()=>r(o)),a.delay):r(o)})(o,n,e)));e.clearTimer=(e,t)=>a(e).forEach((e=>((e,t)=>{const n=e.timers[t];void 0!==n&&null!==n.timer&&clearTimeout(n.timer)})(e,t)))}(jaxon.ajax.callback,jaxon.utils.types,jaxon.config),function(e,t,n,o,r,a,s,i){const c={};e.q={send:a.create(t.requestQueueSize),recv:a.create(2*t.requestQueueSize)},e.register=(e,t,n="")=>c[e]={desc:n,func:t},e.unregister=e=>{const t=c[e];return t?(delete c[e],t.func):null},e.isRegistered=({name:e})=>void 0!==e&&void 0!==c[e];e.execute=t=>{const{name:n,args:o={}}=t;if(!e.isRegistered({name:n}))return!0;const a=o.component?.name;a&&(o.target=r.node(a,o.component.item));const i=o.id;!o.target&&i&&(o.target=s.$(i));const l=((e,t,n)=>{const{func:o,desc:r}=c[e];return o(t,{...n,desc:r})})(n,o,t);return r.changed(o.target,n,o.attr)&&r.process(o.target),l},e.popAsyncRequest=e=>a.empty(e)||"synchronous"===a.peek(e).mode?null:a.pop(e),e.sleep=({duration:e},{commandQueue:t})=>(t.paused=!0,setTimeout((()=>{t.paused=!1,n.processCommands(t)}),100*e),!0);const l=(e,t=0)=>{for(;t>0&&e.count>1&&null!==a.pop(e);)--t;e.paused=!1,n.processCommands(e)};e.confirm=({count:e,question:{lib:t,title:n,phrase:r}},{commandQueue:a})=>{const s=i.get(t);return a.paused=!0,s.confirm(o.makePhrase(r),n,(()=>l(a)),(()=>l(a,e))),!0}}(jaxon.ajax.handler,jaxon.config,jaxon.ajax.response,jaxon.parser.call,jaxon.parser.attr,jaxon.utils.queue,jaxon.utils.dom,jaxon.dialog.lib),function(e,t,n){const o={};e.setBag=(e,t)=>o[e]=t,e.setBags=t=>Object.keys(t).forEach((n=>e.setBag(n,t[n]))),e.clearBag=e=>delete o[e];const r=({func:e,parameters:r,bags:a=[]},s)=>{const i=new Date;var c;s("jxnr",i.getTime()),s("jxnv",`${n.major}.${n.minor}.${n.patch}`),Object.keys(e).forEach((t=>s(t,encodeURIComponent(e[t])))),[...r].forEach((e=>s("jxnargs[]",(e=>{if(null==e)return"*";const n=t.of(e);if("object"===n||"array"===n)try{return encodeURIComponent(JSON.stringify(e))}catch(t){e=""}return e=encodeURIComponent(e),"string"===n?"S"+e:"boolean"===n?"B"+e:"number"===n?"N"+e:e})(e)))),a.length>0&&s("jxnbags",encodeURIComponent((c=a,JSON.stringify(c.reduce(((e,t)=>({...e,[t]:o[t]??"*"})),{})))))};e.process=e=>{e.requestURI=e.URI,e.requestData=(({upload:e})=>e&&e.ajax&&e.input)(e)?(e=>{const t=new FormData;r(e,((e,n)=>t.append(e,n)));const n=e.upload.input;return n.files&&n.files.forEach((e=>t.append(n.name,e))),t})(e):(e=>{const t=[];return r(e,((e,n)=>t.push(e+"="+n))),"POST"===e.method?t.join("&"):(e.requestURI+=(-1===e.requestURI.indexOf("?")?"?":"&")+t.join("&"),"")})(e)}}(jaxon.ajax.parameters,jaxon.utils.types,jaxon.version),function(e,t,n,o,r,a,s,i){const c=e=>{--e.requestRetry,r.execute(e,"onPrepare"),e.httpRequestOptions={...t.httpRequestOptions,method:e.method,headers:{...e.commonHeaders,..."POST"===e.method?e.postHeaders:e.getHeaders},body:e.requestData},e.responseConverter=t=>(e.response=t,e.convertResponseToJson?t.json():t.text()),e.responseHandler=t=>{e.responseContent=t,i.empty(a.q.send)||"synchronous"===e.mode?o.received(e):i.push(a.q.recv,e)},e.errorHandler=t=>{throw r.execute(e,"onFailure"),t},e.responseProcessor||(e.responseProcessor=o.jsonProcessor)},l=e=>(e.status.onRequest(),r.execute(e,"onResponseDelay"),r.execute(e,"onExpiration"),r.execute(e,"onRequest"),e.cursor.onWaiting(),e.status.onWaiting(),fetch(e.requestURI,e.httpRequestOptions).then(e.responseConverter).then(e.responseHandler).catch(e.errorHandler),e.returnValue);e.complete=e=>{if(r.execute(e,"onComplete"),e.cursor.onComplete(),e.status.onComplete(),(e=>{delete e.func,delete e.URI,delete e.requestURI,delete e.requestData,delete e.requestRetry,delete e.httpRequestOptions,delete e.responseHandler,delete e.responseConverter,delete e.responseContent,delete e.response,delete e.errorHandler})(e),"synchronous"===e.mode){for(i.pop(a.q.send),i.pop(a.q.recv);null!==(recvRequest=a.popAsyncRequest(a.q.recv));)o.received(recvRequest);for(;null!==(nextRequest=a.popAsyncRequest(a.q.send));)l(nextRequest);null!==(nextRequest=i.peek(a.q.send))&&l(nextRequest)}},e.abort=t=>{t.aborted=!0,e.complete(t)},e.execute=(e,o)=>{if(void 0===e)return!1;const u=o??{};for(u.func=e,(e=>{t.setRequestOptions(e),r.initCallbacks(e),r.execute(e,"onInitialize"),e.status=e.statusMessages?t.status.update:t.status.dontUpdate,e.cursor=e.waitCursor?t.cursor.update:t.cursor.dontUpdate,s.initialize(e),e.submit=i.empty(a.q.send),"synchronous"===e.mode&&(i.push(a.q.send,e),i.push(a.q.recv,e)),e.submit||i.push(a.q.send,e)})(u),r.execute(u,"onProcessParams"),n.process(u);u.requestRetry>0;)try{return c(u),u.submit?l(u):null}catch(e){if(r.execute(u,"onFailure"),u.requestRetry<=0)throw e}return!0}}(jaxon.ajax.request,jaxon.config,jaxon.ajax.parameters,jaxon.ajax.response,jaxon.ajax.callback,jaxon.ajax.handler,jaxon.utils.upload,jaxon.utils.queue),function(e,t,n,o,r,a,s){const i=[0,200],c=[400,401,402,403,404,500,501,502,503],l=[301,302,307],u=e=>{try{return n.execute(e)}catch(e){console.log(e)}return!0};e.processCommands=e=>{let t=null;for(;!e.paused&&null!==(t=a.pop(e));)if(!u(t))return!1;return!0},e.jsonProcessor=t=>i.indexOf(t.response.status)>=0?(r.execute(t,"onSuccess"),(e=>{if(!s.isObject(e.responseContent))return;const{debug:{message:t}={},jxn:{value:n,commands:o=[]}={}}=e.responseContent;e.status.onProcessing(),n&&(e.returnValue=n),t&&console.log(t);let r=0;o.forEach((t=>a.push(e.commandQueue,{fullName:"*unknown*",...t,sequence:r++,commandQueue:e.commandQueue,request:e,context:e.context}))),a.push(e.commandQueue,{name:"response.complete",fullName:"Response Complete",sequence:r,commandQueue:e.commandQueue,request:e,context:e.context})})(t),e.processCommands(t.commandQueue),t.returnValue):l.indexOf(t.response.status)>=0?(r.execute(t,"onRedirect"),o.complete(t),window.location=t.response.headers.get("location"),t.returnValue):c.indexOf(t.response.status)>=0?(r.execute(t,"onFailure"),o.complete(t),t.returnValue):t.returnValue,e.received=e=>e.aborted?null:(e.commandQueue=a.create(t.commandQueueSize),r.clearTimer(e,"onExpiration"),r.clearTimer(e,"onResponseDelay"),r.execute(e,"beforeResponseProcessing"),e.responseProcessor(e))}(jaxon.ajax.response,jaxon.config,jaxon.ajax.handler,jaxon.ajax.request,jaxon.ajax.callback,jaxon.utils.queue,jaxon.utils.types),function(e,t,n,o){e.assign=({target:e,attr:n,value:o})=>{const r=t.getInnerObject(n,e);return null!==r&&(r.node[r.attr]=o),!0},e.append=({target:e,attr:n,value:o})=>{const r=t.getInnerObject(n,e);return null!==r&&(r.node[r.attr]=r.node[r.attr]+o),!0},e.prepend=({target:e,attr:n,value:o})=>{const r=t.getInnerObject(n,e);return null!==r&&(r.node[r.attr]=o+r.node[r.attr]),!0};e.replace=({target:e,attr:o,search:r,replace:a})=>{const s=t.getInnerObject(o,e);return null!==s&&((e,o,r)=>{const a=n.isFunction(e.node[e.attr]),s=(a?e.node[e.attr].join(""):e.node[e.attr]).replaceAll(o,r);(a||t.willChange(e.node,e.attr,s))&&(e.node[e.attr]=s)})(s,"innerHTML"===o?t.getBrowserHTML(r):r,a),!0},e.clear=({target:t,attr:n})=>(e.assign({target:t,attr:n,value:""}),!0),e.remove=({target:e})=>(t.removeElement(e),!0);const r=(e,t)=>{const n=o.createElement(e);return n.setAttribute("id",t),n};e.create=({target:e,tag:{id:t,name:n}})=>(e&&e.appendChild(r(n,t)),!0),e.insert=({target:e,tag:{id:t,name:n}})=>(e&&e.parentNode&&e.parentNode.insertBefore(r(n,t),e),!0),e.insertAfter=({target:e,tag:{id:t,name:n}})=>(e&&e.parentNode&&e.parentNode.insertBefore(r(n,t),e.nextSibling),!0)}(jaxon.cmd.body,jaxon.utils.dom,jaxon.utils.types,jaxon.config.baseDocument),function(e,t,n,o){e.addHandler=({target:e,event:t,func:r})=>(e.addEventListener(o.stripOnPrefix(t),n.findFunction(r),!1),!0),e.removeHandler=({target:e,event:t,func:r})=>(e.removeEventListener(o.stripOnPrefix(t),n.findFunction(r),!1),!0);const r=(e,n,o)=>t.execExpr({_type:"expr",...o},{event:e,target:n});e.addEventHandler=({target:e,event:t,func:n,options:a})=>(e.addEventListener(o.stripOnPrefix(t),(t=>r(t,e,n)),a??!1),!0),e.setEventHandler=({target:e,event:t,func:n})=>(e[o.addOnPrefix(t)]=t=>r(t,e,n),!0)}(jaxon.cmd.event,jaxon.parser.call,jaxon.utils.dom,jaxon.utils.string),function(e,t,n,o){e.call=({func:e,args:n},{context:o={}})=>(t.execCall({_type:"func",_name:e,args:n},o),!0),e.exec=({expr:e})=>(t.execExpr(e),!0),e.redirect=({url:e,delay:t})=>t<=0?(window.location=e,!0):(window.setTimeout((()=>window.location=e),1e3*t),!0),e.setDatabag=({values:e})=>(n.setBags(e),!0),e.jquery=({selector:e})=>(t.execExpr(e),!0);const r=(e,t)=>e.map((e=>o.isObject(e)&&"page"===e._type?parseInt(t.parentNode.getAttribute("data-page")):e));e.paginate=({target:e,func:n})=>{const o=e.querySelectorAll("li.enabled > a"),{args:a}=n;return o.forEach((e=>e.addEventListener("click",(()=>t.execCall({...n,_type:"func",args:r(a,e)}))))),!0}}(jaxon.cmd.script,jaxon.parser.call,jaxon.ajax.parameters,jaxon.utils.types),jaxon.request=jaxon.ajax.request.execute,jaxon.register=jaxon.ajax.handler.register,jaxon.$=jaxon.utils.dom.$,jaxon.jq=jaxon.parser.query.jq,jaxon.exec=jaxon.parser.call.execExpr,jaxon.confirm=jaxon.dialog.lib.confirm,jaxon.alert=jaxon.dialog.lib.alert,jaxon.dom.ready=jaxon.utils.dom.ready,jaxon.getFormValues=jaxon.utils.form.getValues,jaxon.setBag=jaxon.ajax.parameters.setBag,jaxon.processCustomAttrs=()=>jaxon.parser.attr.process(),jaxon.isLoaded=!0,function(e,t,n,o){e("response.complete",((e,{request:t})=>(n.request.complete(t),!0)),"Response complete"),e("dom.assign",t.body.assign,"Dom::Assign"),e("dom.append",t.body.append,"Dom::Append"),e("dom.prepend",t.body.prepend,"Dom::Prepend"),e("dom.replace",t.body.replace,"Dom::Replace"),e("dom.clear",t.body.clear,"Dom::Clear"),e("dom.remove",t.body.remove,"Dom::Remove"),e("dom.create",t.body.create,"Dom::Create"),e("dom.insert.before",t.body.insert,"Dom::InsertBefore"),e("dom.insert.after",t.body.insertAfter,"Dom::InsertAfter"),e("script.call",t.script.call,"Script::CallJsFunction"),e("script.exec",t.script.exec,"Script::ExecJsonExpression"),e("script.redirect",t.script.redirect,"Script::Redirect"),e("script.sleep",n.handler.sleep,"Handler::Sleep"),e("script.confirm",n.handler.confirm,"Handler::Confirm"),e("handler.event.set",t.event.setEventHandler,"Script::SetEventHandler"),e("handler.event.add",t.event.addEventHandler,"Script::AddEventHandler"),e("handler.add",t.event.addHandler,"Script::AddHandler"),e("handler.remove",t.event.removeHandler,"Script::RemoveHandler"),e("script.debug",(({message:e})=>(console.log(e),!0)),"Debug message"),e("jquery.call",t.script.jquery,"JQuery::CallSelector"),e("pg.paginate",t.script.paginate,"Paginator::Paginate"),e("databag.set",t.script.setDatabag,"Databag:SetValues"),e("databag.clear",t.script.clearDatabag,"Databag:ClearValue"),e("dialog.message",o.cmd.showMessage,"Dialog:ShowMessage"),e("dialog.modal.show",o.cmd.showModal,"Dialog:ShowModal"),e("dialog.modal.hide",o.cmd.hideModal,"Dialog:HideModal")}(jaxon.register,jaxon.cmd,jaxon.ajax,jaxon.dialog); \ No newline at end of file diff --git a/dist/jaxon.module.js b/dist/jaxon.module.js index 2a91ae9..150947c 100644 --- a/dist/jaxon.module.js +++ b/dist/jaxon.module.js @@ -43,9 +43,9 @@ var jaxon = { event: {}, }, - call: { + parser: { attr: {}, - json: {}, + call: {}, query: {}, }, @@ -976,7 +976,7 @@ window.jaxon = jaxon; /** - * Class: jaxon.call.attr + * Class: jaxon.parser.attr * * Process Jaxon custom HTML attributes */ @@ -1090,27 +1090,16 @@ window.jaxon = jaxon; */ self.node = (sComponentName, sComponentItem = sDefaultComponentItem) => xComponentNodes[`${sComponentName}_${sComponentItem}`] ?? null; -})(jaxon.call.attr, jaxon.cmd.event); +})(jaxon.parser.attr, jaxon.cmd.event); /** - * Class: jaxon.call.json + * Class: jaxon.parser.call * * Execute calls from json expressions. */ (function(self, query, dialog, dom, form, types) { - /** - * @var {object} - */ - const xErrors = { - comparator: () => false, // The default comparison operator. - command: (xCall) => { - console.error('Unexpected command: ' + JSON.stringify({ call: xCall })); - return undefined; - }, - }; - /** * The comparison operators. * @@ -1127,49 +1116,6 @@ window.jaxon = jaxon; le: (xLeftArg, xRightArg) => xLeftArg <= xRightArg, }; - /** - * Check if an argument is an expression. - * - * @param {mixed} xArg - * - * @returns {boolean} - */ - const isValidCall = xArg => types.isObject(xArg) && (xArg._type); - - /** - * Get the value of a single argument. - * - * @param {mixed} xArg - * @param {mixed} xCurrValue The current expression value. - * - * @returns {mixed} - */ - const getValue = (xArg, xCurrValue) => { - if (!isValidCall(xArg)) { - return xArg; - } - const { _type: sType, _name: sName } = xArg; - switch(sType) { - case 'form': return form.getValues(sName); - case 'html': return dom.$(sName).innerHTML; - case 'input': return dom.$(sName).value; - case 'checked': return dom.$(sName).checked; - case 'expr': return execExpression(xArg, { target: window }); - case '_': return sName === 'this' ? xCurrValue : undefined; - default: return undefined; - } - }; - - /** - * Get the values of an array of arguments. - * - * @param {array} aArgs - * @param {mixed} xCurrValue The current expression value. - * - * @returns {array} - */ - const getArgs = (aArgs, xCurrValue) => aArgs.map(xArg => getValue(xArg, xCurrValue)); - /** * The call commands * @@ -1222,6 +1168,62 @@ window.jaxon = jaxon; }, }; + /** + * The function to call if one of the above is not found. + * + * @var {object} + */ + const xErrors = { + comparator: () => false, // The default comparison operator. + command: (xCall) => { + console.error('Unexpected command: ' + JSON.stringify({ call: xCall })); + return undefined; + }, + }; + + /** + * Check if an argument is an expression. + * + * @param {mixed} xArg + * + * @returns {boolean} + */ + const isValidCall = xArg => types.isObject(xArg) && !!xArg._type; + + /** + * Get the value of a single argument. + * + * @param {mixed} xArg + * @param {mixed} xCurrValue The current expression value. + * + * @returns {mixed} + */ + const getValue = (xArg, xCurrValue) => { + if (!isValidCall(xArg)) { + return xArg; + } + const { _type: sType, _name: sName } = xArg; + switch(sType) { + case 'form': return form.getValues(sName); + case 'html': return dom.$(sName).innerHTML; + case 'input': return dom.$(sName).value; + case 'checked': return dom.$(sName).checked; + case 'expr': return execExpression(xArg, { target: window }); + case '_': return sName === 'this' ? xCurrValue : undefined; + default: return undefined; + } + }; + + /** + * Get the values of an array of arguments. + * + * @param {array} aArgs + * @param {mixed} xCurrValue The current expression value. + * + * @returns {array} + */ + const getArgs = (aArgs, xCurrValue) => aArgs.map(xArg => getValue(xArg, xCurrValue)); + /** * Execute a single call. * @@ -1248,23 +1250,15 @@ window.jaxon = jaxon; /** * Execute the javascript code represented by an expression object. + * If a call returns "undefined", it will be the final return value. * * @param {array} aCalls The calls to execute * @param {object} oCallContext The context to execute calls in. * * @returns {mixed} */ - const execCalls = (aCalls, oCallContext) => { - let xCurrValue = undefined; - const nLength = aCalls.length; - for (let i = 0; i < nLength; i++) { - xCurrValue = execCall(aCalls[i], oCallContext, xCurrValue); - if (xCurrValue === undefined) { - return xCurrValue; // Exit the loop if a call returns an undefined value. - } - } - return xCurrValue; - }; + const execCalls = (aCalls, oCallContext) => aCalls.reduce((xValue, xCall) => + xValue === undefined ? undefined : execCall(xCall, oCallContext, xValue), null); /** * Replace placeholders in a given string with values @@ -1275,12 +1269,8 @@ window.jaxon = jaxon; * * @returns {string} */ - self.makePhrase = ({ str: sStr, args: aArgs }) => { - const oArgs = {}; - let nIndex = 1; - aArgs.forEach(xArg => oArgs[nIndex++] = getValue(xArg)); - return sStr.supplant(oArgs); - }; + self.makePhrase = ({ str, args }) => str.supplant(args.reduce((oArgs, xArg, nIndex) => + ({ ...oArgs, [nIndex + 1]: getValue(xArg) }), {})); /** * Show an alert message @@ -1289,46 +1279,34 @@ window.jaxon = jaxon; * * @returns {void} */ - const showMessage = (message) => { - if ((message)) { - const { - lib: sLibName, - type: sType, - content: { title: sTitle, phrase }, - } = message; - const xLib = dialog.get(sLibName); - xLib.alert(sType, self.makePhrase(phrase), sTitle); - } - }; + const showMessage = (message) => !!message && + dialog.alert({ ...message, text: self.makePhrase(message.phrase) }); /** + * @param {object} question The confirmation question + * @param {object} message The message to show if the user anwsers no to the question * @param {array} aCalls The calls to execute - * @param {array} aCondition The condition to chek - * @param {object} oMessage The message to show if the condition is not met * @param {object} oCallContext The context to execute calls in. * * @returns {boolean} */ - const execWithCondition = (aCalls, aCondition, oMessage, oCallContext) => { - const [sOperator, xLeftArg, xRightArg] = aCondition; - const xComparator = xComparators[sOperator] ?? xErrors.comparator; - xComparator(getValue(xLeftArg), getValue(xRightArg)) ? - execCalls(aCalls, oCallContext) : showMessage(oMessage); - }; + const execWithConfirmation = (question, message, aCalls, oCallContext) => + dialog.confirm({ ...question, text: self.makePhrase(question.phrase) }, + () => execCalls(aCalls, oCallContext), () => showMessage(message)); /** + * @param {array} aCondition The condition to chek + * @param {object} oMessage The message to show if the condition is not met * @param {array} aCalls The calls to execute - * @param {object} oQuestion The confirmation question - * @param {object} oMessage The message to show if the user anwsers no to the question * @param {object} oCallContext The context to execute calls in. * * @returns {boolean} */ - const execWithConfirmation = (aCalls, oQuestion, oMessage, oCallContext) => { - const { lib: sLibName, phrase } = oQuestion; - const xLib = dialog.get(sLibName); - xLib.confirm(self.makePhrase(phrase), '', - () => execCalls(aCalls, oCallContext), () => showMessage(oMessage)); + const execWithCondition = (aCondition, oMessage, aCalls, oCallContext) => { + const [sOperator, xLeftArg, xRightArg] = aCondition; + const xComparator = xComparators[sOperator] ?? xErrors.comparator; + xComparator(getValue(xLeftArg), getValue(xRightArg)) ? + execCalls(aCalls, oCallContext) : showMessage(oMessage); }; /** @@ -1342,11 +1320,11 @@ window.jaxon = jaxon; const execExpression = (xExpression, oCallContext) => { const { calls, question, condition, message } = xExpression; if((question)) { - execWithConfirmation(calls, question, message, oCallContext); + execWithConfirmation(question, message, calls, oCallContext); return; } if((condition)) { - execWithCondition(calls, condition, message, oCallContext); + execWithCondition(condition, message, calls, oCallContext); return; } return execCalls(calls, oCallContext); @@ -1358,16 +1336,16 @@ window.jaxon = jaxon; * @param {object} xExpression An object representing a command * @param {object=} oCallContext The context to execute calls in. * - * @returns {mixed} + * @returns {void} */ - self.execExpr = (xExpression, oCallContext) => !types.isObject(xExpression) ? null : + self.execExpr = (xExpression, oCallContext) => types.isObject(xExpression) && execExpression(xExpression, { target: window, ...oCallContext }); -})(jaxon.call.json, jaxon.call.query, jaxon.dialog.lib, jaxon.utils.dom, +})(jaxon.parser.call, jaxon.parser.query, jaxon.dialog.lib, jaxon.utils.dom, jaxon.utils.form, jaxon.utils.types); /** - * Class: jaxon.call.query + * Class: jaxon.parser.query */ (function(self, jq) { @@ -1391,7 +1369,200 @@ window.jaxon = jaxon; // Todo: Allow the use of an alternative library instead of jQuery. return !xContext ? self.jq(xSelector) : self.jq(xSelector, xContext); }; -})(jaxon.call.query, window.jQuery); +})(jaxon.parser.query, window.jQuery); + + +/** + * Class: jaxon.dialog.cmd + */ + +(function(self, lib, parser) { + /** + * Find a library to execute a given function. + * + * @param {string} sLibName The dialog library name + * @param {string} sFunc The dialog library function + * + * @returns {object} + */ + const getLib = (sLibName, sFunc) => { + !lib.has(sLibName) && + console.warn(`Unable to find a Jaxon dialog library with name "${sLibName}".`); + + const xLib = lib.get(sLibName); + !xLib[sFunc] && + console.error(`The chosen Jaxon dialog library doesn't implement the "${sFunc}" function.`); + + return xLib; + }; + + /** + * Add an event handler to the specified target. + * + * @param {object} command The Response command object. + * @param {string} command.lib The message library name + * @param {object} command.type The message type + * @param {string} command.title The message title + * @param {object} command.phrase The message content + * + * @returns {true} The operation completed successfully. + */ + self.showMessage = ({ lib: sLibName, type: sType, title: sTitle, phrase }) => { + const xLib = getLib(sLibName, 'alert'); + xLib.alert && xLib.alert(sType, parser.makePhrase(phrase), sTitle); + return true; + }; + + /** + * Remove an event handler from an target. + * + * @param {object} command The Response command object. + * @param {string} command.lib The dialog library name + * @param {object} command.dialog The dialog content + * @param {string} command.dialog.title The dialog title + * @param {string} command.dialog.content The dialog HTML content + * @param {array} command.dialog.buttons The dialog buttons + * @param {array} command.dialog.options The dialog options + * + * @returns {true} The operation completed successfully. + */ + self.showModal = ({ lib: sLibName, dialog: { title, content, buttons, options } }) => { + const xLib = getLib(sLibName, 'show'); + xLib.show && xLib.show(title, content, buttons, options); + return true; + }; + + /** + * Set an event handler with arguments to the specified target. + * + * @param {object} command The Response command object. + * @param {string} command.lib The dialog library name + * + * @returns {true} The operation completed successfully. + */ + self.hideModal = ({ lib: sLibName }) => { + const xLib = getLib(sLibName, 'hide'); + xLib.hide && xLib.hide(); + return true; + }; +})(jaxon.dialog.cmd, jaxon.dialog.lib, jaxon.parser.call); + + +/** + * Class: jaxon.dialog.lib + */ + +(function(self, types, dom, js, jq) { + /** + * Labels for confirm question. + * + * @var {object} + */ + const labels = { + yes: 'Yes', + no: 'No', + }; + + /** + * Dialog libraries. + * + * @var {object} + */ + const libs = {}; + + /** + * Check if a dialog library is defined. + * + * @param {string} sName The library name + * + * @returns {bool} + */ + self.has = (sName) => !!libs[sName]; + + /** + * Get a dialog library. + * + * @param {string=default} sName The library name + * + * @returns {object|null} + */ + self.get = (sName) => libs[sName] ?? libs.default; + + /** + * Show a message using a dialog library. + * + * @param {object} oMessage The message in the command + * @param {string} oMessage.lib The dialog library to use for the message + * @param {string} oMessage.type The message type + * @param {string} oMessage.text The message text + * @param {string=} oMessage.title The message title + * + * @returns {void} + */ + self.alert = ({ lib: sLibName, type: sType, title: sTitle = '', text: sMessage }) => + self.get(sLibName).alert(sType, sMessage, sTitle); + + /** + * Call a function after user confirmation. + * + * @param {object} oQuestion The question in the command + * @param {string} oQuestion.lib The dialog library to use for the question + * @param {string} oQuestion.text The question text + * @param {string=} oQuestion.title The question title + * @param {function} fYesCb The function to call if the question is confirmed + * @param {function} fNoCb The function to call if the question is not confirmed + * + * @returns {void} + */ + self.confirm = ({ lib: sLibName, title: sTitle = '', text: sQuestion }, fYesCb, fNoCb) => + self.get(sLibName).confirm(sQuestion, sTitle, fYesCb, fNoCb); + + /** + * Register a dialog library. + * + * @param {string} sName The library name + * @param {callback} xCallback The library definition callback + * + * @returns {void} + */ + self.register = (sName, xCallback) => { + // Create an object for the library + libs[sName] = {}; + // Define the library functions + xCallback(libs[sName], { types, dom, js, jq, labels }); + }; + + /** + * Default dialog plugin, based on js alert and confirm functions + */ + self.register('default', (lib) => { + /** + * Show an alert message + * + * @param {string} type The message type + * @param {string} text The message text + * @param {string} title The message title + * + * @returns {void} + */ + lib.alert = (type, text, title) => alert(!title ? text : `${title}
${text}`); + + /** + * Ask a confirm question to the user. + * + * @param {string} question The question to ask + * @param {string} title The question title + * @param {callback} yesCallback The function to call if the answer is yes + * @param {callback} noCallback The function to call if the answer is no + * + * @returns {void} + */ + lib.confirm = (question, title, yesCallback, noCallback) => { + confirm(!title ? question : `${title}
${question}`) ? + yesCallback() : (noCallback && noCallback()); + }; + }); +})(jaxon.dialog.lib, jaxon.utils.types, jaxon.dom, jaxon.parser.call, window.jQuery); /** @@ -1554,7 +1725,7 @@ window.jaxon = jaxon; * Class: jaxon.ajax.handler */ -(function(self, config, rsp, json, attr, queue, dom, dialog) { +(function(self, config, rsp, call, attr, queue, dom, dialog) { /** * An array that is used internally in the jaxon.fn.handler object to keep track * of command handlers that have been registered. @@ -1718,22 +1889,27 @@ window.jaxon = jaxon; * @param {integer} args.count The number of commands to skip. * @param {object} args.question The question to ask. * @param {string} args.question.lib The dialog library to use. + * @param {object} args.question.title The question title. * @param {object} args.question.phrase The question content. * @param {object} command The Response command object. * @param {object} command.commandQueue The command queue. * * @returns {true} The queue processing is temporarily paused. */ - self.confirm = ({ count: skipCount, question: { lib: sLibName, phrase } }, { commandQueue }) => { + self.confirm = ({ + count: skipCount, + question: { lib: sLibName, title: sTitle, phrase }, + }, { commandQueue }) => { // The command queue is paused, and will be restarted after the confirm question is answered. - commandQueue.paused = true; const xLib = dialog.get(sLibName); - xLib.confirm(json.makePhrase(phrase), '', () => restartProcessing(commandQueue), + commandQueue.paused = true; + xLib.confirm(call.makePhrase(phrase), sTitle, + () => restartProcessing(commandQueue), () => restartProcessing(commandQueue, skipCount)); return true; }; -})(jaxon.ajax.handler, jaxon.config, jaxon.ajax.response, jaxon.call.json, - jaxon.call.attr, jaxon.utils.queue, jaxon.utils.dom, jaxon.dialog.lib); +})(jaxon.ajax.handler, jaxon.config, jaxon.ajax.response, jaxon.parser.call, + jaxon.parser.attr, jaxon.utils.queue, jaxon.utils.dom, jaxon.dialog.lib); /** @@ -2532,7 +2708,7 @@ window.jaxon = jaxon; * Class: jaxon.cmd.event */ -(function(self, json, dom, str) { +(function(self, call, dom, str) { /** * Add an event handler to the specified target. * @@ -2574,9 +2750,8 @@ window.jaxon = jaxon; * * @returns {void} */ - const callEventHandler = (event, target, func) => { - json.execExpr({ _type: 'expr', ...func }, { event, target }); - }; + const callEventHandler = (event, target, func) => + call.execExpr({ _type: 'expr', ...func }, { event, target }); /** * Add an event handler with arguments to the specified target. @@ -2611,14 +2786,14 @@ window.jaxon = jaxon; target[str.addOnPrefix(sEvent)] = (evt) => callEventHandler(evt, target, func); return true; }; -})(jaxon.cmd.event, jaxon.call.json, jaxon.utils.dom, jaxon.utils.string); +})(jaxon.cmd.event, jaxon.parser.call, jaxon.utils.dom, jaxon.utils.string); /** * Class: jaxon.cmd.script */ -(function(self, json, parameters, types) { +(function(self, call, parameters, types) { /** * Call a javascript function with a series of parameters using the current script context. * @@ -2631,7 +2806,7 @@ window.jaxon = jaxon; * @returns {true} The operation completed successfully. */ self.call = ({ func, args }, { context = {} }) => { - json.execCall({ _type: 'func', _name: func, args }, context); + call.execCall({ _type: 'func', _name: func, args }, context); return true; }; @@ -2644,7 +2819,7 @@ window.jaxon = jaxon; * @returns {true} The operation completed successfully. */ self.exec = ({ expr }) => { - json.execExpr(expr); + call.execExpr(expr); return true; }; @@ -2688,7 +2863,7 @@ window.jaxon = jaxon; * @returns {true} The operation completed successfully. */ self.jquery = ({ selector }) => { - json.execExpr(selector); + call.execExpr(selector); return true; }; @@ -2717,178 +2892,14 @@ window.jaxon = jaxon; self.paginate = ({ target, func: oCall }) => { const aLinks = target.querySelectorAll(`li.enabled > a`); const { args: aArgs } = oCall; - aLinks.forEach(oLink => oLink.addEventListener('click', () => json.execCall({ + aLinks.forEach(oLink => oLink.addEventListener('click', () => call.execCall({ ...oCall, _type: 'func', args: getCallArgs(aArgs, oLink), }))); return true; }; -})(jaxon.cmd.script, jaxon.call.json, jaxon.ajax.parameters, jaxon.utils.types); - - -/** - * Class: jaxon.dialog.cmd - */ - -(function(self, lib, json) { - /** - * Find a library to execute a given function. - * - * @param {string} sLibName The dialog library name - * @param {string} sFunc The dialog library function - * - * @returns {object|null} - */ - const getLib = (sLibName, sFunc) => { - if(!lib.has(sLibName)) { - console.warn(`Unable to find a Jaxon dialog library with name "${sLibName}".`); - } - - const xLib = lib.get(sLibName); - if(!xLib[sFunc]) { - console.error(`The chosen Jaxon dialog library doesn't implement the "${sFunc}" function.`); - return null; - } - return xLib; - }; - - /** - * Add an event handler to the specified target. - * - * @param {object} command The Response command object. - * @param {string} command.lib The message library name - * @param {object} command.type The message type - * @param {string} command.content The message content - * @param {string} command.content.title The message title - * @param {string} command.content.phrase.str The message text with placeholders - * @param {array} command.content.phrase.args The arguments for placeholders - * - * @returns {true} The operation completed successfully. - */ - self.showMessage = ({ lib: sLibName, type: sType, content }) => { - const { title: sTitle, phrase } = content; - const xLib = getLib(sLibName, 'alert'); - xLib && xLib.alert(sType, json.makePhrase(phrase), sTitle); - return true; - }; - - /** - * Remove an event handler from an target. - * - * @param {object} command The Response command object. - * @param {string} command.lib The dialog library name - * @param {object} command.dialog The dialog content - * @param {string} command.dialog.title The dialog title - * @param {string} command.dialog.content The dialog HTML content - * @param {array} command.dialog.buttons The dialog buttons - * @param {array} command.dialog.options The dialog options - * - * @returns {true} The operation completed successfully. - */ - self.showModal = ({ lib: sLibName, dialog: { title, content, buttons, options } }) => { - const xLib = getLib(sLibName, 'show'); - xLib && xLib.show(title, content, buttons, options); - return true; - }; - - /** - * Set an event handler with arguments to the specified target. - * - * @param {object} command The Response command object. - * @param {string} command.lib The dialog library name - * - * @returns {true} The operation completed successfully. - */ - self.hideModal = ({ lib: sLibName }) => { - const xLib = getLib(sLibName, 'hide'); - xLib && xLib.hide(); - return true; - }; -})(jaxon.dialog.cmd, jaxon.dialog.lib, jaxon.call.json); - - -/** - * Class: jaxon.dialog.lib - */ - -(function(self, types, dom, js, jq) { - const labels = { - yes: 'Yes', - no: 'No', - }; - - self.default = {}; - - /** - * Check if a dialog library is defined. - * - * @param {string} sName The library name - * - * @returns {bool} - */ - self.has = (sName) => !!self[sName]; - - /** - * Get a dialog library. - * - * @param {string=default} sName The library name - * - * @returns {object|null} - */ - self.get = (sName) => self[sName] ?? self.default; - - /** - * Register a dialog library. - * - * @param {string} sName The library name - * @param {callback} xCallback The library definition callback - * - * @returns {void} - */ - self.register = (sName, xCallback) => { - // Create an object for the library - self[sName] = {}; - // Define the library functions - xCallback(self[sName], { types, dom, js, jq, labels }); - }; - - /** - * Default dialog plugin, based on js alert and confirm functions - * Class: jaxon.dialog.lib.default - */ - - self.register('default', (lib) => { - /** - * Show an alert message - * - * @param {string} type The message type - * @param {string} text The message text - * @param {string} title The message title - * - * @returns {void} - */ - lib.alert = (type, text, title) => alert(!title ? text : `${title}
${text}`); - - /** - * Ask a confirm question to the user. - * - * @param {string} question The question to ask - * @param {string} title The question title - * @param {callback} yesCallback The function to call if the answer is yes - * @param {callback} noCallback The function to call if the answer is no - * - * @returns {void} - */ - lib.confirm = (question, title, yesCallback, noCallback) => { - if(confirm(!title ? question : `${title}
${question}`)) { - yesCallback(); - return; - } - noCallback && noCallback(); - }; - }); -})(jaxon.dialog.lib, jaxon.utils.types, jaxon.dom, jaxon.call.json, window.jQuery); +})(jaxon.cmd.script, jaxon.parser.call, jaxon.ajax.parameters, jaxon.utils.types); /* @@ -2919,12 +2930,22 @@ jaxon.$ = jaxon.utils.dom.$; /** * Shortcut to the JQuery selector function>. */ -jaxon.jq = jaxon.call.query.jq; +jaxon.jq = jaxon.parser.query.jq; + +/** + * Shortcut to . + */ +jaxon.exec = jaxon.parser.call.execExpr; + +/** + * Shortcut to . + */ +jaxon.confirm = jaxon.dialog.lib.confirm; /** - * Shortcut to . + * Shortcut to . */ -jaxon.exec = jaxon.call.json.execExpr; +jaxon.alert = jaxon.dialog.lib.alert; /** * Shortcut to . @@ -2942,9 +2963,9 @@ jaxon.getFormValues = jaxon.utils.form.getValues; jaxon.setBag = jaxon.ajax.parameters.setBag; /** - * Shortcut to . + * Shortcut to . */ -jaxon.processCustomAttrs = () => jaxon.call.attr.process(); +jaxon.processCustomAttrs = () => jaxon.parser.attr.process(); /** * Indicates if jaxon module is loaded.