413 lines
No EOL
16 KiB
JavaScript
413 lines
No EOL
16 KiB
JavaScript
(function (window) {
|
|
"use strict";
|
|
|
|
window.Litespeed.container.get('view').add(
|
|
{
|
|
selector: 'data-appwrite',
|
|
repeat: true,
|
|
controller: function(element, view, container, form, alerts, expression, window, di, state) {
|
|
let action = element.dataset['appwrite'];
|
|
let singleton = element.dataset['singleton'];
|
|
let loaded = element.dataset['loaded'];
|
|
let service = element.dataset['service'] || action;
|
|
let event = element.dataset['event']; // load, click, change, submit
|
|
let success = element.dataset['success'] || ''; // render, alert, redirect
|
|
let error = element.dataset['error'] || ''; // alert, redirect, page
|
|
let confirm = element.dataset['confirm'] || ''; // Free text
|
|
let loading = element.dataset['loading'] || ''; // Free text
|
|
let loaderId = null;
|
|
let scope = element.dataset['scope'] || 'sdk'; // Free text
|
|
let debug = !!(element.dataset['debug']); // Free text
|
|
|
|
if (debug) console.log('%c[service init]: ' + action + ' (' + service + ')', 'color:red');
|
|
|
|
if(loaded) {
|
|
return true; // Instance already created
|
|
}
|
|
|
|
success = success.trim().split(',');
|
|
error = error.trim().split(',');
|
|
|
|
let resolve = function(target) {
|
|
let FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
|
|
let text = target.toString();
|
|
let args = text.match(FN_ARGS)[1].split(',');
|
|
let data = ('FORM' === element.tagName) ? form.toJson(element) : {};
|
|
|
|
if (debug) console.log('%c[form data]: ', 'color:green', data);
|
|
|
|
return target.apply(target, args.map(function(value) {
|
|
let result = null;
|
|
|
|
if(!value) {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 1. Get from element data-param-* (expression supported)
|
|
* 2. Get from element data-param-state-*
|
|
* 3. Get from element form object-*
|
|
*/
|
|
|
|
if(element.dataset['param' + value.charAt(0).toUpperCase() + value.slice(1)]) {
|
|
result = expression.parse(element.dataset['param' + value.charAt(0).toUpperCase() + value.slice(1)]);
|
|
}
|
|
|
|
if(data[value]) {
|
|
result = data[value];
|
|
}
|
|
|
|
if(!result) {
|
|
result = '';
|
|
}
|
|
|
|
if (debug) console.log('%c[param resolved]: (' + service + ') ' + value + '=' + result, 'color:#808080');
|
|
|
|
return result;
|
|
}));
|
|
};
|
|
|
|
let successes = {
|
|
/**
|
|
*
|
|
*/
|
|
none: function () {
|
|
|
|
},
|
|
|
|
'save': function () {
|
|
return function(data) {
|
|
container.set(service.replace('.', '-'), JSON.parse(data), true, true);
|
|
};
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param view
|
|
* @returns {Function}
|
|
*/
|
|
'render': function (view) {
|
|
return function(data) {
|
|
try {
|
|
container.set(service.replace('.', '-'), JSON.parse(data), true, true);
|
|
} catch (e) {
|
|
container.set(service.replace('.', '-'), {}, true, true);
|
|
}
|
|
|
|
view.render(element);
|
|
|
|
let rerender = element.dataset['successRerender'] || '';
|
|
|
|
element.setAttribute('data-success-rerender', '');
|
|
|
|
rerender = rerender.trim().split(',');
|
|
|
|
for (let i = 0; i < rerender.length; i++) {
|
|
if('' === rerender[i]) {
|
|
continue;
|
|
}
|
|
|
|
document.addEventListener(rerender[i], function (event) {
|
|
console.log(event.type + ' triggered rendering');
|
|
|
|
if(element && element.parentNode) {
|
|
console.log(event.type + ' triggered rendering 2');
|
|
view.render(element.parentNode);
|
|
}
|
|
})
|
|
}
|
|
}
|
|
},
|
|
'reset': function () {
|
|
return function() {
|
|
if('FORM' === element.tagName) {
|
|
return element.reset();
|
|
}
|
|
|
|
throw new Error('This callback is only valid for forms');
|
|
}
|
|
},
|
|
|
|
'empty': function () {
|
|
return function() {
|
|
container.set(service.replace('.', '-'), {}, true);
|
|
view.render(element);
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param alerts
|
|
* @returns {Function}
|
|
*/
|
|
'alert': function (alerts) {
|
|
return function() {
|
|
let alert = element.dataset['successAlert'] || 'Success';
|
|
alerts.send({text: alert, class: 'success'}, 3000);
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @returns {Function}
|
|
*/
|
|
'update': function () {
|
|
return function(data) {
|
|
let service = element.dataset['successUpdate'] || null;
|
|
|
|
if(service) {
|
|
container.set(service, JSON.parse(data), true);
|
|
}
|
|
|
|
//let idElement = element.elements.id;
|
|
//if(idElement) {
|
|
// idElement = (idElement.length > 1) ? idElement[0] : idElement;
|
|
// idElement.value = JSON.parse(data).id;
|
|
//}
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param state
|
|
* @returns {Function}
|
|
*/
|
|
'redirect': function (state) {
|
|
return function() {
|
|
let url = expression.parse(element.dataset['successRedirectUrl']) || '/';
|
|
|
|
state.change(url);
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param document
|
|
* @returns {Function}
|
|
*/
|
|
'trigger': function (document) {
|
|
return function() {
|
|
let triggers = element.dataset['successTriggers'] || '';
|
|
|
|
triggers = triggers.trim().split(',');
|
|
|
|
for (let i = 0; i < triggers.length; i++) {
|
|
if('' === triggers[i]) {
|
|
continue;
|
|
}
|
|
if (debug) console.log('%c[event triggered]: ' + triggers[i], 'color:green');
|
|
|
|
di.report(triggers[i]);
|
|
|
|
document.dispatchEvent(new CustomEvent(triggers[i]));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
let errors = {
|
|
/**
|
|
*
|
|
*/
|
|
none: function () {
|
|
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param alerts
|
|
* @returns {Function}
|
|
*/
|
|
'alert': function (alerts) {
|
|
return function() {
|
|
let alert = element.dataset['errorAlert'] || 'Failure (' + action + ')';
|
|
alerts.send({text: alert, class: 'error'}, 3000);
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param state
|
|
* @returns {Function}
|
|
*/
|
|
'redirect': function (state) {
|
|
return function() {
|
|
let url = expression.parse(element.dataset['errorRedirectUrl']) || '/';
|
|
|
|
state.change(url);
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param view
|
|
* @returns {Function}
|
|
*/
|
|
'render': function (view) {
|
|
return function() {
|
|
container.set(service.replace('.', '-'), {}, true, true);
|
|
|
|
view.render(element);
|
|
|
|
let rerender = element.getAttribute('data-error-rerender') || '';
|
|
|
|
element.setAttribute('data-error-rerender', '');
|
|
|
|
rerender = rerender.trim().split(',');
|
|
|
|
for (let i = 0; i < rerender.length; i++) {
|
|
if('' === rerender[i]) {
|
|
continue;
|
|
}
|
|
|
|
document.addEventListener(rerender[i], function () {
|
|
if(element && element.parentNode) {
|
|
view.render(element.parentNode);
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param document
|
|
* @returns {Function}
|
|
*/
|
|
'trigger': function (document) {
|
|
return function() {
|
|
let triggers = element.dataset['errorTriggers'] || '';
|
|
|
|
triggers = triggers.trim().split(',');
|
|
|
|
for (let i = 0; i < triggers.length; i++) {
|
|
if('' === triggers[i]) {
|
|
continue;
|
|
}
|
|
|
|
di.report(triggers[i]);
|
|
|
|
document.dispatchEvent(new CustomEvent(triggers[i]));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
let exec = function(event) {
|
|
if (debug) console.log('%c[executed]: ' + scope + '.' + action, 'color:yellow', event, element, document.body.contains(element));
|
|
|
|
if(!document.body.contains(element)) {
|
|
element = undefined;
|
|
return false;
|
|
}
|
|
|
|
if(event) {
|
|
event.preventDefault();
|
|
}
|
|
|
|
if(confirm) {
|
|
if (window.confirm(confirm) !== true) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if(loading) {
|
|
loaderId = alerts.send({text: loading, class: ''}, 0);
|
|
}
|
|
|
|
if(element.$lsLock) {
|
|
// console.warn('Execution of ' + scope + '.' + action + ' is locked, wait for previous execution to finish', element);
|
|
return;
|
|
}
|
|
|
|
element.$lsLock = true;
|
|
|
|
let method = container.path(scope + '.' + action);
|
|
|
|
if(!method) {
|
|
throw new Error('Method "' + scope + '.' + action + '" not found');
|
|
}
|
|
|
|
let result = resolve(method);
|
|
|
|
if(!result) {
|
|
return;
|
|
}
|
|
|
|
result
|
|
.then(function (data) {
|
|
if(loaderId !== null) { // Remove loader if needed
|
|
alerts.remove(loaderId);
|
|
}
|
|
|
|
if(!element) {
|
|
return;
|
|
}
|
|
|
|
for (let i = 0; i < success.length; i++) { // Trigger success callbacks
|
|
container.resolve(successes[success[i]])(data);
|
|
}
|
|
|
|
element.$lsLock = false; // Release lock
|
|
}, function (exception) {
|
|
if(loaderId !== null) { // Remove loader if needed
|
|
alerts.remove(loaderId);
|
|
}
|
|
|
|
if(!element) {
|
|
return;
|
|
}
|
|
|
|
for (let i = 0; i < error.length; i++) { // Trigger failure callbacks
|
|
container.resolve(errors[error[i]])(exception);
|
|
}
|
|
|
|
element.$lsLock = false; // Release lock
|
|
});
|
|
};
|
|
|
|
let events = event.trim().split(',');
|
|
|
|
for (let y = 0; y < events.length; y++) {
|
|
if ('' === events[y]) {
|
|
continue;
|
|
}
|
|
|
|
switch (events[y].trim()) {
|
|
case 'empty':
|
|
for (let i = 0; i < success.length; i++) {
|
|
container.resolve(successes[success[i]])('{}');
|
|
}
|
|
break;
|
|
case 'load':
|
|
exec();
|
|
break;
|
|
case 'none':
|
|
break;
|
|
case 'click':
|
|
case 'change':
|
|
case 'keypress':
|
|
case 'keydown':
|
|
case 'keyup':
|
|
case 'input':
|
|
case 'submit':
|
|
element.addEventListener(events[y], exec);
|
|
element.setAttribute('data-event', 'none'); // Avoid re-attaching event
|
|
break;
|
|
default:
|
|
//document.addEventListener(events[y], exec);
|
|
di.listen(events[y], exec);
|
|
element.setAttribute('data-event', 'none'); // Avoid re-attaching event
|
|
}
|
|
|
|
if (debug) console.log('%cregistered: "' + events[y].trim() + '" (' + service + ')', 'color:blue');
|
|
}
|
|
|
|
if(singleton) {
|
|
element.dataset.loaded = 'true';
|
|
}
|
|
}
|
|
}
|
|
);
|
|
})(window); |