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.