diff --git a/.DS_Store b/.DS_Store index bd53731..2755e02 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/jsonic/.DS_Store b/jsonic/.DS_Store index e861d1f..2ffd97a 100644 Binary files a/jsonic/.DS_Store and b/jsonic/.DS_Store differ diff --git a/jsonic/js/.DS_Store b/jsonic/js/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/jsonic/js/.DS_Store differ diff --git a/jsonic/js/jsonic.1.0.13 copia.js b/jsonic/js/jsonic.1.0.13 copia.js deleted file mode 100644 index d321526..0000000 --- a/jsonic/js/jsonic.1.0.13 copia.js +++ /dev/null @@ -1,16029 +0,0 @@ -/*----------------------------- - JSONIC V. 1.0.13 - jsonic.io --------------------------------*/ - -// CHANGELOG - -// 1.0.13 jsonApp removed; [replaceProperties: include event properties] -// 1.0.12 jsonApp; if is array option -// 1.0.11 block blocks -> parts -// 1.0.10 for: {name} work also with {value:name with path} (function replaceValue) -// 1.0.8 for: {name} replaced with {value:name} -// 1.0.5 set: if array of, the assignments follow the order -// 1.0.4 deprecated: to assign without set (too ambiguous now that the key can be function, window.function, etc) -// 1.0.3 "x": "2*3" if the value is a string, -> self.js(value) -// 1.0.2 plugins ondemand -// 1.0.1 jsonc support -// 1.0.0 FUNCTIONS -// 0.9.9 RESOURCES: Inside modules (resources will be deprecated) -// 0.9.3 DEBUG: Rimosso break in docElement -// 0.9.4 NOTE: In this.nested, commented and decommented nested.animate = partObj.animate; nested.if partObj.if, ... -// 0.9.5 CLASS: "div btn": "content" =
content
-// 0.9.6 DEBUG: in this.createElement newSelector (newSelector should be a dedicated function separated from selector) -// 0.9.7 REMOVE: method to remove an element from the DOM / Restored html {attr} to set the attributes of an element - -// https://minify-js.com Input: 624.1 kB; Output: 95.46 kB; Compression: 84.7%, saving: 528.64 kB; - -// README - -// PRIORITY - -// in attr -> addStyle / removeStyle -// instead of shortcuts the user can use {data shortcuts} -// {arguments:value|default} -> ({arguments:value}) ? {arguments:value} : default -// use (typeof id == "undefined") to understand if id is defined and is = 0 -// css should call defineCss in any part of code -// attr (addClass, removeClass, changeStyle direct methods?) can be changed (in element?) to avoid confusion with the use inside html -// add remove element from array -// debug of "set" key -// can be useful to define pointers (shortcode/path of the objects) -// https://dev.to/ternentdotdev/json-compression-in-the-browser-with-gzip-and-the-compression-streams-api-4135 -// a method to append an image to the DOM in base64 format methods? no -// check this.html notes -// anime can be a part/block/key function? called with "ui:anime" asking for the relative plugin? -// if the name of the block/part includes ":" it is more explicit -// blocks or parts or keys or nodes? -// parts -> blocks considering jsblocks.com? -// Dynamic modules loading? What if we ask for a node that is in the main modules? - -// remove console from methods and add log in browser functions - -// add log of the error if the app or json module is not in json format -// init, run, start -> do -// if selector is an array, repeat the action (do) -// think about html/do. Is it possible to avoid html object? Any unknown object is an html tag -// in parts, {setup:on.success} or {setup:config.color} doesn't work -// setup -> arguments -// part ui:icon: {selector:, config:} can be a js function () {var part = {}; self.run(config); } -// {arguments[0] arguments[1]. {1.setup} } -// improve shortcuts (in extendJsonFromElement and in attr) -// this.text -> this.content -// html attribute of html method -> content (should be an html but can be multilingual) -// property validation like the sintax (\w[\w+d+]) of the "name" in the "for" method ) -// default "html" al posto di "text": ogni contenuto testuale viene inserito con innerHTML anziché innerTEXT -// html [] tipo array e "" stringa (innerHTML) ok, html {} deprecato -// "p": "text" -> p.innerTHTML('text') -// "p": [] -> se item è oggetto -> htmlTag, se stringa dovrebbe fare append della stringa html sempre nello p. Ora invece crea più p.innerText -// ADD: append. empty true fixed on html -/* -1 page -> url (method and property) -2 dynamic class with ternary condition -3 swal button style -4 components copy bugs -5 installation guide -6 self.page -> not the variable but the real window path and window hash (can be jsonic.url) -7 page -> url -8 "roles" -> "only" -9 add localStorage actions -> ANY WINDOW method -10 add dataStorage -10 in parts {string} instead of {value} ? -11 on load image solution (should already work on: load -> animate -> fadein) - */ - -// BUGS - -// BUG from Tailwind 3.3.2 -// Sembra richiesto tailwind nel plugin Jsonic e non caricato dinamicamente come su eliokit.com -// Different rendering width or without spaces after commans "alert": " {js:(1 == 2) ? \"test\" : \"false condition\"} " - - - -// HOW IT WORKS -// loadModules -> loadPlugins -> Run - -// KNOWN BUGS - -// in museomira.it cerca "socialIcons", rimuovendo data-value l'icona finisce dentro contatti perché il newSelector è a:eq(5) -// è necesario creare una funzione selector destinata ai nuovi elementi - -// PARTS - -// 1. Responsive header menu -// 2. Alert -// 3. Slide -// 4. Form -// 5. Table - -// GOAL - -// Reduce custom js code in Jsonic and move the functions in modules -// Requires an extension of js method to make it more flexible -// js {function: String, params: Array} - -// TO DO - -// inline use: data-jsonic -> jsonic.run(data-jsonic, selector); (es. in body) -// init = run (or play) -// in parts {setup} should get subreferences link {setup:on.success} -// i plugins possono includere direttamente l'url -// la gestione dei plugin dovrebbe essere centralizzata (riferimento a jsonic e non all'oggetto) -// si potrebbe definire la distinsione tra oggetti specifici e oggetti globali (jsonic) -// verificare se oggetto function con {name: , params: []} è assegnabile a variabili -// addClass, removeClass etc with array -// change the behaviour of p: [] become a a list of content, not a list of p -// to do it, search and change "div": [ "p": [ "span": [ "li": [ "button": [ -// hypothesis (no, more complete with actions): class="ui:button{text:#333;bg:#fff}" -> bg-[white] text-[#333] hover:bg-[#fff] hover:text-[white] -// OPTIMIZATION: pluginsRequiredByTag only for self.json.resources.pluginsFunctions keys or better only for parts that requires plugins. alert -> ui:alert -// getJSON: load json (id: exampleApp, url: ...), success-> {getJSON:exampleApp} -// Ajax: load ajax (id: exampleApp, url: ...), success-> {ajax:exampleApp} -// DOM: queryAll(selector) -> value is string, el.before(value) and all the other methods of an element of the dom -// properties {dom:title} -// https://www.w3schools.com/jsref/dom_obj_all.asp -// DOCUMENT -// https://www.w3schools.com/jsref/dom_obj_document.asp -// {document: {title: 'test'}} -// properties {document:title} -// ON: https://www.w3schools.com/jsref/dom_obj_event.asp -// "selector" can be "query" / no selector recalls querySelector -// or APPEND/PREPEND -// https://registry.npmjs.com/-/v1/search?text=tailwindcss&size=1 -//https://api.npms.io/v2/package/tailwindcss -// https://api-docs.npms.io - -/* -TO DO - -1. ajax call with an id to identify the data in case of simultaneous requests -1. database path should be separated by spaces (or slashes) - -replaceProperties default: - -check if - -if p1 is a function, if p2 -> value = p1(p2), if p3 -> value = p1(p2(p3)) -if p1 is a value, and not p2, value = p1 - -self.methods[p1] or... -p1 is a function - - -{alert:string} -{window.f} -{window f1:window f2:window x} = window.f1(window.f2(window.x)) - -{querySelector:'.class':append} = window.f(jsonic.json.var.x) - -ESEMPI - -{new Date:'December 17, 1995 03:24:00'} -{new Date().getDay} -{console.log:'test'} -{window.innerHeight} invece di {window:innerHeight} (specifica) o {js:window.innerHeight} - -il vantaggio di questo schema è che si evita un livello di parentesi annidate -quando sono coinvolte variabili jsonic: -{querySelector:var obj x:append} -che puo diventare -{querySelector:var {item} x:append} -LIMITE -questo metodo preclude l'accesso ad eventuali oggetti javascript var o data -SOLUZIONE -in realtà, var e data devono essere elementi definiti nel json -altrimenti non sono trovati dall'interprete che può vagliare l'esistenza -di una funzione js - -{path to a data} is a reference to a value in the data node of the Jsonic app -if the action context (do) -{path to an action} is a reference to a method or a sub app in the "parts" node of the Jsonic app -if the html rendering context (html) - -{window.f:var x} = window.f(jsonic.json.var.x) -{window.f:num} if is number -{window.f:array} if isArray (more than one parameter) -{window.f:'string'} - -{jsonic.f:var x} - -do: [ - "functionName": [] // parameters -] - -check if functionName is a function -html tags can't have a space or points... - -Align with ELIO Language: -1. "if": {"is": ["a", "=", "b","and"...] (retrocompatibile: se is è un array...) -2. "set": ["a", "+=", "1","*", "3"...] (retrocompatibile: se set è un array...) -3. "div classes": ... - -CODE REDUCING - -1. string in "html" object that starts with a tag and continue with classes - -"html": [ - "span appsDeviceListName ms-2 me-2 text-[16px] text-left w-[80%] leading-tight|content" -] - -NOTES - -// datapicker and other input fiels now are native https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date - -COMPONENTS - -MONACO TAILWINDCSS AUTOCOMPLETE (check Tailwindcss VS Code extensions) -https://github.com/remcohaszing/monaco-tailwindcss - - -FIREBASE STRUCTURE DATA - -If you create your own keys, they must be UTF-8 encoded, can be a maximum of 768 bytes, and cannot contain ., $, #, [, ], /, or ASCII control characters 0-31 or 127. You cannot use ASCII control characters in the values themselves, either. - -24.4KB gzipped (85.24KB minified) -25.2KB minified + gzipped in 100ms - -65ms 3G 3 Mbps (375 KBs) -10ms 4G 20 Mbps (2,5 MBs) -<1ms 5G/Fiber 200 Mbps (25 MBs) - -TEST - -tailwindcss -104 KB 105 ms - -INTEGRATIONS: -https://b2bsaasleads.com - -NEW PLUGINS: - -http://jakim.me/Toasty.js/ -https://tingle.robinparisi.com - -GUIDE: - -COMPONENTS: reusable components / architectural philosophy -ENGINE, (no hidden code) all the parts of the app is exposed to the developer / can set the layout and the behaviour -JSON E' il modello di struttura ad albero usato da JSONIC per descrivere i dati, lo stile, e le azioni dell'applicazione -SHORTCUTS: combinations of utility names (classes) to reuse in "class" property (from WindiCSS) - // preloaded js/css plugins - -{ - "attr": { - "class": "py-2 text-center" - }, - "subTitle": { - "lang": { - "it": "L'albero JSON dell'app può contenere i seguenti rami principali:", - "en": "The JSON app tree may contain the following main branches:", - "es": "El árbol de la aplicación JSON puede contener los siguientes ramas principales:" - } - } -}, - - -PROPERTIES - -With {property}, a string delimited by braces you can refer to any sub-branch the app tree and special properties. - ------------------------ -HOME PARAGRAPHS ------------------------ - -AUTO-LOADED PLUGINS - -NESTED CSS - -HTML has a clear nested and visual hierarchy but CSS doesn't. JSONIC let you nest your CSS definitions in a way that follows the same visual hierarchy of your HTML. It's similar to the SAAS extension but without the need to compile the code. In modo simile al linguaggio SAAS, è necessario compilare il codice - - - // BP - Questo dimostra che c'è bisogno di semplificazione più di quanto non si possa pensare - -IDE - -Special char (or shortener or autocomplete) with { } etcetera) - - -PRIORITY: - -tags: - -button: "title" -or -button: { - text: title - color: color - on: ... -} - -buttonOutline: { - text: title - color: color - on: ... -} - ------------------------- -qualunque metodo: -[ - {"path": args}, - {"path": args} - {"path": args} -] ------------------------- - - -DEBUG -class must be a string otherwise log error -style in attr must work (now error) - - -CONFIG (now setup) -extend the main branch {b:config} - -ACTIONS (now parts) -extend the main branch {b:actions} - -DO -execute one or an array of functions -"do": "actionID" (string) execute the actions.actionID function - -CONTAINER (now selector) -change the context to the element {b:container} -Can be an object like {id, class, data-value} -or a string with a CSS selector like "body > div:nt-child(2)" -or a jquery-like selector like "body > div:eq(2)" - ------------------------- - -bootstrap menu -> tailwind - ------------------------- - - -IDEAS - -- share the modules in the object "jsonic" with the other jsonic objects in the page -- jsonic.registerJsMethod(name, function) register new js method to be inserted in jsonic.methods and called with "method": {params} -- choose can contain the methods "next":"1" / "previous":"1" or step "+1"/"-1" -- calendar can return the object {lang: {...}} -- self.js can be embedded in self.compile (if typeof params == 'string') -- Page doesn't exist / if admin / want to create it? -- if no jsonic file for the page, create it on save - -- AUTH (debug) + GITHUB - -- preload font flag -- IDE: Wordpress API new page -- window methods in (docs) -- for -> addTag (?) -- setup: form to set setup properties -- Method ARRAY - -"array": { -"push": "{var:num}" (pop, shift, unshift, length) - -DONE: - -remove JSONIC references: jsonic.firebaseEventAction / jsonic.resizeEvent -- HOME: docs / examples / integrations -- wordpress: access to media API -- iconify -- iconify remove SVG old -- colors -> setup (mmm) (like logo) -- styles -> css -> senza categorie, solo elements '#div' -> https://transform.tools/css-to-js DONE -} - -BUGS: -- version è necessario in pluginsFunctions -- shortcut as a node: attr / class values doesn't overwrite the shortcut - -WORDPRESS: - -(_embed to your URL will add the wp:featuremedia) -https://jsonic.io/wp-json/wp/v2/media?&context=embed&per_page=100 -https://jsonic.io/wp-json/wp/v2/media?&context=embed&after=2017-11-07T00:00:00 -https://jsonic.io/wp-json/wp/v2/media?include=1681,491 - -// https://github.com/schlosser/pig.js - -NOTE: - -- autoupdate only if the previous update is complete (we need a param in config complete:true/false) -- Play (create your app!) -- add a tag in menu buttons ? -- inViewport -> 'enter'/'exit' ? -- inViewport solo la prima volta? -- ('on': 'in'/out NO) confirm 'init'? -- IDE: backup timeline -- duplicato di this.selector dedicata a ottenere il selector di un nuovo elemento (su append e poco altro) -- col: [1,2,3] -> row with col1 col2 col3 ? or tailwind grid solution (ragionare su soluzione di tag. esempio: flex: []) -- in examples, test in posizione assoluta sul codice (utile su mobile) - -KEY BENEFITS - -- Integration (Jsonic code includes the logic, the layout and the style of the app on in one JSON object) -- Accelerator - -*/ - -// JQUERY to Vanilla: https://youmightnotneedjquery.com | http://vanilla-js.com -// Jquery plus: https://atypiccraft.com/insights/reasons-why-we-still-use-jquery -// https://cyrilletuzi.github.io/javascript-guides/jquery-to-javascript.html -// Tools to integrate: https://bestofjs.org/tags -// MINIFY: https://closure-compiler.appspot.com/home -// https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=cat - -// INTEGRATIONS - -// https://www.dropzone.dev/js/ -// uploadcare -// zaiper - -// a graph js tool - -// anime.js -// transition.style // analogo ad animate.style - -/* There were issues affecting this run of Lighthouse: - -There may be stored data affecting loading performance in this location: IndexedDB. Audit this page in an incognito window to prevent those resources from affecting your scores. - -// UI - -https://windicss.org/play.html -https://basscss.com -https://twind.dev -https://emotion.sh/docs/introduction -https://cssinjs.org/?v=v10.8.2 - -https://picturepan2.github.io/spectre/ -https://get.foundation -https://ant.design/ -https://purecss.io -https://onsen.io/ -https://shuffle.dev/ -*/ - -//{"type": "js", "url":"https://cdn.jsdelivr.net/npm/tailwindcss@{version}/lib/index.min.js"}, - - -//$.fn.jsonic = function(options) {return new jsonicObject(options);}; -//jsonicApp = function(options) {return new jsonicObject(options);}; - - -var jsonAppObj = function(options) { - - var self = this; - console.log(); - - //this.options = options; - /* var json = { // the jsonic app tree - setup: {}, - blocks: {}, // to be removed - parts: {}, - // plugins: {}, // TO DO: remove the error if included - // css: {}, - do: {}, - on: {}, - shortcuts: {}, - texts: {}, - data: {}, - var: {} - }; */ - //var var = json.var; - //this.setup = json.setup; - // for external access - this.json = { - setup: {}, - blocks: {}, // to be removed - parts: {}, - // plugins: {}, // TO DO: remove the error if included - // css: {}, - functions: {}, - do: {}, - on: {}, - shortcuts: {}, - texts: {}, - data: {}, - var: {} - }; - this.app = this.json; - - //var json = self.json; // TO DO: remove - var alertObj = {}; - var alertValues = {}; - this.params = {}; // maybe can be removed - - this.javascriptReservedWord = ['abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield', 'Array', 'Date', 'eval', 'function', 'hasOwnProperty', 'Infinity', 'isFinite', 'isNaN', 'isPrototypeOf', 'length', 'Math', 'NaN', 'name', 'Number', 'Object', 'prototype', 'String', 'toString', 'undefined', 'valueOf', 'getClass', 'java', 'JavaArray', 'javaClass', 'JavaObject', 'JavaPackage', 'alert', 'all', 'anchor', 'anchors', 'area', 'assign', 'blur', 'button', 'checkbox', 'clearInterval', 'clearTimeout', 'clientInformation', 'close', 'closed', 'confirm', 'constructor', 'crypto', 'decodeURI', 'decodeURIComponent', 'defaultStatus', 'document', 'element', 'elements', 'embed', 'embeds', 'encodeURI', 'encodeURIComponent', 'escape', 'event', 'fileUpload', 'focus', 'form', 'forms', 'frame', 'innerHeight', 'innerWidth', 'layer', 'layers', 'link', 'location', 'mimeTypes', 'navigate', 'navigator', 'frames', 'frameRate', 'hidden', 'history', 'image', 'images', 'offscreenBuffering', 'open', 'opener', 'option', 'outerHeight', 'outerWidth', 'packages', 'pageXOffset', 'pageYOffset', 'parent', 'parseFloat', 'parseInt', 'password', 'pkcs11', 'plugin', 'prompt', 'propertyIsEnum', 'radio', 'reset', 'screenX', 'screenY', 'scroll', 'secure', 'select', 'self', 'setInterval', 'setTimeout', 'status', 'submit', 'taint', 'text', 'textarea', 'top', 'unescape', 'untaint', 'window', 'onblur', 'onclick', 'onerror', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onmouseover', 'onload', 'onmouseup', 'onmousedown', 'onsubmit']; - // Source: https://www.w3schools.com/js/js_reserved.asp - var nodes = { - //parts: ['text', 'div', 'ul', 'p', 'a', 'button', 'input', 'span', 'img', 'video', 'audio', 'source', 'figure', 'figcaption', 'textarea', 'iframe', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'svg', 'path', 'g', 'd', 'polygon', 'circle', 'small', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'form', 'form-group', 'label', 'select', 'option', 'optgroup', 'nav', 'tab', 'header', 'main', 'footer', 'ide', 'model-viewer', 'i', 'icon', 'pre', 'code','animateMotion','animateTransform','circle','clipPath','defs','desc','discard','ellipse','feBlend','feColorMatrix','feComponentTransfer','feComposite','feConvolveMatrix','feDiffuseLighting','feDisplacementMap','feDistantLight','feDropShadow','feFlood','feFuncA','feFuncB','feFuncG','feFuncR','feGaussianBlur','feImage','feMerge','feMergeNode','feMorphology','feOffset','fePointLight','feSpecularLighting','feSpotLight','feTile','feTurbulence','filter','foreignObject','g','hatch','hatchpath','image','line','linearGradient','marker','mask','metadata','mpath','path','pattern','polygon','polyline','radialGradient','rect','script','set','stop','switch','symbol','text','textPath','title','tspan','use','view'], - //functions: ['do', 'function', 'for', 'run', 'module', 'page', 'html', 'text', 'empty', 'alert', 'blocks', 'attr', 'color', 'set', 'array', 'replace', 'var', 'js', 'javascript', 'if', 'switch', 'choose', 'delay', 'ajax', 'hide', 'show', 'toggle', 'in', 'out', 'link', 'scroll', 'lang', 'find', 'data', 'reload', 'calendar', 'moment', 'dayjs', 'log', 'setInterval', 'clearInterval', 'offcanvas', 'firebase', 'database', 'qrcode', 'editor', 'ace', 'code', 'thunkable', 'animate', 'sortablejs', 'uiUpdate'], // 'String', 'Number', 'Math', - //functionsWithContainer: ['for', 'editor', 'ace', 'code', 'qrcode', 'lottie', 'animate', 'html', 'hide', 'show', 'toggle', 'in', 'out', 'if', 'ajax', 'attr', 'run', 'delay'], - // not execute - extend: ['setup', 'blocks', 'parts', 'css', 'actions', 'texts', 'data', 'functions'], // also plugins? (TO DO: remove actions) - params: ['style', 'on', 'matchMedia', 'action', 'code', 'roles', 'plugins', 'css'], // 'if', 'attr', 'text'. 'html' - exclude: ['setup', 'container', 'selector', 'info', 'note', 'comment', 'lang', 'tag', 'plugins', 'template'] - }; - - /* - * Converts a JSON object to a JSON Schema - * @param {any} json - * @param {object} options - * @returns {object} a json schema - */ - // [{"name": "vito", "gallery": {"name":2, "date":"10-10-2012"}, "num":3, "bool":true, "color": "#ff0000"}] - const FORMAT_REGEX = { - email: /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/, - url: /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, - ip: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, - // J. Meijer / Stackoverflow / 15491894 - date: /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/, - // Joey / Stackoverflow / 1636350 - color: /^#(?:[0-9a-fA-F]{3}){1,2}$|#(?:[0-9a-fA-F]{3,4}){1,2}$/, - }; - - this.jsonToSchema = function (json, options = {}) { - // https://github.com/mohsen1/json-to-json-schema - if (typeof json === 'function') { - throw new TypeError('Can not convert a function'); - } - - if (json === undefined) { - return {}; - } - - // primitives - if (typeof json === 'string') { - - if (FORMAT_REGEX.url.test(json)) return { type: 'string', format: 'url' }; - else if (FORMAT_REGEX.email.test(json)) return { type: 'string', format: 'email' }; - else if (FORMAT_REGEX.ip.test(json)) return { type: 'string', format: 'ip' }; - else if (FORMAT_REGEX.date.test(json)) return { type: 'string', format: 'date' }; - else if (FORMAT_REGEX.color.test(json)) return { type: 'string', format: 'color' }; - else return { type: 'string' }; - } - - else if (typeof json === 'boolean') return { type: 'boolean' }; - - else if (typeof json === 'number') { - if (Number.isInteger(json)) { - return { type: 'integer' }; - } else { - return { type: 'number' }; - } - } - - else if (Array.isArray(json)) { - let schema = { type: 'array' }; - - if (!json.length) { - schema.items = {}; - return schema; - } - - let schemas = json.map(self.jsonToSchema); - - // if all schemas are the same use that schema for items - if (schemas.every(s => self.isEqual(s, schemas[0]))) { - schema.items = schemas[0]; - - // if there are multiple schemas use oneOf - } else { - schema.items = { oneOf: unique(schemas) }; - } - - return schema; - } - - if (json === null) { - return { type: 'null' }; - } - - let schema = { type: 'object' }; - - if (!Object.keys(json).length) { - return schema; - } - - schema.properties = Object.keys(json).reduce((properties, key) => { - properties[key] = self.jsonToSchema(json[key]); - return properties; - }, {}); - - return schema; - }; - - this.isEqual = function (a, b) { - return (JSON.stringify(a) == JSON.stringify(b)); - }; - - - //var canvasElement = document.getElementById("canvas"); - // * this is not important for PDFMake, it's here just to render the result * - // It's a Mozilla lib called PDFjs that handles pdf rendering directly on the browser - /* this.pdfjs = function (params, selectorParams) { - - var url = params.url; - var options = params.options || { scale: 1.4 }; - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - var canvasContainer = self.query(container); - - function renderPage(page) { - var viewport = page.getViewport(options.scale); - var wrapper = document.createElement("div"); - wrapper.className = "canvas-wrapper"; - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - var renderContext = { - canvasContext: ctx, - viewport: viewport - }; - - canvas.height = viewport.height; - canvas.width = viewport.width; - wrapper.appendChild(canvas) - canvasContainer.appendChild(wrapper); - - page.render(renderContext); - } - - function renderPages(pdfDoc) { - for(var num = 1; num <= pdfDoc.numPages; num++) - pdfDoc.getPage(num).then(renderPage); - } - - PDFJS.disableWorker = true; - PDFJS.getDocument(url).then(renderPages); - - } */ - //renderPDF('https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf', document.querySelector('#canvas')); - /* this.localStorage = function (params) { - // -> use self.method - if (params.getItem) return localStorage.getItem(params.get); - else if (params.setItem) return localStorage.setItem(params.setItem.name, params.setItem.value); - } */ - // UTILITY - /** A storage solution aimed at replacing jQuerys data function. - * Implementation Note: Elements are stored in a (WeakMap)[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap]. - * This makes sure the data is garbage collected when the node is removed. - */ - this.dataStorage = { - _storage: new WeakMap(), - set: function (element, key, obj) { - if (!this._storage.has(element)) { - this._storage.set(element, new Map()); - } - this._storage.get(element).set(key, obj); - }, - get: function (element, key) { - return this._storage.get(element).get(key); - }, - has: function (element, key) { - return this._storage.has(element) && this._storage.get(element).has(key); - }, - remove: function (element, key) { - var ret = this._storage.get(element).delete(key); - if (!this._storage.get(element).size === 0) { - this._storage.delete(element); - } - return ret; - } - }; - - // JQUERY cross-over - this.extend = function (out) { - - if (typeof arguments[0] == 'boolean' && arguments[0] == true) - return deepExtend(out); - else { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - if (!arguments[i]) - continue; - - for (var key in arguments[i]) { - if (arguments[i].hasOwnProperty(key)) - out[key] = arguments[i][key]; - } - } - return out; - } - }; - - var deepExtend = function (out) { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - var obj = arguments[i]; - - if (!obj) continue; - - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - if (typeof obj[key] === "object" && obj[key] !== null) { - if (obj[key] instanceof Array) out[key] = obj[key].slice(0); - else out[key] = deepExtend(out[key], obj[key]); - } else out[key] = obj[key]; - } - } - } - - return out; - }; - - /* this.actionResult = function(value, args) { // value -> params - - // Methods with a result - - if (value && typeof value == 'object') { - - // jsonic methods - if (value.js) { - return self.js(value.js, args); - } else if (value.array) { - return self.array(value.array, args); - } else if (value.calendar) { - return self.calendar(value.calendar, args); - } else if (value.data) { - return self.data(value.data, args); - } else if (value.var) { - return self.var(value.var, args); - } else if (value.module) { - return self.module(value.module, args); - } else if (value.color) { - return self.color(value.color, args); - } else if (value.css) { - return self.css(value.css, undefined, args); - } else if (value.if) { - return self.if(value.if, undefined, args); - } else if (value.switch) { - return self.switch(value.switch, args); - } else if (value.database) { - return self.database(value.database, args); - // js methods - } else if (value.Math) { - return self.Math(value.Math, args); - } else if (value.Number) { - return self.Number(value.Number, args); - } else if (value.String) { - return self.String(value.String, args); - // plugin methods - } else if (value.ace) { - return self.ace(value.ace, args); - // else if (value.code) { - // return self.code(value.code, args); - } else if (value.moment) { - return self.moment(value.moment, args); - } else if (value.dayjs) { - return self.dayjs(value.dayjs, args); - } else if (value.function) { // TO DO: remove (replaced by do) - return self.function(value.function, value.params); - } else { - return value; - } - } else { - return value - } - //} else if (typeof value == 'string') { - // return self.javascript(value, args); - - } */ - this.var = function (params, args) { - - - if (Array.isArray(params)) { - for (var index in params) - self.var(params[index], args); - } else { - - //self.log('var'); - var name; - var value; - var varValue; - - if (params.path && !params.name) - name = self.path(params.path, args, '.'); - - if (typeof params == 'string') { - // gives a variable value - name = self.replaceProperties(params, args); - /* self.log('name'); - self.log(name); */ - /* self.log('typeof params == string'); - self.log('params'); - self.log(params); - self.log('name'); - self.log(params); */ - varValue = self.docElement('self.json.var.' + name); - - /* self.log('varValue'); - self.log(varValue); */ - } else { - - /* self.log('var'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - //self.log('params'); - //self.log(params); - var paramsReplaced = self.replaceProperties(params, args); - //self.log('paramsReplaced'); - //self.log(paramsReplaced); - name = paramsReplaced.name; - value = paramsReplaced.value; - var operator = paramsReplaced.operator; - var type = paramsReplaced.type; - - /* self.log('extend'); - self.log(extend); */ - if (name) { - var pathString = 'self.json.var.' + name; - var pathLast = pathString.substr(pathString.lastIndexOf(".") + 1); - var pathBase = pathString.substr(0, pathString.lastIndexOf(".")); - var varObj = self.docElement(pathBase); - - /* self.log('name'); - self.log(name); - self.log('pathBase'); - self.log(pathBase); - self.log('pathLast'); - self.log(pathLast); - self.log('varObj'); - self.log(varObj); */ - if (value !== undefined) { - - //if (value == 'string') - // value = self.docElement('self.json.var.'+value); // todo - //else - value = self.actionResult(value, args); - - // typization - switch (type) { - case 'string': value = String(value); break; - case 'number': value = Number(value); break; - case 'boolean': value = Boolean(value); break; - case 'array': value = JSON.parse(value); break; - case 'object': value = JSON.parse(value); break; - } - - //self.log('value'); - //self.log(value); - /* - // reset - if (value == undefined && typeof value == 'string') value = ''; - if (value == undefined && typeof value == 'number') value = 0; - if (value == undefined && typeof value == 'object') value = {}; */ - /* self.log('operator'); - self.log(operator); - self.log('pathLast'); - self.log(pathLast); - self.log('varObj[pathLast]'); - self.log(varObj[pathLast]); */ - if (varObj && pathLast) { - switch (operator) { - case '+=': varObj[pathLast] += value; break; - case '-=': varObj[pathLast] -= value; break; - case '/=': varObj[pathLast] /= value; break; - case '*=': varObj[pathLast] *= value; break; - default: varObj[pathLast] = value; break; - } - - /* operators: [ - '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', - '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%', - '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=', - '%=', '<<=', '>>=', '>>>=' - ], */ - //self.log('varObj[pathLast]'); - varValue = varObj[pathLast]; - } else { - /* self.log('pathString'); - self.log(pathString); */ - //varValue = self.docElement(pathString, value); - //varValue = value; - self.docElement(pathString, value); - - /* self.log('name'); - self.log(name); - - self.log('var '+name); - self.log(self.var(name)); */ - } - - /* self.log('pathLast'); - self.log(pathLast); - self.log('varObj[pathLast]'); - self.log(varObj[pathLast]); */ - /* //alert(value); - //value = self.replaceProperties(value, args); - if (value == 'string') { - //self.json.var[name] = self.docElement('self.json.var.'+value); - varObj[pathLast] = self.docElement('self.json.var.'+value); - } else { - //self.json.var[name] = self.actionResult(value, args); - varObj[pathLast] = self.actionResult(value, args); - } */ - //self.log('varObj[pathLast]'); - //if (self.isJson(self.json.var[name])) - // self.json.var[name] = self.parse(self.json.var[name]); - } else if (paramsReplaced.push) { - if (varObj && pathLast && varObj[pathLast]) { - varObj[pathLast] = varObj[pathLast].push(paramsReplaced.push); - varValue = varObj[pathLast]; - } - } else if (paramsReplaced.extend) { - if (varObj && pathLast && varObj[pathLast]) { - varObj[pathLast] = self.extend({}, varObj[pathLast], paramsReplaced.extend); - varValue = varObj[pathLast]; - } - } else { - // no "value" property: return the value of the var "name" - varValue = varObj[pathLast]; - /* varValue = self.replaceProperties(varObj[pathLast], args); - alert(JSON.stringify(varValue)); */ - } - - //varValue = self.json.var[name] || {}; // to check - } else { - self.log('var name undefined'); - self.log(params); - varValue = undefined; - } - - if (params.do && params.do.length > 0) { - self.log('this.var params.do'); - self.log(params.do); - //alert(JSON.stringify(params.do)); - //self.do(params.do, args); - self.do(params.do, undefined, args); - } - - } - - return varValue; - - } - }; - - this.find = function (params, args) { - if (params.in) { - var list = self.replaceProperties(params.in, args); - return list.filter(function (item) { - if (params.value) { - if (typeof params.value == 'string') { - if (JSON.stringify(item).indexOf(params.value) >= 0) - return item; - } else { // if (typeof params.value == 'string') { - for (var key in params.value) { - if (params.value[key] == item[key]) - return item; - } - } - } - }); - } - }; - - /* this.data = function (params, args) { - if (typeof params == 'string') - return self.db(params, args); - else - self.firebase(params, args); - } */ - this.array = function (params, args) { - /* self.log("---- this.array ----"); - self.log('params'); - self.log(params); */ - if (args) - params = self.replacePropertyWithPrefix(params, 'result', args); - - for (var par in params) { - var paramReplaced = self.replaceProperties(params[par], args); - //value[par](params[par]) // ipotesi di eseguire in automatico qualunque funzione js su stringhe - /* self.log("par"); - self.log(par); - self.log("params[par]"); - self.log(params[par]); - self.log("paramReplaced"); - self.log(paramReplaced); */ - params[par] = paramReplaced; - } - - //self.log("params"); - //self.log(params); - var value = self.element({ path: params.name }) || []; - /* self.log("value"); - self.log(...value); */ - if (params.push) { - if (Array.isArray(params.push)) - value.push(...params.push); - - else - value.push(params.push); - - } - if (params.unshift) value.unshift(...params.unshift); - if (params.pop) return value.pop(params.pop); - if (params.shift) return value.shift(params.shift); - - self.element({ path: params.name, value: value }); - - }; - - this.replace = function (params, args) { - // self.log("---- this.replace ----"); - params = self.replacePropertyWithPrefix(params, 'result', args); - /* self.log("params"); - self.log(params); */ - var value = self.element({ path: params.path }) || []; - var to = params.to || ''; - - var type = typeof value; - /* self.log("type"); - self.log(type); */ - if (type !== "string") value = JSON.stringify(value); - /* self.log("value 1"); - self.log(value); */ - if (params.from) value = self.replaceAll(value, params.from, to); - /* self.log("value2 "); - self.log(value); */ - switch (type) { - case "number": - value = Number(value); - break; - case "boolean": - value = Boolean(value); - break; - case "object": - value = JSON.parse(value); - break; - } - /* self.log("value 3"); - self.log(value); */ - //return value; - return self.element({ path: params.path, value: value }); - - }; - - - this.unshift = function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.unshift(value); - self.element({ path: path, value: obj }); - } - } - }; - - this.set = function (params, args) { - - if (Array.isArray(params)) { // 1.0.5 - for (var obj of params) - self.set(obj, args); - } else { - for (var param in params) { - - var value = params[param]; - - if (value) value = self.replaceProperties(value, args, false); // TO DO: check - if (value && args) value = self.replacePropertyWithPrefix(value, 'result', args); // backward compatibility TO DO: remove - - self.element({ path: param, value: value }); - } - } - - //return true - }; - - - this.get = function (element) { - //self.log('self.get'); - if (element.startsWith('\'')) - return String(element.match(/\'([^\']*)\'/)[1]); // stringa racchiusa tra apici (serve?) - else if (element.startsWith('Boolean')) - return Boolean(element.match(/Boolean\(([^\)]*)\)/)[0]); // Boolean(x) - else if (element.startsWith('Number')) - return Number(element.match(/Number\(([^\)]*)\)/)[0]); // Number(x) - else if (element.startsWith('String')) - return String(element.match(/String\(([^\)]*)\)/)[0]); // String(x) - - else - return (self.docElement(element)); // ora le tipizzazioni sono già in docElement grazie a eval - }; - - this.getJSON = function (url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'json'; - xhr.onload = function () { - var status = xhr.status; - if (status === 200) { - callback(null, xhr.response); - } else { - callback(status, xhr.response); - } - }; - xhr.send(); - }; - - /*--------------------- - var - ---------------------*/ - var database, auth, storage; - this.listeners = {}; - this.resizeActions = {}; - - /* var iconsFile; - - this.device = false; // touch device - this.touch = 'mousedown'; if (this.device) {this.touch = 'touchstart';} - - var animations = {}; - var tweenLoading; - - var tasksIntervals = {}; - var timedTasks = {'yearly':{},'monthly':{},'daily':{},'hourly':{}, '10mins':{}, '5mins':{}, '30mins':{}, '1min':{}, '30sec': {}, '10sec': {}, '1sec': {}}; */ - /* this.dateSelection; // = {day:0, month:0, year:0}; - this.timeSelection = {hour:0, min:0, sec:0, ampm:'AM', allday:true}; - this.timeSelectionCallback = null; */ - /*-------------------- - FIREBASE - --------------------*/ - //var firebaseInitialized = false; - this.firebaseVerifyUser = function (data) { - self.log('firebaseVerifyUser'); - //self.log(data); - //self.log(data.code); - if (self.params.oobCode) { - var oobCode = self.params.oobCode; - - auth.applyActionCode(oobCode).then(function (resp) { - // self.log('resp'); - // self.log(resp); - self.alert({ - //toast: true, - icon: "success", - title: "titVerifyEmail", - html: "msgVerifyEmail", - confirmButtonText: "btnOk", - //showCancelButton: false, - confirm: function () { - //self.reload(); - // self.do(data); - window.location.href = "/app/index.html"; - } - }); - }).catch(function (error) { - self.log('error'); - self.alert({ - icon: "error", - title: "titWarning", - html: error.code + " - " + error.message, - confirmButtonText: "btnOk", - //showCancelButton: false, - confirm: function () { - // self.reload(); - // self.do(data); - window.location.href = "/app/index.html"; - } - }); - }); - // verifica su auth - } - //data.code / data.params.code - //self.do(data); - self.do(data); - }; - - /* this.firebaseInit = function (data) { - self.log("firebaseInit"); - - if (json.setup && json.setup.firebase) { - //var.databaseURL = json.setup.firebase.databaseURL; - - firebase.initializeApp(json.setup.firebase); - database = firebase.database(); - auth = firebase.auth(); - // if (self.json.plugins['firebase-storage'].active) OR find in self.json.plugins name: 'firebase-storage' - //storage = firebase.storage(); - - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - // No user logged in - self.log('onAuthStateChanged:GUEST\n'); - // non bisognerebbe chiedere sempre di fare login - } else { - // User logged in - self.log('onAuthStateChanged:USER\n'); - self.log('name: '+self.user('displayName') + '\nemail: '+user.email + '\nuid: '+ user.uid); - } - //self.log('firebaseInitialized'); - //self.log(firebaseInitialized); - if (!firebaseInitialized) { - firebaseInitialized = true; - self.do(data); - } - }); - } else { - self.do(data); - } - } */ - this.sendMail = function (data) { - self.log('sendMail'); - - var emailParams = { - Host: "smtp.mailgun.com", - Username: "vito@nuvolaria.com", - Password: "bee02191be84c784a665fa98c61e03ce-915161b7-d32cb9d0", - From: data.from, - To: data.to, - Subject: data.subject, - Body: data.html - }; - - Email.send(emailParams).then( - message => self.alert({ - icon: 'success', - title: 'titEmailSuccess', - confirmButtonText: 'btnClose' - }) - ); - - /* - "from": "gianfrancoguglielmi@gmail.com", - "to": "vito.minchilli@gmail.com", - "subject": "Prova oggetto", - "html": "Prova testo", - "text": "Prova testo" -*/ - /* - var SERVER_NODEJS_BASEURL='https://app.fixo.io:4002'; - - var params = { - rom: data.from, - to: data.to, - subject: data.subject, - html: data.html, - text: data.text - }; - - $.ajax({ - type: "POST", - 'beforeSend': function(xhr) { - xhr.setRequestHeader('Accept', 'application/json'); - xhr.setRequestHeader('Content-Type', 'application/json'); - }, - data: JSON.stringify(params), - url: SERVER_NODEJS_BASEURL + '/sendMail', - success: function(data) { - self.log('sendMail SUCCESS'); - self.log(data); - self.do(data); - }, - error: function(error) { - self.log('sendMail ERROR'); - self.log(error); - self.do(data); - } - }); - */ - }; - - //var multipleFiles = []; - /* this.fileDownload = function (url) { - self.log('fileDownload'); - self.log(url); - - var fileArr = url.split('?'); - self.log(fileArr); - //var file = fileArr[0]; - var urlArr = fileArr[0].split('/'); - self.log(urlArr); - var name = urlArr[urlArr.length-1]; - self.log(name); - var token = self.getParameterByName('token', url); - self.log(token); - - window.location.href = '/app/php/proxy.php?name='+ name + '&url='+ url; - - } */ - /* this.fileUrl = function (params) { - // da nome file a l'url Firebase Storage inclusiva del token - self.log('fileUrl'); - self.log(params); - // self.log('storage'); - // self.log(storage); - if (storage) { - var storageRef = storage.ref(); - var pathReference = storageRef.child(params.user+'/'+params.name); - - pathReference.getDownloadURL().then(function(url) { - if (params.callback) params.callback(url); - }).catch(function(error) { - if (error && error.code && params.error) { - self.log(self.firebaseStorageError(error.code)); - params.error(error.code); - } - // A full list of error codes is available at - // https://firebase.google.com/docs/storage/web/handle-errors - }); - } else { - self.log('storage undefined'); - } - } */ - /* this.firebaseStorageError = function (errorCode) { - switch (errorCode) { - case 'storage/object-not-found': - // File doesn\'t exist - return 'File doesn\'t exist'; - case 'storage/unauthorized': - // User doesn\'t have permission to access the object - return 'User doesn\'t have permission to access the object'; - case 'storage/canceled': - // User canceled the upload - return 'User canceled the upload'; - case 'storage/unknown': - // Unknown error occurred, inspect the server response - return 'Unknown error occurred, inspect the server response'; - default: - return 'No error' - } - } */ - var x = [{ if: 3 }, function () { }, 3, []]; - - this.firebaseAddListener = function (params) { - /* self.log('firebaseAddListener'); - self.log(params); */ - // {path, orderByChild, equalTo} - //self.log(params.path); - if (database) { - // Aggiunge listener in ascolto su params.path che esegue params.action - if (params.action) { - if (!self.listeners[params.path]) self.listeners[params.path] = []; - /* alert('params.action:'+params.action); - alert('type params.action:' + typeof params.action); - alert(params.path+':'+JSON.stringify({ - action: params.action - })); */ - //if (Array.isArray(params.action)) - // self.listeners[params.path].concat(params.action); - //else - self.listeners[params.path].push(params.action); - } - /* if (params.success !== undefined) { - alert('params.success:'+params.success); - alert('type params.success:' + typeof params.success); - alert(params.path+':'+JSON.stringify({ - success: params.success - })); - self.listeners[params.path].push(params.success); - } */ - //self.log('params.path: '+ params.path); - //self.listeners[params.path] = params.action; - //alert(self.listeners[params.path]); - /* - - limitToFirst() Sets the maximum number of items to return from the beginning of the ordered list of results. - limitToLast() Sets the maximum number of items to return from the end of the ordered list of results. - - startAt() Return items greater than or equal to the specified key or value, depending on the order-by method chosen. - startAfter() Return items greater than the specified key or value depending on the order-by method chosen. - endAt() Return items less than or equal to the specified key or value, depending on the order-by method chosen. - endBefore() endBefore() Return items less than the specified key or value depending on the order-by method chosen. - equalTo() Return items equal to the specified key or value, depending on the order-by method chosen. - - orderByChild() Order results by the value of a specified child key or nested child path. - orderByKey() Order results by child keys. - orderByValue() Order results by child values. - orderByPriority() Order results by priority - - https://firebase.google.com/docs/reference/js/v8/firebase.database.Query - - */ - //Firestore.collection(collectionName).orderBy(field).where(field, ">=", keyword.toUpperCase()).where(field, "<=", keyword.toUpperCase() + "\uf8ff").get() - // https://medium.com/feedflood/filter-by-search-keyword-in-cloud-firestore-query-638377bf0123 - // https://firebase.google.com/docs/database/rest/retrieve-data?hl=it#range-queries - // startAt , endAt , limitToFirst , limitToLast o equalTo - //databaseReference.orderByChild('_searchLastName').startAt(queryText).endAt(queryText+"\uf8ff") - // where ("string, "in"/"not-in", array) - // https://firebase.google.com/docs/firestore/query-data/queries?hl=it#in_and_array-contains-any - var dbRef = database.ref(params.path); - dbRef.off(); - if (params.orderByChild) dbRef = dbRef.orderByChild(params.orderByChild); - if (params.orderByKey) dbRef = dbRef.orderByKey(params.orderByKey); - if (params.orderByValue) dbRef = dbRef.orderByValue(params.orderByValue); - if (params.equalTo) dbRef = dbRef.equalTo(params.equalTo); - if (params.startAt) dbRef = dbRef.startAt(params.startAt); - if (params.startAfter) dbRef = dbRef.startAfter(params.startAfter); - if (params.endAt) dbRef = dbRef.endAt(params.endAt); - if (params.endBefore) dbRef = dbRef.endBefore(params.endBefore); - if (params.limitToFirst) dbRef = dbRef.limitToFirst(params.limitToFirst); - if (params.limitToLast) dbRef = dbRef.limitToLast(params.limitToLast); - if (params.where) dbRef = dbRef.where(params.where[0], params.where[1], params.where[2]); // maybe params.where in enough - - var feedback = dbRef.on('value', firebaseEvent); - //console.log(feedback); - /* console.log('dbRef'); - console.log(dbRef); - */ - /* if (params.orderByChild && params.equalTo) - dbRef.orderByChild(params.orderByChild).equalTo(params.equalTo).on('value', firebaseEvent); - else - dbRef.on('value', firebaseEvent); */ - } else { - self.log('database undefined'); - // Restart the db - } - }; - - var firebaseEvent = function (snapshot) { - console.log(snapshot.val()); - var ref = snapshot.ref; - if (snapshot.val() !== undefined) { - var dbVal = snapshot.val(); - var path = snapshot.ref.toString(); - //if (!dbVal) dbVal = {}; - var pathArr = path.split(/\.\w+\//); - var dbPath = pathArr[1]; - self.log('firebaseEvent: ' + dbPath); - //if (var.databaseURL) dbPath = path.substr(var.databaseURL.length+1); - //else dbPath = path; - /* self.log('path: '+ path); - //self.log('var.databaseURL: '+ var.databaseURL); - self.log('dbPath: '+ dbPath); */ - if (dbVal) - self.localDbUpdate(dbVal, dbPath); - else { - var dbObj = self.element({ path: 'self.json.var.db.' + self.replaceAll(dbPath, '/', '.') }); - if (dbObj) - dbObj = null; - //delete dbObj; - } - - - //self.do(self.listeners[dbPath], dbVal); - } - }; - - this.localDbUpdate = function (newObj, dbPath) { - /* self.log('localDbUpdate'); - self.log(newObj); - self.log(dbPath); */ - //var path = newObj.path; - //delete newObj.path; - /* self.do( - { - var: { - name: "db."+self.replaceAll(dbPath, '/', '.'), - value: newObj, - //success: function () { - // self.do(self.listeners[dbPath], newObj); - //} - } - } - ); */ - //alert('db.'+self.replaceAll(dbPath, '/', '.')); - /* var dbUpdateAction = { - var: { - name: 'db.'+self.replaceAll(dbPath, '/', '.'), - value: newObj - //do: (self.listeners[dbPath] && self.listeners[dbPath].length > 0) ? self.listeners[dbPath] : undefined - } - }; - if (self.listeners[dbPath] !== undefined && self.listeners[dbPath] !== null && self.listeners[dbPath].length > 0) - dbUpdateAction.var.do = self.listeners[dbPath]; - - newObj.path = dbPath; - - self.do(dbUpdateAction, newObj); */ - // TO DO: decide l'utente dove salvare i dati - newObj = Object.fromEntries(Object.entries(newObj).reverse()); - - //newObj = Object.keys(newObj).reverse(); - self.element({ path: 'self.json.var.db.' + self.replaceAll(dbPath, '/', '.'), value: newObj }); - if (self.listeners[dbPath] !== undefined && self.listeners[dbPath] !== null && self.listeners[dbPath].length > 0) { - newObj.path = dbPath; - if (self.listeners[dbPath]) { - self.methods.firebaseEvent.action(newObj); - //self.do(self.listeners[dbPath], newObj); - self.do(self.listeners[dbPath], undefined, newObj); - } - } - - - }; - - - - this.firebaseRemoveListener = function (params) { - // Rimuove listener in ascolto su data.path - self.log('firebaseRemoveListener'); - if (self.listeners[params.path]) { - delete self.listeners[params.path]; - var dbRef = database.ref(params.path); - dbRef.off(); - } - }; - - // Rimuove un elemento del database - this.firebaseRemove = function (path, callback) { - self.log('firebaseRemove'); - self.log(path); - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.remove(function (error) { - //Dati impostati con successo - if (error == null) { - self.log('set SUCCESS'); - result = { success: true }; - } else { - self.log('set ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - // Write or replace data to a defined path - this.firebaseSet = function (path, value, callback) { - /* - set Write or replace data to a defined path, like messages/users/ - update Update some of the keys for a defined path without replacing all of the data - push Add to a list of data in the database. Every time you push a new node onto a list, your database generates a unique key, like messages/users// - transaction Use transactions when working with complex data that could be corrupted by concurrent updates - */ - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.set(value, function (error) { - //Dati impostati con successo - if (error == null) { - self.log('set SUCCESS'); - result = { success: true }; - } else { - self.log('set ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - // Update some of the keys for a defined path without replacing all of the data - this.firebaseUpdate = function (path, value, callback) { - self.log('firebaseUpdate'); - self.log('path'); - self.log(path); - self.log('value'); - self.log(value); - - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.update(value, function (error) { - //Dati impostati con successo - if (error == null) { - self.log('update SUCCESS'); - result = { success: true }; - } else { - self.log('update ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - // Add to a list of data in the database. Every time you push a new node onto a list, your database generates a unique key, like messages/users// - this.firebasePush = function (path, value, callback) { - self.log('firebasePush'); - self.log(path); - - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.push(value, function (error) { - //Dati impostati con successo - if (error == null) { - self.log('push SUCCESS'); - result = { success: true }; - } else { - self.log('push ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - - - // https://firebase.google.com/docs/database/security/rules-conditions - // tutte le get / o listeners / potrebbero essere basate su orderByChild("owner") - /* - rooms": { - // this rule applies to any child of /rooms/, the key for each room id - // is stored inside $room_id variable for reference - "$room_id": { - "topic": { - // the room's topic can be changed if the room id has "public" in it - ".write": "$room_id.contains('public')" - } - } - } - */ - /* this.firebaseQuery = function(params) { - self.log('firebaseQuery'); - self.log(params); - // path = 'users/'+self.user('email') - // value = 'guest' - var dbRef = database.ref(params.path); - - if (!params.result) params.result = {}; - if (params.value && !Array.isArray(params.value)) { - var buffer = params.value; - params.value = []; - params.value[0] = buffer; - } - //self.log('params.value'); - //self.log(params.value); - if (params.value && params.value.length > 0) { - var value = params.value.shift(); - //self.log('value'); - //self.log(value); - //self.log('params.key'); - //self.log(params.key); - dbRef.orderByChild(params.key).equalTo(value).once('value', (object) => { - self.log('object'); - self.log(object); - if(object) { - params.result = self.extend(params.result, object.val()); - if (params.value.length > 0) - self.firebaseQuery(params); - else - params.callback({ - success: true, - error: null, - data: params.result - }); - } else { - //self.log('firebaseQuery ERROR'); - //result = {success:false, error:8}; - params.callback({ - success:true, - error:null, - data: params.result - }); - } - }); - } else { - params.callback({success:false, error:null}); - } - } */ - this.firebaseGetPart = function (params) { - self.log('firebaseGetPart'); - let remotePath = self.replaceAll(params.localPath, '.', '/'); - - self.log('localPath:' + params.localPath); - //self.log('remotePath:'+remotePath); - if (self.partContainers[params.localPath]) { - self.partContainers[params.localPath].push(params); - } else { - self.partContainers[params.localPath] = []; - self.partContainers[params.localPath].push(params); - - dbRef = database.ref().child(remotePath); - - return dbRef.once('value').then(function (object) { - //Dati recuperati con successo - if (object) { - self.log('firebaseGetPart SUCCESS'); - self.log(object); - // local db update - if (object.val() !== undefined) { - window.dbVal = object.val(); - var dbVal = object.val(); - self.log('dbVal'); - self.log(dbVal); - if (dbVal !== null) { - let fullPath = object.ref.toString(); - let pathArr = fullPath.split(/\.\w+\//); // split on the domain extension - let dbPath = pathArr[1]; // path after the domain extension - let localPath = self.replaceAll(dbPath, '/', '.'); - //var dbPath = path.substr(var.databaseURL.length+1); - self.log('dbPath: ' + dbPath); - self.log('localPath: ' + localPath); - //self.log('self.partContainers[localPath]'); - //self.log(self.partContainers[localPath]); - self.element({ path: localPath, value: dbVal }); - for (partObj of self.partContainers[localPath]) { - /* self.log('partObj'); - self.log(partObj); */ - let part = self.replacePropertyWithPrefix(dbVal, 'setup', partObj.setup); - part = self.replacePropertyWithPrefix(part, 'arg', partObj.arg); - self.extendJsonFromElement(part); // or selectorParams - - - /* self.log('part'); - self.log(part); */ - self.html(part, partObj.container); - //self.run(part, partObj.container); - //self.run(dbVal, container); - } - } - } - } else { - self.log('firebaseGetPart ERROR'); - result = { success: false, error: 8 }; - } - //self.log(result); - //callback(result); - }); - } - }; - - - /* { - "database": { - "do": "get", - "path": "apps/dev/{setup:key}", - "on": { - "success": [ - { */ - this.firebaseIncrease = function (params) { - console.log('firebaseIncrease'); - self.firebaseGet(params.path, function (result) { - console.log(result); - if (result.success) { - if (result.data === null || result.data === undefined || typeof result.data == 'number') { - var counter = Number(result.data) + 1; - console.log('counter:' + counter); - self.firebaseSet(params.path, counter, function (result) { - if (result.success) { - self.log('firebaseIncrease SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - }); - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - }); - }; - - this.firebaseGet = function (path, callback) { - self.log('firebaseGet:' + path); - var result = { success: false, error: 7 }; - if (path) { - // try, if path is wrong "Uncaught TypeError: Cannot read properties of undefined (reading 'ref')" - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - - /* if (false) { //path == 'files') { - //alert(self.user('email')); - return dbRef.orderByChild('users/'+self.user('email')).equalTo('guest').on('value', (object) => { - //return dbRef.orderByChild('prefs/authorId').equalTo(self.user('uuid')).on('value', (object) => { - //return dbRef.orderByChild('users').equalTo(self.user('email')).on('value', (object) => { - //self.log(object); - //var user = object.val(); - //Dati recuperati con successo - if(object) { - result = {success:true, error:null, data: object.val()}; - } else { - self.log('get ERROR'); - //Errore recupero dati - result = {success:false, error:8}; - } - //self.log(result); - callback(result); - }); - } else { */ - // ATTENZIONE: va intercettato e loggato l'errore di accesso negato dalle regole - return dbRef.once('value').then(function (object) { - //Dati recuperati con successo - if (object) { - self.log('get SUCCESS'); - result = { success: true, error: null, data: object.val() }; - - // local db update - if (object.val() !== undefined) { - var dbVal = object.val(); - var path = object.ref.toString(); - if (!dbVal) dbVal = {}; - var pathArr = path.split(/\.\w+\//); // split on the domain extension - var dbPath = pathArr[1]; // path after the domain extension - - //var dbPath = path.substr(var.databaseURL.length+1); - self.log('dbPath: ' + dbPath); - self.localDbUpdate(dbVal, dbPath); - } - } else { - self.log('get ERROR'); - //Errore recupero dati - result = { success: false, error: 8 }; - } - //self.log(result); - callback(result); - }); - - //} - }; - - this.stringToKey = function (str) { - return str.replace(/\./g, '%2E'); - }; - - this.keyToString = function (key) { - return key.replace(/%2E/g, '.'); - }; - - this.firebaseKey = this.getKey = function (path) { - var dbRef = database.ref(path); - return dbRef.child(path).push().getKey(); - }; - - // -------------- - // SELECTOR - // -------------- - this.exist = function (selector) { - console.log('selector'); - console.log(selector); - console.log(Boolean(self.query(selector))); - return Boolean(self.query(selector)); - }; - - this.count = function (selector) { - //self.log('count:'+selector+ '='+ self.queryAll(selector).length); - return self.queryAll(selector).length; - - /* if (selector) { - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - var route = routes[index]; - - //onsole.log('route'); - //self.log(route); - - var routeParts = route.match(/(.*):eq\((\d*)\)/); - - //self.log('routeParts'); - //self.log(routeParts); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - element = element.querySelectorAll(routeElement)[routeIndex]; - - - } else { - element = element.querySelectorAll(route)[0]; - } - } */ - /* var elements = self.query(selector); - if (elements) - return elements.querySelectorAll().length; - else - return 0 */ - /* if (self.exist(selector)) - return document.querySelectorAll(selector).length; - else - return 0 */ - }; - - var log = function (id, value) { - self.log(id); - self.log(value); - }; - - this.classSelector = function (selClass) { - if (selClass.indexOf('.') == 0) { selClass = String(selClass).substr(1); } // backward compatibility - let classes = selClass.split(' '); - selClass = classes[0]; - /* self.log('selClass'); - self.log(selClass); */ - // avoid dynamic classes as selector - var regex = new RegExp('[\-][\[]'); - if (selClass && selClass.match(regex)) selClass = classes[1]; - if (selClass && selClass.match(regex)) selClass = classes[2]; - return selClass; - }; - - this.selector = function (params, containerParams, selectAll) { - // {container, class, value, id} - var selector; - - if (params) { - - if (typeof params == 'string') { - /* self.log('this.selector'); - self.log(params); */ - return params; - } else if (Array.isArray(params)) { - return params; - } else { - var selContainer; - - if (params.selector || params.container) - selContainer = params.selector || params.container; - - else if (containerParams) - selContainer = containerParams.selector || containerParams.container; - - //var selContainer = container; //data.container; - var attr = (params.attr) ? params.attr : {}; - var selId = (attr.id) ? attr.id : params.id; - var selClass = (attr.class) ? attr.class : params.class; - var selValue = (attr.value) ? attr.value : params.value; - var selDataValue = (attr['data-value']) ? attr['data-value'] : params['data-value']; - selValue = selDataValue || selValue; - if (selId) selId = self.replaceProperties(selId); - if (selValue) selValue = self.replaceProperties(selValue); - if (selClass) selClass = self.replaceProperties(selClass); - /* if (selId) selId = self.compile(selId); - if (selValue) selValue = self.compile(selValue); - if (selClass) selClass = self.compile(selClass); */ - // use the first class as selector - if (selClass) - selClass = self.classSelector(selClass); - - //if (!selectAll) selClass = undefined; - if (selId) { - selector = '#' + selId; - } else if (selValue && selClass) { - selector = '.' + selClass + '[data-value="' + selValue + '"]'; - } else if (selValue && params.tag) { - selector = params.tag + '[data-value="' + selValue + '"]'; - } else if (selClass && selectAll) { - selector = '.' + selClass; - - //if (!selectAll) - // selector += ':eq(' + self.count(selector) + ')'; - // qui c'è / c'era un baco: - // quando proviamo a eseguire un'azione su un elemento esistente - // usando solo la classe come selector, $(selector).length = 1 - // quindi prova a selezionare il secondo elemento eq(1), non il primo eq(0) - } else if (params.tag) { - //if (selContainer) selector = selContainer; - selector = params.tag; - if (selContainer) { - selector = selContainer + ' > ' + params.tag; - if (!selectAll) { - - //if (count !== $(selector).length) self.log('>> '+ selector + ' count:'+ self.count(selector) + ' !== ' + $(selector).length ); - selector += ':eq(' + self.count(selector) + ')'; - //selector += '[' + self.count(selector) + ']'; - //selector += ':eq(' + $(selector).length + ')'; - } - } else { - if (!selectAll) { - selector += ':eq(' + self.count(selector) + ')'; - //selector += '[' + self.count(selector) + ']'; - } - } - } else { - selector = selContainer; - }; - - } - return selector; - } - }; - - // -------------- - // TEXTS - // -------------- - this.stringify = function (obj) { - if (typeof obj == 'object') - try { - return JSON.stringify(obj); - } catch (error) { - return obj; - } - - else - return obj; - - }; - - this.parse = function (str) { - if (typeof str == 'string') - try { - return JSON.parse(str); // json - } catch (error) { - return str; // non json - } - - else - return str; - }; - - /* this.removeEventProperties = function (params) { - var paramsObj = self.cloneObject(params); - if (paramsObj && paramsObj.on) { - paramOn = self.cloneObject(paramsObj.on); - delete paramsObj.on; - } - if (paramsObj && paramsObj.success) { - paramSuccess = self.cloneObject(paramsObj.success); - delete paramsObj.success; - } - return paramsObj; - }; */ - - - self.setupId = 0; - - this.replacePropertyWithPrefix = function (params, prefix, args) { - - var paramsString; - - if (typeof params == 'object') - paramsString = self.stringify(params); - - else - paramsString = String(params); - - /* let argsWithProperties = (args) ? JSON.stringify(args) : ''; - paramsString = self.replaceAll(paramsString, '"{'+prefix+'}"', argsWithProperties); // obsolete */ - //if (typeof args == undefined) - // self.log('replacePropertyWithPrefix args is undefined', 'yellow'); - if (paramsString && paramsString.indexOf('{' + prefix) >= 0) { - paramsString = paramsString.replace(new RegExp('"{' + prefix + '[:\\s]?([\\w\\d\\s\\.\\|]*)}"', 'g'), function (match, path) { - if (path) { - let value = self.replaceUndefined({ match: match, path: path, root: args, removeUndefined: true }); - //let value = self.element({path:path, root: args}); - /* if (typeof value == undefined) { - self.log(match + ' not found', 'orange'); - value = ''; - } else */ - if (value === undefined) { - return '""'; - } else if (typeof value == 'object') - return JSON.stringify(value); - else if (typeof value == 'string') - return '"' + value + '"'; - - else - return value; - } else { - if (typeof args == 'object') - return JSON.stringify(args); - else if (typeof args == 'string') - return '"' + args + '"'; - - else - return args; - } - }); - - /* if (paramsString && paramsString.indexOf('Contacts')>= 0) { - self.log(paramsString, 'green'); - } */ - paramsString = paramsString.replace(new RegExp('{' + prefix + '[:\\s]?([\\w\\d\\s\\.]*)}', 'g'), function (match, path) { - if (path) { - let value = self.replaceUndefined({ match: match, path: path, root: args, removeUndefined: true }); - //let value = self.element({path:path, root: args}); - /* if (typeof value == undefined) { - self.log(match + ' not found', 'orange'); - value = ''; - } else */ - if (value === undefined) - return ''; - else if (typeof value == 'object') // when object inside a string? - return JSON.stringify(value); - - else - return value; - } else { - if (typeof args == 'object') - return JSON.stringify(args); - - else - return args; - } - }); - - if (self.isJsonString(paramsString)) { - var paramsObj = self.parse(paramsString); - return paramsObj; - } else { - return paramsString; - } - } else { - return params; - } - - }; - - /* this.replaceProperty = function (params, name, args) { // TO DO: change name in replaceArguments - //console.log('replaceProperty:'+name); - //var actions = {}; - - if (typeof params == 'object') { - - params = self.stringify(params); - } - - if (typeof args !== 'string') { - - let argsWithProperties = (args) ? JSON.stringify(args) : ''; - params = self.replaceAll(params, '"{'+name+'}"', argsWithProperties); // obsolete - - // TO DO: get self.element({path:key, root: args}); - - for (let key in args) { - if (typeof args[key] !== undefined) { - if (typeof args[key] == 'object') - params = self.replaceAll(params, '"{'+name+' '+key+'}"', JSON.stringify(args[key])); - else - params = self.replaceAll(params, '{'+name+' '+key+'}', args[key]); - } else { - params = self.replaceAll(params, '{'+name+' '+key+'}', ''); - self.log('{'+name+' '+key+'}' + ' not found', 'yellow'); - } - } - - for (let key in args) { - if (args[key]) { - if (typeof args[key] == 'object') - params = self.replaceAll(params, '"{'+name+':'+key+'}"', JSON.stringify(args[key])); - else - params = self.replaceAll(params, '{'+name+':'+key+'}', args[key]); - } else { - params = self.replaceAll(params, '{'+name+':'+key+'}', ''); - } - } - - } else { - //console.log('args STRINGA'); - - params = self.replaceAll(params, '{'+name+'}', args); - - } - - if (self.isJson(params)) {// (typeof params == 'object') - var paramsObj = self.parse(params); - return paramsObj; - } else { - //alert(paramsString); - return params; - } - - } - */ - this.replaceResult = function (params, args) { - - var paramOn, paramSuccess, paramError; - - if (typeof params == 'object') { - var paramsObj = self.cloneObject(params); - if (paramsObj && paramsObj.on) { - paramOn = self.cloneObject(paramsObj.on); - delete paramsObj.on; - } - if (paramsObj && paramsObj.success) { - paramSuccess = self.cloneObject(paramsObj.success); - delete paramsObj.success; - } - - params = self.stringify(params); - } - - if (typeof args !== 'string') { - params = self.replaceAll(params, '"{result}"', JSON.stringify(args)); - } else { - params = self.replaceAll(params, '{result}', args); - } - - /* self.log('replaceResult'); - self.log('params'); - self.log(params); */ - if (self.isJson(params)) { // (typeof params == 'object') - var paramsObj = self.parse(params); - if (paramOn) paramsObj.on = paramOn; - if (paramSuccess) paramsObj.success = paramSuccess; - if (paramError) paramsObj.error = paramError; - return paramsObj; - } else { - //alert(paramsString); - return params; - } - - }; - - /* - this.replaceTags = function (params, selectorParams) { - self.log('replaceTags'); - var undef = false; - - if (params.text && (typeof params.text == 'string' || typeof params.text == 'object')) { - //alert(params.text); - - params.text = self.stringify(params.text); - - // i tag speciali sono contenuti tra i caratteri { e } - if (params.text.indexOf('{') >= 0) { - // alert(params.text.indexOf('{')); - - // <{visible:element}> - params.text = params.text.replace(/\<\{visible\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = ($(p1).is(':visible')); - return value; - }); - - // <{var:var.object}> - params.text = params.text.replace(/\<\{this\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.json[p1]; - if (!value) undef = true; - return self.stringify(value); - }); - - // <{data:value}> - params.text = params.text.replace(/\<\{data\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.json.var[p1]; - if (!value) undef = true; - return self.stringify(value); - }); - - params.text = params.text.replace(/\<\{var\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.get(p1); - if (!value) undef = true; - return self.stringify(value); - }); - - params.text = params.text.replace(/\<\{param\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.params[p2]; - if (!value) undef = true; - return value; - }); - - // <{value:[id]}> - params.text = params.text.replace(/\<\{value\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = $('#'+p1).val(); - // https://www.geeksforgeeks.org/html-value-attribute/ - if (!value) undef = true; - return value; - }); - - // <{user:[fieldName]}> - params.text = params.text.replace(/\<\{user\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.user(p1); - if (!value) undef = true; - return self.stringify(value); - }); - - // <{time:timestamp}> - params.text = params.text.replace(/\<\{time\:timestamp\}\>/g, self.getTimestamp()); - - // <{result}> - if (params.args) { - params.args = self.stringify(params.args); - params.text = params.text.replace(/\<\{result\}\>/g, params.args); - } - - // <{function:app.mac}> - params.text = params.text.replace(/\?/g, function(match, p1, offset, string) { - var functionName = self.docElement(p1); - return functionName(selectorParams); - }); - - // <{random}> - params.text = params.text.replace(/\<\{random\:([^\-]+)\-([^\}]+)\}\>/g, function(match, p1, p2, offset, string) { - return Number(p1)+Math.round((p2-p1)*Math.random()); - }); - - // <{firebaseKey:path}> - params.text = params.text.replace(/\<\{firebaseKey\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - return self.firebaseKey(p1); - }); - - } - if (undef) return undefined - else return self.parse(params.text); - - } else { - //self.log('params.text undefined or number or boolean'); - return params.text; - } - } */ - this.langText = function (textId) { - // find text in language and follow the capitalization of textId - // we could need text in langId language - - if (textId) { - var textValue = textId; - if (typeof textId == 'string') { - if (self.json.texts[textId]) { - textValue = self.json.texts[textId]; - if (typeof textValue == 'object') - textValue = textValue[self.json.setup.language] || textValue['en'] || textValue[Object.keys[0]]; - } - else - textValue = textId; - } else if (typeof textId == 'object') { - textValue = textId[self.json.setup.language] || textId['en'] || textId[Object.keys[0]]; - //textValue = textObj[langId] || textObj[self.json.setup.language] || textObj['en']; - } - return textValue; - } else { - return textId; - } - - /* if (self.json.texts[textId]) - textObj = self.json.texts[textId]; - else if (self.json.texts[textId.toLowerCase()]) - textObj = self.json.texts[textId.toLowerCase()]; - //else if (self.json.texts[textId.toUpperCase()]) - // textObj = self.json.texts[textId.toUpperCase()]; - if (textObj) { - var textValue = textObj[self.json.setup.language] || textObj['en'] || textId; - if (textId.charAt(0) == textId.charAt(0).toUpperCase()) // first char uppercase - if (textId.charAt(1) == textId.charAt(1).toUpperCase()) - return textValue.toUpperCase(); - else - return textValue.replace(/\b\w/, l => l.toUpperCase()); // capitalize - // textValue = textValue.charAt(0).toUpperCase() + name.slice(1) - // style: text-transform: capitalize; - else - return textValue.toLowerCase(); - } else { - return textId; - } */ - /* } else { - self.log('textId undefined in langText'); - } */ - }; - - this.lang = function (params, args) { - if (args) { - var value = self.replaceProperties(params, args); - self.json.setup.language = value; - //alert(value); - self.log('lang'); - self.log(value); - - document.querySelectorAll('[data-text]').forEach(function (element, index) { - //$('*[data-text]').each(function( index ) { - var dataParams = self.dataStorage.get(element, 'params'); - var selector = self.dataStorage.get(element, 'selector'); - /* self.log('index'); - self.log(index); - self.log('dataParams'); - self.log(dataParams); - */ - //alert(JSON.stringify(dataParams)); - self.html(dataParams, { selector: selector }); - //self.text($(this).data('params'), {container: this}); - }); - - /* - var elements = document.querySelectorAll('[data-text]'); - self.log('elements'); - self.log(elements); - //var elements = document.querySelectorAll(selector); - if (elements) - elements.forEach(function (element, index) { - self.log(index); - //var dataParams = self.dataStorage.get(element, 'params'); - var dataSelector = self.attribute(element, 'data-selector'); - //self.text(dataParams, {container: dataSelector}); - self.text($(dataSelector).data('params'), {container: dataSelector}); - - }); - */ - } else { - return self.json.setup.language; - } - }; - // Determine whether is possible to write an image/text to the clipboard. - var isClipboardWritingAllowed = function () { - return new Promise(function (resolve, reject) { - try { - navigator.permissions.query({ name: "clipboard-write" }).then(function (status) { - // PermissionStatus object - // { - // onchange: null, - // state: "granted" (it could be as well `denied` or `prompt`) - // } - self.log(status); - - resolve((status.state == "granted")); - }); - } catch (error) { - // This could be caused because of a Browser incompatibility or security error - // Remember that this feature works only through HTTPS - reject(error); - } - }); - }; - - this.codeSearch = function (params) { - let selector = params.selector || params.container; - // {container, word} - if (selector && params.word) { - var element = self.query(selector); - var editor = ace.edit(element); - - var range = editor.find(params.word, { - wrap: true, - caseSensitive: true, - wholeWord: true, - regExp: false, - preventScroll: false // do not change selection - }); - editor.session.selection.clearSelection(); - editor.setOption("highlightActiveLine", true); - - - /* range.start.column = 0; - range.end.column = Number.MAX_VALUE; - //editor.session.replace(range, "x" + editor.session.getLine(range.start.row) + "x"); - editor.selection.setRange(range); */ - } - }; - - - this.ace = function (params, selectorParams) { - // https://codepen.io/zymawy/pen/XwbxoJ - //self.log('code'); - //self.log(params); - var selector = params.selector || params.container; - var container = selector || self.selector(selectorParams); - - //paramsReplaced = self.cloneObject(params); - //paramsReplaced.value = self.actionResult(paramsReplaced.value); - var value = params.value; - - // item from library - if (params.blocks && self.json.blocks) - if (self.json.blocks[params.blocks]) - value = self.json.blocks[params.blocks]; - - else - self.log('"code" method can\'t find in "blocks" the element ' + params.blocks); - // json file - if (params.module) { - let moduleName = self.replaceProperties(params.module); - if (moduleName && self.modules[moduleName] !== undefined) { - value = self.modules[moduleName]; - - /* self.log('value'); - self.log(value); - self.log(value); */ - } - else - self.log('"code" method can\'t find the file ' + params.file); - } - if (params.var) - if (self.json.var) - value = self.var(params.var); - - else - self.log('"code" method can\'t find the variable ' + params.blocks); - - var element = self.query(container); - //var containerId = $(container).attr('id'); - //self.log('containerId'); - //self.log(containerId); - //var containerId = $(container).attr('id'); - if (element) { - - //var containerId = self.attribute(element, 'id'); // or assign a random unique id - var editor = ace.edit(element); - - /* var keywordMapper = this.createKeywordMapper({ - "tag" : 'div|ul|p|a|button|input|span|img|video|audio|source|figure|figcaption|textarea|iframe|table|thead|tbody|tfoot|tr|th|td|svg|small|h1|h2|h3|h4|h5|h6|form|form-group|label|select|option|optgroup|nav|lottie-player|qrcode|tab|model-viewer' - }, "identifier"); */ - /* var staticWordCompleter = { - getCompletions: function(editor, session, pos, prefix, callback) { - var wordList = ['div', 'ul', 'p', 'a', 'button', 'input', 'span', 'img', 'video', 'audio', 'source', 'figure', 'figcaption', 'textarea', 'iframe', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'svg', 'small', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'form', 'form-group', 'label', 'select', 'option', 'optgroup', 'nav', 'lottie-player', 'qrcode', 'tab', 'model-viewer']; - callback(null, wordList.map(function(word) { - return { - caption: word, - value: word, - meta: "static" - }; - })); - - } - } - - //langTools.setCompleters([staticWordCompleter]) - // or - editor.completers = [staticWordCompleter] */ - /* if (editor) - AceColorPicker.load(ace, editor); */ - //var value = paramsReplaced.value; // else value = params; - if (!params.do || (params.do == 'set')) { - - //var langTools = ace.require('ace/ext/language_tools'); - if (params.theme) - editor.setTheme(params.theme); // "ace/theme/monokai" - var editorMode = params.mode || "ace/mode/json"; - editor.getSession().setMode(editorMode); - - if (params.options) - editor.setOptions(params.options); - //AceColorPicker.load(ace, editor, {hideDelay: 1000}); - //import AceColorPicker from 'ace-colorpicker'; - /* editor.getSession().setMode(editorMode, () => { - AceColorPicker.load(ace); // , {hideDelay: 1000} - }); */ - var editorStyle = self.extend({ - //background: "rgba(255,255,255,0)" - }, params.style); - //$(container).css(editorStyle); //editor.container.style - self.css({ - style: editorStyle - }, { - selector: container - }); - - //var aceOptions = params.options; - /* var aceOptions = self.extend({ - fontSize: "12pt", - selectionStyle: "line", - //showGutter: false, - highlightGutterLine: false, - fixedWidthGutter: false, - //vScrollBarAlwaysVisible: true, - tabSize: 3, - //readOnly: true, - //enableBasicAutocompletion: false, - //enableSnippets: false, - //enableLiveAutocompletion: false, - }, params.options); */ - // https://github.com/ajaxorg/ace/wiki/Configuring-Ace - var codeString; - if (typeof value == 'string') - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(JSON.parse(value), null, '\t'); // json formatting - - else - codeString = value; - else { - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(value, null, '\t'); - else { - var functionObj = self.docElement(value.function); //? - var functionParams = value.params; - codeString = functionObj(functionParams); - } - } - - // should be {lines:dividcode} - if (codeString) { - var codeRows = codeString.split(/\r\n|\r|\n/).length; - /* $(container).css({ - height: Number(21 * (codeRows)) + 'px' - }); */ - /* self.log('element'); - self.log(element); - self.log('container'); - self.log(container); - self.log('codeRows'); - self.log(codeRows); */ - element.style.height = Number(21 * codeRows) + 'px'; - - - //element.querySelector('.ace_scroller').querySelector('.ace_content').height = Number(21 * codeRows) + 'px'; - /* self.css({ - style: { - height: Number(21 * codeRows) + 'px' - } - }, { - container: container - }); */ - editor.setValue(codeString, -1); // -1 unselect the code - - - - //editor.renderer.updateFull(true); - //AceColorPicker.load(ace, ace.edit(containerId)); - self.uiUpdate(); // resize event trigger - - - // workaround known ACE bug (.ace_content element doesn't follow the height until window resize) - } - - if (params.on) { - - var containerId = self.attribute(element, 'id'); // or assign a random unique id - self.codeChangeFunctions[containerId] = params.on; - //self.editorChangeFunctions[editor.id] = params.on; - if (params.on.change) { - editor.on('change', function (event, obj) { - /* self.log('event'); - self.log(event); - self.log('obj'); - self.log(obj); */ - if (self.isJson(obj.getValue())) { - var code = JSON.parse(obj.getValue()); - var action = self.codeChangeFunctions[obj.container.id].change; - //var methods = self.replaceResult(action, code); - var methods = self.replaceResult(action, code); - - //var methods = self.replaceProperties(action, code); - // check on jsonic.io/play (methods is string instead of object) - /* self.log('code'); - self.log(code); - self.log('method'); - self.log(method); - self.log('-------------'); */ - //self.do(methods); - self.do(methods); - //self.do(code, self.editorChangeFunctions[obj.id]); - //var container = self.editorChangeFunctions[obj.id].change.container; - } else { - // syntax error - } - //self.do(self.editorChangeFunctions[obj.id].change, JSON.parse(obj.getValue())); - //self.log(obj); - //self.blocks(JSON.parse(obj.getValue()), {container: }); - }); - } - - // save key - // https://michilehr.de/overwrite-cmds-and-ctrls-in-javascript - } - - - } else if (params.do == 'get') { - return JSON.parse(editor.getValue()); - - } else if (params.do == 'update') { - - self.uiUpdate(); // resize event trigger - - - // workaround known ACE bug (.ace_content element doesn't follow the height until window resize) - } else if (params.do == 'search') { - if (params.word) { - var range = editor.find(params.word, { - wrap: true, - caseSensitive: true, - wholeWord: true, - regExp: false, - preventScroll: false // do not change selection - }); - editor.session.selection.clearSelection(); - editor.setOption("highlightActiveLine", true); - /* range.start.column = 0; - range.end.column = Number.MAX_VALUE; - //editor.session.replace(range, "x" + editor.session.getLine(range.start.row) + "x"); - editor.selection.setRange(range); */ - } - } else if (params.do == 'find') { - // toggle - editor.execCommand('find'); - //editor.searchBox.show(); - } else if (params.do == 'copy') { - // Select the whole content of the editor - editor.selectAll(); - // Store text that will be copied to clipboard - let copyText = editor.getCopyText(); - // Verify if clipboard writing is allowed - isClipboardWritingAllowed().then(function (allowed) { - // Write to clipboard if allowed - if (allowed) { - navigator.clipboard.writeText(copyText).then(function () { - editor.getSession().selection.clearSelection(); - //self.log("Code copied!"); - }); - } - }).catch(function (err) { - self.log("Cannot copy to clipboard", err); - }); - } else { - self.log('"code" function requires value param'); - } - } else { - self.log('"code" method can\'t select the container'); - self.log('container'); - self.log(container); - self.log('element'); - self.log(element); - } - - }; - - // TO DO: should be in the app var and reset on a new execution - this.codeChangeFunctions = {}; - this.editorChangeFunctions = {}; - this.quillElements = {}; - - this.text = function (params, selectorParams, args) { - /* - { - "text": / "string": / textId -> textId "{text:textId}" - "case": [up, down, capitalize] - } - */ - - - /* if (Array.isArray(params)) { - for (var obj of params) - self.text(obj, selectorParams, args); - } else { */ - var textKey; - var textCase; - var textArgs; - var textLang; - var langId; - var selector, element; - //var textAction; - if (typeof params == 'object') { - - if (selectorParams && selectorParams.isConnected) { // Check if an element is attached to DOM - element = selectorParams; - //selector = self.dataStorage.get(element, 'selector'); - //selector = element.getAttribute('data-selector'); - selector = self.elementToSelector(element); // 1.0.12 - } else { - selector = self.selector(self.extend({}, params, selectorParams)); - element = self.query(selector); - } - - // todo: REMOVE (check the menu) - //textAction = self.actionResult(params, textArgs); - //textAction = params; - //textKey = params.string; // || params.text || params.title; // params.key to be removed? - textCase = params.case; // use text-transform uppercase lowercase capitalize - textArgs = params.args; // deve diventare args (secondo parametro) al posto di caseFunction - - - //langId = params.langId; - if (typeof params == 'object') { - - textKey = params.key || params.string || params; // || params.text || params.title; // params.key to be removed? - - - - - - - //textCase = params.case; // use text-transform uppercase lowercase capitalize - //textArgs = params.args; // deve diventare args (secondo parametro) al posto di caseFunction - //langId = params.langId; - } else { - textKey = params; - } - - /* self.log('textKey'); - self.log(textKey); */ - } else if (typeof params == 'string') { - textKey = params; - - /* self.log('textKey'); - self.log(textKey); */ - //textCase = caseFunction; - if (selectorParams) { - if (selectorParams.isConnected) { // Check if an element is attached to DOM - element = selectorParams; - selector = self.dataStorage.get(element, 'selector'); - } else { - selector = self.selector(selectorParams); - element = self.query(selector); - } - } else { - // here when windowTitle += ' ' + self.text(page.title); // window title - } - } - - if (typeof textKey == 'string') { - - /* // TO DO: remove - if (textKey.startsWith('js:')) textKey = self.js(textKey.substr(3)); - else if (textKey.startsWith('db:')) textKey = self.element({path: 'var.db.'+textKey.substr(3)}); - else if (textKey.startsWith('var:')) textKey = self.element({path: 'var.'+textKey.substr(4)}); - else if (textKey.startsWith('data:')) textKey = self.element({path: 'data.'+textKey.substr(5)}); - else - // ----- */ - /* console.log('textKey'); - console.log(textKey); */ - textKey = self.replaceProperties(textKey, textArgs); - /* console.log('textKey'); - console.log(textKey); */ - } - - //self.log('selector'); - //self.log(selector); - //self.log(selector.isConnected); - /* self.log('HOTSPOT'); - self.log(params); - self.log(self.json.setup.language); */ - if (params && params.lang) { // multi-language text - - //self.log('params.lang definito'); - textLang = self.langText(params.lang); // , langId - - //textLang = params.lang[self.json.setup.language] || params.lang['en'] || params.lang[Object.keys[0]]; - textLang = self.replaceProperties(textLang, textArgs); - - /* self.log('textLang'); - self.log(textLang); - self.log('element'); - self.log(element); */ - if (textCase) textLang = self.textCase(textLang, textCase); - - //self.log('textLang'); - //self.log(textLang); - if (element) { - element.textContent = textLang; - self.attribute(element, 'data-text', true); // textKey instead of lang? - self.dataStorage.set(element, 'params', params); - //$(selector).data('params', params); - } - - } else { - //self.log('params.lang non definito'); - //if (!textKey) textKey = params; - if (textKey) { - //textKey = self.compile(textKey, textArgs); // TO DO: verify - /* self.log('textKey'); - self.log(textKey); */ - //if (!textKey) alert(JSON.stringify(params)); - //if (typeof textKey == 'object') { - // textLang = JSON.stringify(textKey, null, '\t'); - //} else { - //textLang = params.lang[self.json.setup.language] || params.lang['en'] || params.lang[Object.keys[0]]; - if (textKey.lang) // multi-language text - textLang = self.langText(textKey.lang); // , langId - - else - textLang = textKey; - - /* self.log('textLang1'); - self.log(textLang); */ - textLang = self.replaceProperties(textLang, textArgs); // move after textLang = self.langText(textKey.lang); - if (textCase) textLang = self.textCase(textLang, textCase); - - //} - /* self.log('textLang2'); - self.log(textLang); */ - //if (selector) { // set - if (element) { // set - - if (self.json.texts[textKey]) { - // save data-text for lang change - //$(selector).data('params', params); - //$(selector).attr('data-text', textKey); - self.attribute(element, 'data-text', true); - self.dataStorage.set(element, 'params', params); - } - - // obsolete - /* if (params.background) $(selector).css({'background': params.background}); - if (params.color) $(selector).css({'color': params.color}); - if (params.size) $(selector).css({'font-size': params.size}); */ - if (params.style) - self.css({ - style: params.style - }, { - selector: selector - }); - //$(selector).css(params.style); - element.textContent = textLang; // put text in element - - - //$(selector).text(textLang); - } else { // get - return textLang; - } - - } else { - /* self.log('"string" parameter required in text object'); - self.log(params); */ - return params; - } - - } - - }; - - var caseUp = function (string) { - return string.toUpperCase(); - }; - - var caseDown = function (string) { - return string.toLowerCase(); - }; - - var capitalize = function (string) { - return self.capitalize(string); - }; - - this.textCase = function (textParam, caseParam) { - if (textParam) { - var text = textParam; - switch (caseParam) { - case 'up': - text = text.toUpperCase(); - break; - - case 'down': - text = text.toLowerCase(); - break; - - case 'capitalize': - text = self.capitalize(text); - break; - } - return text; - } else { - self.log('textParam undefined in textCase'); - } - }; - - /* this.textFit = function (selector,params) { - if (params.alignHoriz == undefined) { - params.alignHoriz = true; - } - if (params.alignVert == undefined) { - params.alignVert = true; - } - if (params.minFontSize) { - params.minFontSize = parseInt(params.minFontSize, 10); // remove px - } - if (params.maxFontSize) { - params.maxFontSize = parseInt(params.maxFontSize, 10); // remove px - } - - // textFit va in errore se l'oggetto diventa invisibile - // mentre sta elaborando la dimensione del testo - if (!$(selector).children('span').hasClass('textFitted')) { - $(selector).each(function(i, obj) { - if ($(obj).is(":visible") - && ($(obj).css("display") !== 'none') - && ($(obj).css('width')) - && ($(obj).css('height'))) { - textFit($(obj), params); - } - }); - } - } */ - /* this.data = function (path, value) { - if (!value) return self.json.var; - } - - this.setvar = function (data) { - var = self.data(); - self.data(data); - } */ - // -------------- - // PAGES - // -------------- - /* this.lastInteraction = function () { - // uso: self.lastInteraction().asMinutes() - var lastInteraction = 0; - if (var.touchTime) lastInteraction = moment(var.touchTime); - var thisMoment = moment(); - var duration = moment.duration(thisMoment.diff(lastInteraction)); - return duration - } */ - // -------------- - // icons e - // -------------- - /* this.icons = this.icon = function (params, selectorParams, args) { - // { [container, class, value, id] - // [html, text, append, prepend] } - - if (Array.isArray(params)) { - for (var index in params) - {self.icons(params[index], selectorParams);} - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.icons(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - - //if (selectorParams) params = self.extend(params, selectorParams); - - var paramsReplaced = self.replaceProperties(params, args); - - self.log('icons'); - self.log('paramsReplaced'); - self.log(paramsReplaced); - - if (paramsReplaced) { - if (paramsReplaced.disabled == true) - self.disableIcon(paramsReplaced, selectorParams); - else if (paramsReplaced.disabled == false) - self.enableIcon(paramsReplaced, selectorParams); - else if (paramsReplaced.change) - self.changeItem(paramsReplaced, selectorParams); - else - self.addItem(paramsReplaced, selectorParams); - } - - if (paramsReplaced.firebase) self.addFirebaseTag(paramsReplaced); - - var selector = self.selector(self.extend(paramsReplaced, selectorParams)); - - if (paramsReplaced.span) // text near icon - self.addTag(paramsReplaced, {container: selector}); - - } - } - } */ - /* this.buttons = this.tab = function (params, selectorParams) { - - // { [container, class, value, id] - // [html, text, append, prepend] } - if (Array.isArray(params)) { - for (var index in params) - self.tab(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.tab(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - - // se necessario, replaceProperties dovrebbe escludere il contenuto di events/action - // in quanto verrà ripetuto sulle azioni in tempo reale solo dove necessario - //params = self.replaceProperties(params); - - if (!params.class) params.class = ''; - var classes = params.class.split(' '); - - if (params.change) { - if (classes.includes('icon')) - self.changeItem(params, selectorParams); - else // if (classes.includes('tabs')) - self.changeTab(params, selectorParams); - } else { - if (classes.includes('icon')) - self.addItem(params, selectorParams); - else // if (classes.includes('tabs')) - self.addTab(params, selectorParams); - } - - if (params.firebase) self.addFirebaseTag(params); - - } - } - } - */ - /* - this.replacePropertyNew = function (params, name, args) { - console.log('replacePropertyNew'); - // like replaceProperties but only for {name:...} property - var paramsString; - - if (typeof paramsString !== 'string') {paramsString = JSON.stringify(self.cloneObject(params));} - - // remove string quotes for object property - if (args && paramsString && paramsString.indexOf('{')>= 0) { - //if (args && paramsString && /{\w/.test(paramsString)) { - paramsString = paramsString.replace(/\"\{(\w+\:)?([\w\s\.\:]+)\}\"/g, function(match, p1, p2, offset, string) { - var value; - if (p1 && p1.endsWith(':')) {p1 = p1.slice(0, -1);} - console.log('match:'+match); - console.log('p1:'+p1); - console.log('p2:'+p2); - if (p1 == name || (!p1 && p2 == name)) { - let nameFound = p1 || p2; - let pathFound = (p1) ? p2 : undefined; - console.log(nameFound+':'+pathFound); - if (typeof args !== 'string') { - //return self.replaceAll(self.stringify(args), '\"', '\''); - return self.stringify(args); - } else { - return '"' + args + '"'; - } - } else - return match; - }); - //console.log('paramsString without quotes'); - //console.log(paramsString); - paramsString = paramsString.replace(/\{(\w+\:)?([\w\s\.\:]+)\}/g, function(match, p1, p2, offset, string) { - var value; - if (p1 && p1.endsWith(':')) {p1 = p1.slice(0, -1);} - if (p1 == name || (!p1 && p2 == name)) { - let nameFound = p1 || p2; - let pathFound = (p1) ? p2 : undefined; - console.log(nameFound+':'+pathFound); - self.partSetup = args; - if (pathFound) { - value = self.docElement('self.partSetup.'+pathFound); - } else { - value = args; - } - console.log('value:'+value); - delete self.partSetup; - } else { - value = match - } - if (typeof value !== 'string') value = self.stringify(value); - return value; - }); - if (self.isJsonString(paramsString)) {// (typeof params == 'object') - console.log('isJsonString'); - var paramsObj = self.parse(paramsString); - return paramsObj; - } else { - console.log('NOT isJsonString'); - console.log(paramsString); - // TO DO: log of wrong json string - return paramsString; - } - } else { - return params - } - } - */ - this.replaceUndefined = function (params) { - let value, defaultValue; - //if (params.path == 'badge') alert(); - if (typeof params.path !== undefined) { - if (params.path.indexOf('|') > 0) - [params.path, defaultValue] = params.path.split('|'); - value = self.element({ path: params.path, root: params.root }); - } - if (value == undefined || value == null) { // empty string is false - if (typeof defaultValue !== undefined) - value = defaultValue; - else { - if (params.removeUndefined) { //p1 == 'args' || p1 == 'selector') { - value = ''; // remove undefined values - } else { - value = params.match; - self.log(value + ' not found', 'yellow'); - } - } - } else { - //console.log('match:'+params.match); - //if (params.removeUndefined) value = ''; - } - return value; - }; - //value = self.replaceUndefined({match: '{'+match+'}', id:p1, removeUndefined: removeUndefined}); - this.replaceProperties = function (params, args, removeUndefined) { - // TO DO: remove fieldsObj. can't find replaceProperties with 3 args - // the third parameter can be removeUndefined - // test with a firebase app like elio - - var paramsString; - var paramOn, paramDo, paramSuccess, paramError, paramEvents, paramConfirm; - if (typeof params == 'string') { - paramsString = params; - } else { - //paramsString = JSON.stringify(params); - var paramsObj = self.cloneObject(params); - if (paramsObj) { - if (paramsObj.on) { paramOn = paramsObj.on; delete paramsObj.on; } - if (paramsObj.success) { paramSuccess = paramsObj.success; delete paramsObj.success; } - if (paramsObj.error) { paramError = paramsObj.error; delete paramsObj.error; } - if (paramsObj.events) { paramEvents = paramsObj.events; delete paramsObj.events; } // TO DO: remove - if (paramsObj.confirm) { paramConfirm = paramsObj.confirm; delete paramsObj.confirm; } // TO DO: check it - if (paramsObj.do) { paramDo = paramsObj.do; delete paramsObj.do; } - } - paramsString = JSON.stringify(paramsObj); - } - /* self.log("paramsString"); - self.log(paramsString); */ - if (paramsString && paramsString.indexOf('{') >= 0) { - - paramsString = paramsString.replace(/\"\{([\w\s\.]+)\}\"/g, function (match, p1, offset, string) { - var value; - if (p1) { - //self.log('p1:' + p1); - //value = self.element({path: p1}); // || match; - value = self.replaceUndefined({ match: '{' + match + '}', path: p1, removeUndefined: removeUndefined }); - if (value) { - if (value.isConnected) return self.elementToSelector(value); // DOM element to CSS selector - if (typeof value !== 'string') - return self.stringify(value); // object or array to string (TO DO: check numbers) - else { - //console.warn('we are here'); - return '"' + value + '"'; - } - } - else - return '""'; - } else { - return '""'; - } - }); - - paramsString = paramsString.replace(/\{(\w+\:)?([\w\s\->|\/=\.:#&;,\[\]\']+)\}/g, function (match, p1, p2, offset, string) { - /* - Firebase references may contain any unicode characters except: - . (period) - $ (dollar sign) - [ (left square bracket) - ] (right square bracket) - # (hash or pound sign) - / (forward slash) - */ - - /* self.log("paramstring"); - self.log(match, p1, p2); */ - // self.log(match, p1, p2); - var value; - if (p1) { - if (p1.endsWith(':')) { - p1 = p1.slice(0, -1); // remove the final ":" - - - // check if is a function name (in this.json.functions) - if (self.functions[p1]) { - //value = self.functions[p1](JSON.parse(p2)); - let funcArgs = p2.split('|'); - /* console.warn('p2'); - console.warn(p2); - console.warn('funcArgs'); - console.warn(funcArgs); */ - // if Number(funcArgs[i]) == funcArgs[i] -> funcArgs[i] = Number(funcArgs[i]); - value = self.function({ name: p1, arguments: [funcArgs] }); - } else { - switch (p1) { - - /* case 'hasClass': - var element = document.querySelector(p2); - if (p3) - value = self.hasClass(el,p3); - else - value = false; el:selector.class (esiste l'elemento selector.class o l'elemento selector ha la classe class) - break; */ - // 'isVisible', 'isHidden', 'isDisplay', 'inViewport', 'outViewport', 'notClass', 'hasClass' - // hasClass da aggiungere come funzione css - // html markups - // 'b:string' 'i:string' 'u:string' 'a:STRING|URL' - /* case 'i': case 'b': case 'u': case 'strong': case 'em': case 'mark': case 'del': case 'ins': case 'sub': case 'sup': - value = '<'+p1+'>'+p2+''; - break; - - case 'a': - // example: "{a:text|href:....|target:_blank}" - let props = p2.split('|'); // or indexOf(':') prima occorrenza - let string = props.shift(); - var propsString = ''; - for (var prop of props) { - //let propArr = prop.split(':'), propName = propArr[0], propValue = propArr[1]; - propsString += ' ' + prop; - } - if (propsString == '') propsString = ' href="'+string+'"'; - value = ''+string+''; - - // https://stackoverflow.com/questions/1547899/which-characters-make-a-url-invalid - // https://www.w3schools.com/tags/tag_a.asp - break; - */ - // DOM properties - case 'visible': - var element = document.querySelector(p2); // self.query(p2); - value = (element && self.isVisible(element)); - //value = ($(p2).is(':visible')); - break; - - case 'number': - value = Number(p2); - break; - - case 'string': - value = String(p2); - break; - - case 'js': // deprecated (too much special characters like {}) - try { - value = eval(p2); - } catch (error) { - value = ''; - self.log('javascript error on ' + p2); - self.log(error); - } - break; - - /* case 'item': - if (fieldsObj) { - //self.log('fieldsObj['+p2+']:'+fieldsObj[p2]); - value = fieldsObj[p2] || ''; //|| p2+'=NULL'; - } else { - //self.log('p2:'+p2); - //self.log('fieldsObj == undefined'); - value = '{'+p1+':'+p2+'}'; - } - break; */ - /* case 'item': - case 'items': - value = self.docElement('self.json.items.'+p2); - break; */ - /* case 'frame': - var element = self.query(p2); - element.contentWindow - break; */ - /* case 'field': - if (fieldsObj) { - //self.log('fieldsObj['+p2+']:'+fieldsObj[p2]); - value = fieldsObj[p2] || ''; // || p2+'=NULL'; - } else { - //self.log('p2:'+p2); - //self.log('fieldsObj == undefined'); - value = ''; - } - break; */ - /* case 'setup': - value = self.docElement('self.json.setup.'+p2) || match; - break; */ - /* - case 'setup': - if (args) { - self.partSetup = args; - value = self.docElement('self.partSetup.'+p2); - delete self)Setup; - } else { - value = ''; - } - break; */ - case 'wp': - case 'wordpress': - // TO DO: should get/set data with jsonic.get/setWordpressData - // setWordpressData can be done automatically in the init - value = self.docElement('self.json.setup.wordpress.' + p2) ?? match; - //alert(value); - //if (value.indexOf('"') >= 0) - // value = self.replaceAll(value, '"', '\\"'); - // the first should replace only " and not \" but it doesn't works - //value = value.replaceAll(/([^\\\"])\"/g, '$1\\"'); - break; - - case 'plugins': - value = self.json.resources.pluginsFunctions[p2]; - if (value && !Array.isArray(value)) value = [value]; - else value = []; - /* self.log('plugins'); - self.log('value'); - self.log(value); */ - /* value = plugins; - for (plugin of plugins) { - value = self.json.resources.pluginsFunctions[p2].name || 'unknown plugin required'; - } */ - break; - - case 'database': - case 'db': - value = self.docElement('self.json.var.db.' + self.replaceProperties(p2, args)); - break; - - // shorteners (useful?) - case 'media': // or m or src - if (self.json.setup && self.json.data.media) - value = self.docElement('self.json.data.media.' + p2) || match; - - else - value = match; - break; - - case 'color': // or col - if (self.json.data && self.json.data.colors) - value = self.docElement('self.json.data.colors.' + p2) || match; - - else - value = match; - break; - - case 'class': // or cla - if (self.json.data && self.json.data.class) - value = self.docElement('self.json.data.class.' + p2) || match; - - else - value = match; - break; - - case 'text': - value = self.langText(p2); - break; - - case 'param': - value = self.params[p2] || ''; // || p2+'=NULL'; - break; - - case 'height': - /* self.log('{height:p2}'); - self.log('p2'); - self.log(p2); */ - var element = document.querySelector(p2); // self.query(p2); - if (element) // && self.isVisible(element) - //value = getComputedStyle(element, null).height; - value = element.offsetHeight + 'px'; - - - - //if ($(p2).is(':visible')) - //value = $(p2).height() + 'px' - else - value = '0px'; - break; - - case 'offsetWidth': - var element = document.querySelector(p2); // self.query(p2); - if (element) // && self.isVisible(element) - //value = getComputedStyle(element, null).height; - value = element.offsetWidth; - - - - //if ($(p2).is(':visible')) - //value = $(p2).height() + 'px' - else - value = '0'; - break; - - case 'width': - var element = document.querySelector(p2); // self.query(p2); - if (element) // && self.isVisible(element) - //value = getComputedStyle(element, null).height; - value = element.offsetWidth + 'px'; - - - - //if ($(p2).is(':visible')) - //value = $(p2).height() + 'px' - else - value = '0px'; - break; - - case 'local': - value = self.methods.local.get(p2); - //self.log('{localStorage:cart}'); - //self.log(value); - break; - - case 'ace': - var element = document.querySelector(p2); - if (element) { - var editor = ace.edit(element); - value = JSON.parse(editor.getValue()); - } - //self.log('{localStorage:cart}'); - //self.log(value); - break; - - /* case 'innerText': - var element = document.querySelector(p2); - value = (element) ? element.innerText : undefined; - self.log('p1:'+p1); - self.log('p2:'+p2); - self.log('value:'+value); - //.trisBox[data-value="0"] - break; - - case 'innerHtml': - var element = document.querySelector(p2); - value = (element) ? element.innerHTML : undefined; - break; */ - case 'shuffle': - value = self.element({ path: p2 }); - value = self.methods.shuffle(value); - break; - - case 'select': - case 'input': - case 'value': // deprecated - - var element = document.querySelector(p2); // self.query(p2); - value = (element) ? String(element.value || '') : ''; - - //value = $('#'+p2).val() || ''; //|| p2+'=NULL'; - // input field value - // https://www.geeksforgeeks.org/html-value-attribute/ - break; - - case 'user': - if (p2 == 'in') { - value = self.userIn(); - } else if (p2 == 'out') - value = self.userOut(); - - else - value = self.user(p2) || match; //|| p2+'=NULL'; - break; - - // can go in objects - case 'length': - var varObj = self.element({ path: p2 }); // to get also js objects length - - //var varObj = self.docElement('self.json.'+p2); - if (varObj) - if (typeof varObj == 'object') - value = Object.keys(varObj).length; - - else - value = varObj.length; - - else - self.log('' + p2 + ' is undefined'); - break; - - case 'Date': - case 'time': - if (p2 == 'timeZone') value = new Intl.DateTimeFormat().resolvedOptions().timeZone; - else if (p2 == 'weekday') value = self.weekday(); - else if (p2 == 'stamp') value = self.getTimestamp(); - else if (p2 == 'timestamp') value = self.getTimestamp(); - else if (p2 == 'getTimestamp') value = self.getTimestamp(); - else if (p2 == 'getDay') value = new Date().getDay(); - else if (p2 == 'getDate') value = new Date().getDate(); - else if (p2 == 'getMonth') value = new Date().getMonth(); - else if (p2 == 'getFullYear') value = new Date().getFullYear(); - else if (p2 == 'getTime') value = new Date().getTime(); // timestamp - else if (p2 == 'getSeconds') value = new Date().getSeconds(); - else if (p2 == 'getMinutes') value = new Date().getMinutes(); - else if (p2 == 'getHours') value = new Date().getHours(); - - // second, minute, hour, weekday, day, month, year - else value = p2 + '=NULL'; - break; - - case 'now': - // ... - break; - - case 'month': - var month = (p2 == 'today' || p2 == undefined) ? new Date().getMonth() : Number(p2); - value = self.month(month); - break; - - case 'weekday': // format: long, short, narrow - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'long' }); - break; - - case 'weekdayNarrow': // format: long, short, narrow - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'narrow' }); - break; - - case 'weekdayShort': // format: long, short, narrow - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'short' }); - break; - - case 'moment': - var timeFormat = (p2) ? p2 : ''; - value = moment().format(timeFormat); - break; - - case 'dayjs': // TO DO: check - var timeFormat = (p2) ? p2 : ''; - value = dayjs().format(timeFormat); - break; - - case 'Math': - value = self.Math(p2); - break; - - - case 'action': - case 'do': - self.log('do'); - self.log('p2'); - self.log(p2); - //value = self.do(p2); // || match; // TO DO: log error - value = self.do(p2); // || match; // TO DO: log error - - - - - //var functionName = self.docElement(p2); - //value = (functionName) ? functionName(functionName) : p2+'=NULL' - break; - - /* WITH ARGS */ - case 'method': - var method = self.element({ path: p2, root: self.methods }); - if (method) { - value = method(args); // how to pass args? needs p3 - } else { - value = match; - } - break; - - case 'function': // TO DO: remove - var func = self.element({ path: p2, root: self.functions }); - if (func) { - value = func(args); // how to pass args? needs p3 - } else { - value = match; - } - break; - - case 'on': - /* self.log('args'); - self.log(args); */ - if (args) { - self.onResult = args; - value = self.docElement('self.onResult.' + p2); - //alert(JSON.stringify(value)); - delete self.onResult; - } else { - //alert(JSON.stringify(value)); - value = match; - } - //value = ($(p2).is(':visible')); - break; - - case 'ajax': - if (args) { - self.ajaxResult = args; // -> self.json.var.ajaxData[self.json.var.ajaxId] = args.response - - //alert(JSON.stringify(args)); - value = self.docElement('self.ajaxResult.' + p2); - - delete self.ajaxResult; - } else { - //alert(JSON.stringify(value)); - value = match; - } - //value = ($(p2).is(':visible')); - break; - - /* case 'function': // TO DO: remove - //self.log('function'); - //self.log('p2'); - //self.log(p2); // app.mac - value = self.function(p2) || match; // TO DO: log error - - //var functionName = self.docElement(p2); - //value = (functionName) ? functionName(functionName) : p2+'=NULL' - - break; */ - case 'if': // TO DO: remove (can't manage spacial characters !<>'' etc) - p2 = self.replaceProperties(p2); - var ifArr = p2.split('|'); - if (self.js(ifArr[0])) value = true; - if (ifArr.length > 1 && value) value = ifArr[1]; - if (ifArr.length > 2 && !value) value = ifArr[2]; - break; - case 'random': - /* var random = p2.replace(/([^\-]+)\-([^\}]+)/g, function(match, n1, n2, offset, string) { - return Number(n1)+Math.round((n2-n1)*Math.random()); - }); */ - value = String(Math.floor(Number(p2) * Math.random())); - //self.log('random value: '+value); - //value = random; //p2+' format is wrong' - // CHANGE TO {math.random:max} - break; - - case 'getKey': - case 'firebaseKey': - value = self.firebaseKey(p2); - // https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot - // CHANGE TO {data.exists:path/to/record} - //"alert.close" functions(alert, do:close) - break; - - case 'window': - /* try { - value = eval('window.'.p2); - } catch (error) { - self.log('javascript error on '+ p2); - value = match; - } */ - //value = self.js('window.'.p2) || match; - value = self.docElement(p2) || match; - break; - - - /* case 'args': - // often replaceProperties is called without args - value = match; - break; */ - default: - // ci finiamo dentro con {setup:value} - /* var element = document.querySelector(p2); - value = (element) ? element[p1] : ''; - self.log('p1 ' + p1); - self.log('p2 ' + p2); - self.log('value ' + value); - if (!element) - self.log('can\'t match ' + match, 'color:red'); */ - break; - - - /* default: - - var node = self.docElement('self.json.'+p1); - self.log('node'); - self.log(node); - if (node) value = node[p2] // example: p1 = styles.colors p2 = colorName - else value = '<{'+p1+':'+p2+'}>'; - break; - */ - } - } // not self.functions[p1] - } - } else if (p2) { - - // can be a FUNCTION: from modules - let keyPrefix = p2.split(' ')[0]; // /\s\./ - if (self.functions[keyPrefix]) { - value = self.function({ name: keyPrefix }); - value = self.element({ path: p2, root: value }); // example: {pathFromHash 0} - console.log(keyPrefix); - console.log(value); - } - else - value = self.replaceUndefined({ match: match, path: p2, removeUndefined: removeUndefined }); - //value = self.element({path: p2}); - } - - // value is a DOM element - if (value && value.isConnected) value = self.elementToSelector(value); // DOM element to CSS selector - - if (!value) { - // TO DO: should be (typeof value == undefined) - // t's a critical change. It changes the result of "is": "'{data id}' !== ''" - if (removeUndefined) - value = ''; - else { - if (typeof value == undefined) - self.log(match + ' is undefined', 'yellow'); - } - } - if (typeof value !== 'string') value = self.stringify(value); // object or array to string (TO DO: check numbers) - - return value; - }); - - - // js property TO DO: check it - if (paramsString.startsWith('{js:') && paramsString.endsWith('}')) - paramsString = self.js(paramsString.substr(4, paramsString.length - 1 - 4)); - - //if (self.isJson(paramsString)) {// (typeof params == 'object') - if (self.isJsonString(paramsString)) { // (typeof params == 'object') - var paramsObj = self.parse(paramsString); - - // restore event nodes - if (paramOn) paramsObj.on = paramOn; - if (paramDo) paramsObj.do = paramDo; - if (paramConfirm) paramsObj.confirm = paramConfirm; - if (paramSuccess) paramsObj.success = paramSuccess; - if (paramError) paramsObj.success = paramError; - if (paramEvents) paramsObj.events = paramEvents; // obsolete - return paramsObj; - } else { - // TO DO: log of wrong json string - //alert(paramsString); - /* if (Array.isArray(self.parse(paramsString))) - return self.parse(paramsString) - else */ - return paramsString; - } - } else { - // restore event nodes - if (paramOn) params.on = paramOn; - if (paramDo) params.do = paramDo; - if (paramConfirm) params.confirm = paramConfirm; - if (paramSuccess) params.success = paramSuccess; - if (paramError) params.error = paramError; - if (paramEvents) params.events = paramEvents; // obsolete - return params; - } - - }; - - /* if (!value) undef = true; - if (undef) return undefined - else return params; - */ - this.isJsonString = function (str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; - }; - - this.isJson = function (item) { - item = typeof item !== "string" ? JSON.stringify(item) : item; - try { - item = JSON.parse(item); - } catch (e) { - return false; - } - - if (typeof item === "object" && item !== null) { - return true; - } - - return false; - }; - - this.replaceStringInObject = function (obj, stringToReplace, value) { - var paramsString, valueString; - if (typeof obj == 'string') paramsString = obj; else paramsString = JSON.stringify(obj); - if (typeof value == 'string') valueString = value; else valueString = JSON.stringify(value); - paramsString = self.replaceAll(paramsString, stringToReplace, valueString); - if (self.isJson(paramsString)) - return self.parse(paramsString); - - else - return paramsString; - }; - - /* this.replaceResult = function (params, args) { - - paramsString = paramsString.replace(/(\"\s*)\{[result]\:(\w+)\}(\s*\")/g, function(match, p1, p2, p3, offset, string) { - }); - } - */ - this.replaceItems = function (params, item, name) { - // check this: http://mir.aculo.us/2011/03/09/little-helpers-a-tweet-sized-javascript-templating-engine/ - // params:
  • <{item:name}>
  • , item: Vito or item: {name: Vito} - //var paramString = self.replaceProperties(params, undefined, item); - var paramsString; - var specialPattern; - var itemName = name || 'item'; - /* if (name) { - self.log('replaceItems'); - self.log('params'); - self.log(params); - self.log('item'); - self.log(item); - self.log('name'); - self.log(name); - } */ - if (typeof params == 'string') paramsString = params; else paramsString = JSON.stringify(params); - - /* paramsString = paramsString.replace(/\{item\}/g, function(match, p1, offset, string) { - - var value; - - if (item) { - value = item; - } else { - value = ''; - } - - if (typeof value == 'object') value = self.stringify(value); - return value; - }); */ - if (typeof item == 'object' || Array.isArray(item)) { // || Array.isArray(item) not needed - paramsString = self.replaceAll(paramsString, '"{' + itemName + '}"', JSON.stringify(item)); - for (let key in item) { - if (typeof item[key] == 'object') - paramsString = self.replaceAll(paramsString, '"{' + itemName + ':' + key + '}"', JSON.stringify(item[key])); - - else - paramsString = self.replaceAll(paramsString, '{' + itemName + ':' + key + '}', item[key]); - } - } else { - paramsString = self.replaceAll(paramsString, '{' + itemName + '}', String(item)); - } - //if (itemName == 'hour') alert(paramsString); - /* if (itemName !== 'item') { // TO DO: remove - var propertyPattern = new RegExp('\{'+itemName+'\:([^\}]+)\}', 'g'); - paramsString = paramsString.replace(propertyPattern, function(match, p1, p2, p3, offset, string) { - - - var value = self.docElement(p1, undefined, item); - if (value) - return value - else - return match; - - }); - } */ - //specialPattern = new RegExp(/\"\{(\w+)\}\"/, "g"); - // item: inside double quotes (to manage objects inside double string) - //specialPattern = new RegExp(`(\")\{${itemName}\:(\w+)\}(\")`, 'g'); - //paramsString = paramsString.replace(specialPattern, function(match, p1, p2, p3, offset, string) { - //specialPattern = new RegExp('(\"\s*)\{'+itemName+'\:(\w+)\}(\s*\")', 'g'); - paramsString = paramsString.replace(/(\"\s*)\{item\:(\w+)\}(\s*\")/g, function (match, p1, p2, p3, offset, string) { - - var value; - - if (item) - value = item[p2] || ''; - - else - value = ''; - - if (typeof value == 'object') - value = self.stringify(value); - else if (Array.isArray(value)) - value = value; - - else - value = p1 + value + p3; // p1 and p3 are the " matched by (\"\s*) and (\s*\") - - return value; - }); - - /* - specialPattern = new RegExp('\{'+itemName+'\:([^\}]*)\}', 'g'); - paramsString = paramsString.replace(specialPattern, function(match, p2, offset, string) { - //paramsString = paramsString.replace(/\{item\:([^\}]*)\}/g, function(match, p2, offset, string) { - - var value; - - if (item) - value = item[p2] || ''; - else - value = ''; - - if (typeof value == 'object') - value = self.stringify(value); - - return value; - }); */ - if (self.isJson(paramsString)) - return self.parse(paramsString); - - else - return paramsString; - //if (typeof params == 'object') return self.parse(paramsString); else return paramsString; - }; - - /* this.replaceItems = function (objWithNames, name) { - //self.log('replaceItems'); - var paramString = self.stringify(objWithNames); - //self.log(paramString); - if (!name) name = ''; - paramString = self.replaceAll(paramString, '{item}', name); - //self.log(paramString); - //paramString = self.replaceTags({text:paramString}); - //self.log(paramString); - //paramString = self.replaceProperties(paramString); - //self.log(paramString); - if (typeof objWithNames == 'object') return self.parse(paramString); else return paramString; - } */ - this.color = function (params, args) { - var paramsReplaced = self.replaceProperties(params, args); - //if (self.json.styles.colors) - // return self.json.styles.colors[paramsReplaced]; - if (self.json.data && self.json.data.colors) - return self.json.data.colors[paramsReplaced]; - }; - - // ---------------------------- - // ELEMENT METHODS - // ---------------------------- - this.empty = function (params) { - /* self.log('empty'); - self.log(params); */ - var el = self.query(params); - if (el) { - while (el.firstChild) - el.removeChild(el.firstChild); - } else { - self.log('"empty" is unable to select element'); - self.log(params); - } - }; - - this.isArray = function (value) { - return Array.isArray(self.js(value)); - }; - - this.isVisible = function (el) { - return (el.style.display !== 'none' && !self.hasClass(el, 'd-none')); - }; - - this.isHidden = function (el) { - return (el.offsetParent === null); - }; - - this.isDisplay = function (el, displayValue) { - //var style = window.getComputedStyle(el); - /* self.log('isDisplay'); - self.log('el.style'); - self.log(el.style); - self.log('displayValue'); - self.log(displayValue); */ - return (el.style.display === displayValue); - }; - - this.inViewport = function (el) { - const rect = el.getBoundingClientRect(); - return ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - rect.right <= (window.innerWidth || document.documentElement.clientWidth) - - ); - }; - - this.outViewport = function (el) { - return !self.outViewport(el); - }; - - this.notClass = function (el, className) { - return !self.hasClass(el, className); - }; - - this.hasClass = function (el, className) { - if (el.classList) - return el.classList.contains(className); - - else - return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')); - }; - - this.addClass = function (el, className) { - if (el.classList) - el.classList.add(className); - else if (!self.hasClass(el, className)) el.className += " " + className; - }; - - this.removeClass = function (el, className) { - if (el.classList) - el.classList.remove(className); - else if (self.hasClass(el, className)) { - var reg = new RegExp('(\\s|^)' + className + '(\\s|$)'); - el.className = el.className.replace(reg, ' '); - } - }; - - this.toggleClass = function (el, className) { - if (self.hasClass(el, className)) - self.removeClass(el, className); - - else - self.addClass(el, className); - }; - - this.choose = this.select = function (params, selectorParams, args) { - // "choose OR options / "select" is deprecated because select is an html tag - // {selection: selection class, id: selected id} - // or: choosed, choosable, selection - // or: selector, selectable, selection - // or: opted, options, selection - /* self.log('select'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - if (Array.isArray(params)) { - for (var obj of params) - self.choose(obj, args); - } else { - - //if (selectorParams) params = self.extend({}, selectorParams, params); - var selId, selClass, selValue; - - selValue = params['data-value']; // || params.value - if (params.id) selId = self.replaceProperties(params.id, args); - if (params.class) selClass = self.replaceProperties(params.class, args); - if (selValue) selValue = self.replaceProperties(selValue, args); - - //var selector = self.selector(params.selector, undefined, true) || self.selector(selectorParams, undefined, true); - if (params.selection) { - - var selectionClass = params.selection; - /* self.log('selClass'); - self.log(selClass); - self.log('selValue'); - self.log(selValue); - self.log('selectionClass'); - self.log(selectionClass); */ - var selector = self.selector({ class: selClass }); - var elements = document.querySelectorAll('.' + selClass); // convert to any string selector (move the point to the code) - elements.forEach(function (element, index) { - self.removeClass(element, selectionClass); - }); - - //$(selector).removeClass(selectionClass); - if (selId || selValue) { - var selector = self.selector({ id: selId, class: selClass, 'data-value': selValue }); - - //self.log('selector'); - //self.log(selector); - //var elements = self.query(selector); - //self.log('elements'); - //self.log(elements); - //if (elements) - //self.addClass(elements, selectedIconClass); - var elements = document.querySelectorAll(selector); - elements.forEach(function (element, index) { - self.addClass(element, selectionClass); - }); - } - } else { - /* self.log('select'); - self.log('selClass'); - self.log(selClass); - self.log('selValue'); - self.log(selValue); - self.log('selectionClass'); - self.log(selectionClass); */ - self.hide({ - "selector": { - "class": selClass - } - }); - self.show({ - "selector": { - "id": selId, - "class": selClass, - "data-value": selValue - } - }); - - //self.log('selectselection" class parameter is required in "select" object'); - } - - //self.updateCodeEditors(); // workaround known ACE bug - self.uiUpdate(); // resize event trigger - - } - - }; - - /* this.select = function (params, selectorParams) { - // { [container, class, value, id] - self.log('self.select'); - if (Array.isArray(params)) { - for (var index in params) - self.choose(params[index], selectorParams); - } else { - - if (selectorParams) params = self.extend({}, selectorParams, params); - - params = self.replaceProperties(params); - //params = self.replaceTags({text:params}); - - self.selectItem(params); - } - } -*/ - this.toggle = function (params, selectorParams, args) { - self.log('toggle'); - self.log(params); - if (Array.isArray(params)) { - for (var index in params) - self.toggle(params[index], selectorParams, args); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var element = self.query(selector); - /* self.log('selector'); - self.log(selector); - self.log('element'); - self.log(element); - self.log('self.isVisible(element)'); - self.log(self.isVisible(element)); */ - //if ($(selector).is(":visible")) - if (self.isVisible(element)) - //self.fadeOut(params, selectorParams); - self.out(params, selectorParams, args); - - else - //self.fadeIn(params, selectorParams); - self.in(params, selectorParams, args); - //$(selector).toggle(500); // jquery bugs // , self.resizeEvent - } - }; - - this.in = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.in(params[index], selectorParams, args); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - - var transition = params.transition || 'fadeIn'; - var duration = params.duration || '500ms'; - - //self.log('selector'); - //self.log(selector); - var start = [{ - "show": { - "selector": selector, - } - }]; - var end = [ - { - "do": self.resizeEvent - } - ]; - if (params.on && params.on.start) - start.push(params.on.start); - if (params.on && params.on.end) - end.push(params.on.end); - - var animation = { - "animate": { - "selector": selector, - "transition": transition, - "duration": duration, - "on": { - "start": start, - "end": end - } - } - }; - //self.do(animation, args); - self.do(animation, undefined, args); - //self.resizeEvent(); - } - - }; - - this.out = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.out(params[index], selectorParams); - } else { - - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - - var transition = params.transition || 'fadeOut'; - var duration = params.duration || '500ms'; - - var start = []; - var end = [ - { - "hide": { - "selector": selector, - } - }, - { - "do": self.resizeEvent - } - ]; - if (params.on && params.on.start) - start.push(params.on.start); - if (params.on && params.on.end) - end.push(params.on.end); - - var animation = { - "animate": { - "selector": selector, - "transition": transition, - "duration": duration, - "on": { - "start": start, - "end": end - } - } - }; - //self.do(animation, args); - self.do(animation, undefined, args); - } - }; - - this.show = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.show(params[index], selectorParams); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - elements.forEach(function (element, index) { - self.removeClass(element, 'hidden'); - self.removeClass(element, 'opacity-0'); - self.removeClass(element, 'invisible'); - self.removeClass(element, 'd-none'); // bootstrap - - //element.style.display = 'block'; - element.style.visibility = 'visible'; - /* - container = element.getAttribute('data-selector'); - //container = self.dataStorage.get(element, 'selector'); - var action = [ - { - "if": { - "container": container, - "hasClass": "opacity-0", - "then": { - "attr": { - "container": container, - "removeClass": "opacity-0" - } - } - } - }, - { - "if": { - "container": container, - "hasClass": "invisible", - "then": { - "attr": { - "container": container, - "removeClass": "invisible" // bootstrap & tailwind - } - } - } - }, - { - "if": { - "container": container, - "hasClass": "d-none", - "then": { - "attr": { - "container": container, - "removeClass": "d-none" // bootstrap - } - } - } - }, - { - "if": { - "container": container, - "hasClass": "hidden", - "then": { - "attr": { - "container": container, - "removeClass": "hidden" // taliwind - } - } - } - }, - { - "if": { // should be if style.display == none - "container": container, - "isDisplay": "none", - "then": { - "attr": { - "container": container, - "style": { - "display": "" - } - } - } - } - } - ]; - //element.style.display = ' '; - //alert(JSON.stringify(element.style)); - if (element.style.visibility && element.style.visibility !== 'visible') - element.style.visibility = 'visible'; - //self.do(action, args); - //self.do(action, undefined, args); - self.do(action, undefined, args); */ - }); - } - }; - - this.hide = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.hide(params[index], selectorParams); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - elements.forEach(function (element, index) { - self.addClass(element, 'hidden'); - - /* container = element.getAttribute('data-selector'); - var action = [ - { - "attr": { - "container": container, - "addClass": "d-none" // bootstrap (to be removed) - } - }, - { - "attr": { - "container": container, - "addClass": "hidden" // tailwind - } - } - ]; - //self.do(action, args); - self.do(action, undefined, args); */ - }); - } - }; - - - /* this.fadeIn = function (params, selectorParams, args) { - //self.log('fadeIn'); - //self.log(params); - if (Array.isArray(params)) { - for (var index in params) - self.fadeIn(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - var duration = params.duration || 500; - var done = (params.done) ? function () { - self.resizeEvent(); - self.do(params.done); - } : null; - $(selector).stop().fadeIn(duration, done); - } - } - - this.fadeOut = function (params, selectorParams, args) { - //self.log('fadeOut'); - //self.log(params); - // add onComplete and duration - if (Array.isArray(params)) { - for (var index in params) - self.fadeOut(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - var duration = params.duration || 500; - var done = (params.done) ? function () { - self.do(params.done); - } : null; - $(selector).stop().fadeOut({ - duration: duration, - done: function () { - self.resizeEvent(); - self.do(params.done); - } - }); - } - } */ - /* this.show = function (params, selectorParams, args) { - //self.log('show'); - //self.log(JSON.stringify(params)); - if (Array.isArray(params)) { - for (var index in params) - self.show(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - //self.log('selector'); - //self.log(selector); - $(selector).show(); - self.resizeEvent(); - } - } - - this.hide = function (params, selectorParams, args) { - //self.log('hide'); - //self.log(JSON.stringify(params)); - if (Array.isArray(params)) { - for (var index in params) - self.hide(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - //self.log('selector'); - //self.log(selector); - $(selector).hide(); - self.resizeEvent(); - } - } */ - this.matchMedia = function (mediaAction, mediaEvent) { - const mediaQuery = window.matchMedia(mediaEvent); - mediaQuery.addListener(function (e) { - /* self.log('matchMedia'); - self.log('e'); - self.log(e); */ - if (e.matches) { - self.do(mediaAction); - //self.do(mediaAction); - } - }); - //self.do(mediaAction); - }; - - - /* this.firebaseEventAction = function (newObj) { - - var path = newObj.path; - delete newObj.path; - - document.querySelectorAll('[data-firebase="'+path+'"]').forEach(function (element, index) { - - var pathString = 'self.json.var.db.' + self.replaceAll(element.getAttribute('data-firebase'), '/', '.'); // data('firebase') - var dbObj = self.docElement(pathString); - - var firebaseValue = newObj[element.getAttribute('data-value')]; // TODO: not works for nested nodes - var container = element.getAttribute('data-selector'); - //var template = element.getAttribute('data-template'); - var template = self.dataStorage.get(element, 'data-template'); - - if (element.tagName == 'UL') { // se $(this) è un ul - - var liTemplate = template.li; - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - //if (dbPath == 'lessons') - //prompt(JSON.stringify(liTemplate)); - var dbParams = self.replaceItems(liTemplate, item, 'item') || ''; - // var dbParams = self.replaceProperties(liTemplate, undefined, item) || ''; - self.li(dbParams, {container: container}); - } - - //} else if ( $(element).is('span') || $(element).is('p')) { - } else if (element.tagName == 'SPAN' || element.tagName == 'P') { - - //$(element).text(firebaseValue); - element.textContent = firebaseValue; - - } else { // se $(this) non è un ul - - if (template.blocks || template.html) { - var blocksTemplate = template.html || template.blocks; - - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - self.log('newObj'); - self.log(newObj); - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - var dbParams = self.replaceProperties(blocksTemplate, undefined, item) || ''; - - self.html(dbParams, {container: container}); - } - } - - if (template.init) self.do(template.init); - - } - - - }); - }; */ - /* self.jsonic = function () { - } */ - this.addFirebaseTag = function (params) { - // self.log('addFirebaseTag'); - var dataObj = params.database; - - if (dataObj) { - - dataObj = self.replaceProperties(dataObj); - /* self.log('dataObj'); - self.log(dataObj); */ - //var path = self.replaceTags({text:params.firebase}); - var path, success; - if (typeof dataObj == 'string') { - path = dataObj; - } else { - path = dataObj.path; - success = dataObj.success; - } - - if (path) { - var selector = self.selector(params, undefined, false); - //var element = self.query(selector); - var elements = self.queryAll(selector); - //var elements = document.querySelectorAll(selector); - if (elements) - elements.forEach(function (element, index) { - - var listenerObj = { - path: path - //success: dataObj.success - }; - - var elementsDataPath = document.querySelectorAll('[data-firebase="' + path + '"]'); - - //if ($('[data-firebase="'+path+'"]').length == 0) { - if (elementsDataPath.length == 0) { - listenerObj.action = [ - /* { - "firebaseEvent.action": {} // should use self.get function to parse "self" - // todo: remove "jsonic". The function firebaseEventAction can be stored in self.do (or?) - } */ - ]; - - if (dataObj.success) - listenerObj.action.push(dataObj.success); - - } - - //$(selector).attr('data-firebase', path); - //$(selector).data('data-template', params); - if (element) { - element.setAttribute('data-firebase', path); - self.dataStorage.set(element, 'data-template', params); - } else { - self.log('!element selector:' + selector + ' / firebase path:' + path); - self.log('params'); - self.log(params); - } - - //if (params.on && params.on.data) $(selector).data('ondata', params.on.data); // maestry - if (dataObj.orderByChild !== undefined) listenerObj.orderByChild = dataObj.orderByChild; - if (dataObj.equalTo !== undefined) listenerObj.equalTo = dataObj.equalTo; - - self.firebaseAddListener(listenerObj); - }); - - } else { - self.log('data object requires path parameter'); - self.log(params); - } - } - }; - - this.dbObject = function (path) { - var pathString = 'self.json.var.db.' + self.replaceAll(path, '/', '.'); - return self.docElement(pathString); - }; - - this.only = function (permissions, user) { - // "visitor" or "only" - if (user) { - return (user == self.user('uid')); - } else { - var permission = (permissions) ? String(permissions).split(',') : false; - return (!permission || (permissions.indexOf(self.userRole()) >= 0)); - } - }; - - this.extendJsonFromElement = function (p) { - /* self.log('extendJsonFromElement'); - self.log(p); */ - - var params = self.cloneObject(p); - - // properties - if (params.resources) self.extendJson(self.json, { "resources": params.resources }); - if (params.plugins) self.extendJson(self.json, { "plugins": params.plugins }); - if (params.parts) self.extendJson(self.json, { "parts": params.parts }); - if (params.blocks) self.extendJson(self.json, { "blocks": params.parts }); // obsolete - if (params.shortcuts) self.extendJson(self.json, { "shortcuts": params.shortcuts }); - if (params.css) self.extendJson(self.json, { "css": params.css }); - if (params.setup) self.extendJson(self.json, { "setup": params.setup }); - if (params.data) self.extendJson(self.json, { "data": params.data }); - if (params.var) self.extendJson(self.json, { "var": params.var }); - if (params.texts) self.extendJson(self.json, { "texts": params.texts }); // maybe used in self.text - - - // can't be extended "setup" (is relative to the full app) and "on" (is relative to the element) - }; - - - this.query = function (selector, element) { - //self.log('query: '+selector); - if (selector) { - if (typeof selector == 'object') - selector = self.selector(selector, undefined, true); - - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - - if (element && element[0]) element = element[0]; - - if (element && element.isConnected) { - - var route = routes[index]; - - - - /* route.replace(/([^\s])\[/g, function(match, p1) { // -> .class [data-value=...] - return p1 + ' [' - }); */ - //self.log('route'); - //self.log(route); - var routeParts = route.match(/(.*):eq\((\d*)\)/); - - //self.log('routeParts'); - //self.log(routeParts); - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - - if (routeElement.startsWith('.')) - routeElement = '.' + self.classSelector(routeElement); - - //if (self.exist(routeElement)) - element = element.querySelectorAll(routeElement)[routeIndex]; - - /* self.log('routeElement'); - self.log(routeElement); - self.log('routeIndex'); - self.log(routeIndex); */ - } else { - //if (self.exist(route)) - if (route.startsWith('.')) - route = '.' + self.classSelector(route); - element = element.querySelectorAll(route)[0]; - } - } else { - element = undefined; - } - } - //element.innerHTML = 'test'; - //element.style.display = 'none'; - //self.log(element); - //if (element && !Array.isArray(element)) element = [element]; - if (!element) - self.log('can\'t find the element "' + selector + '" ("query" function)'); - - return element; - } else { - //self.log('function "query" without selector parameters'); - // BUG: many calls from addtag - } - }; - - /* this.queryAllTest = function (selector, element) { - //self.log('query: '+selector); - if (selector) { - - //route = self.replaceAll(route, '[', ' ['); - selector.replace(/([^\s])\[/g, function(match, p1) { // -> .class [data-value=...] - return p1 + '[' - }); - - - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - self.log('routes'); - self.log(routes); - - for (var index in routes) { - self.log('index'); - self.log(index); - - if (element.isConnected) { - - var route = routes[index]; - - var routeParts = route.match(/([^:]*):eq\((\d*)\)/); - - self.log('routeParts'); - self.log(routeParts); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - //if (self.exist(routeElement)) - element = element.querySelectorAll(routeElement)[routeIndex]; - - self.log('routeElement'); - self.log(routeElement); - self.log('routeIndex'); - self.log(routeIndex); - - } else { - //if (self.exist(route)) - self.log('route'); - self.log(route); - element = element.querySelectorAll(route); - } - } else { - self.log('Not in the DOM '+ selector); - self.log('route'); - self.log(route); - element = []; - } - } - //element.innerHTML = 'test'; - //element.style.display = 'none'; - //if (element && !Array.isArray(element)) element = [element]; - //self.log(element); - - return element; - } else { - self.log('DOM "query" without selector parameters'); - } - } */ - /* this.convertRoute = function (route) { - var routeElement, routeValue; - - route = route.replace(/([^\s])\[/g, function(match, p1) { // -> .class [data-value=...] - return p1 + ' [' - }); - - if (route.indexOf(' ')) { - var parts = route.split(' '); - routeElement = parts[0]; - routeValue = parts[1]; - } else { - routeElement = route - } - self.log(routeElement); - self.log(routeValue); - - if (routeElement.startsWith('.')) - routeQuery = '[class='+routeElement+']'; - else if (routeElement.startsWith('#')) - routeQuery = '[id='+routeElement+']'; - else - routeQuery = routeElement + routeValue; - - if (routeValue) - routeQuery += ' ' + routeValue; - - return routeQuery; - } */ - /* - // https://www.examplefiles.net/cs/1222124 - var querySelectorAllWithEq = function(selector, document) { - var remainingSelector = selector; - var baseElement = document; - var firstEqIndex = remainingSelector.indexOf(':eq('); - - while (firstEqIndex !== -1) { - var leftSelector = remainingSelector.substring(0, firstEqIndex); - var rightBracketIndex = remainingSelector.indexOf(')', firstEqIndex); - var eqNum = remainingSelector.substring(firstEqIndex + 4, rightBracketIndex); - eqNum = parseInt(eqNum, 10); - - var selectedElements = baseElement.querySelectorAll(leftSelector); - if (eqNum >= selectedElements.length) { - return []; - } - baseElement = selectedElements[eqNum]; - - remainingSelector = remainingSelector.substring(rightBracketIndex + 1).trim(); - // Note - for now we just ignore direct descendants: - // 'a:eq(0) > i' gets transformed into 'a:eq(0) i'; we could maybe use :scope - // to fix this later but support is iffy - if (remainingSelector.charAt(0) === '>') { - remainingSelector = remainingSelector.substring(1).trim(); - } - - firstEqIndex = remainingSelector.indexOf(':eq('); - } - - if (remainingSelector !== '') { - return Array.from(baseElement.querySelectorAll(remainingSelector)); - } - - return [baseElement]; - }; */ - this.queryAll = function (selector, element) { - //self.log('queryAll: '+selector); - if (selector) { - - if (Array.isArray(selector)) { - let elements = self.queryAll(selector[0]); - selector.shift(); - for (let str of selector) { - elements = Array.prototype.slice.call(elements).concat(Array.prototype.slice.call(self.queryAll(str))); - - //elements = elements.concat(self.queryAll(str)); - } - /* console.log('queryAll'); - console.log(elements); */ - return elements; - - } else { - - /* - if (selector.indexOf(',')>= 0) { - return element.querySelectorAll(selector) - } - // TO DO: check why all the rest - */ - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - /* self.log('routes'); - self.log(routes); */ - /* self.log('element[0]'); - self.log(element[0]); */ - for (var index in routes) { - - if (element && element[0]) element = element[0]; - - /* self.log('element'); - self.log(element); */ - if (element && element.isConnected) { - - var route = routes[index]; - - var routeParts = route.match(/([^:]*):eq\((\d*)\)/); - - /* self.log('route'); - self.log(route); - self.log('routeParts'); - self.log(routeParts); */ - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - /* self.log('routeElement'); - self.log(routeElement); - self.log('routeIndex'); - self.log(routeIndex); */ - if (routeElement.startsWith('.')) - routeElement = '.' + self.classSelector(routeElement); - - //if (self.exist(routeElement)) - element = element.querySelectorAll(routeElement)[routeIndex]; - - if (index == (routes.length - 1) && element) { - /* console.log('index:'+index); - console.log('routes.length:'+routes.length); */ - element = [element]; - } - - } else { - //if (self.exist(route)) - if (route.startsWith('.')) - routeElement = '.' + self.classSelector(route); - - /* self.log('route'); - self.log(route); */ - element = element.querySelectorAll(route); - } - } else { - //self.log('!element.isConnected'); - element = []; - } - } - - //if (element && !Array.isArray(element)) element = [element]; - //if (element && !element.length) element = [element]; - if (!element) - self.log('No element selected by ' + selector); - //else - // if (!Array.isArray(element)) - // element = [element]; - return element; - } - } else { - console.log('%cDOM queryAll requires selector argument', 'color: orange'); - //self.log('DOM "query" without selector parameters'); - } - }; - - /* this.queryAll = function (selector, element) { - //self.log('query: '+selector); - if (selector) { - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - var route = routes[index]; - - //onsole.log('route'); - //self.log(route); - - var routeParts = route.match(/(.*):eq\((\d*)\)/); - - //self.log('routeParts'); - //self.log(routeParts); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - //if (self.exist(routeElement)) - element = [element.querySelectorAll(routeElement)[routeIndex]]; - } else { - //if (self.exist(route)) - element = element.querySelectorAll(route); - } - } - //element.innerHTML = 'test'; - //element.style.display = 'none'; - //if (element && !Array.isArray(element)) element = [element]; - //self.log(element); - - return element; - } else { - self.log('DOM "query" without selector parameters'); - } - } */ - /* var querySelectorAllWithEq = function(selector, document) { - var remainingSelector = selector; - var baseElement = document; - var firstEqIndex = remainingSelector.indexOf(':eq('); - - while (firstEqIndex !== -1) { - var leftSelector = remainingSelector.substring(0, firstEqIndex); - var rightBracketIndex = remainingSelector.indexOf(')', firstEqIndex); - var eqNum = remainingSelector.substring(firstEqIndex + 4, rightBracketIndex); - eqNum = parseInt(eqNum, 10); - - var selectedElements = baseElement.querySelectorAll(leftSelector); - if (eqNum >= selectedElements.length) { - return []; - } - baseElement = selectedElements[eqNum]; - - remainingSelector = remainingSelector.substring(rightBracketIndex + 1).trim(); - // Note - for now we just ignore direct descendants: - // 'a:eq(0) > i' gets transformed into 'a:eq(0) i'; we could maybe use :scope - // to fix this later but support is iffy - if (remainingSelector.charAt(0) === '>') { - remainingSelector = remainingSelector.substring(1).trim(); - } - - firstEqIndex = remainingSelector.indexOf(':eq('); - } - - if (remainingSelector !== '') { - return Array.from(baseElement.querySelectorAll(remainingSelector)); - } - - return [baseElement]; - }; */ - this.jitcss = function (classes) { - // https://tailwindcss.com/docs/just-in-time-mode - if (classes.indexOf('-[') > -1) { - let classesArr = classes.split(' '); // change to one or more spaces - - // (sm\:|md\:|lg\:|xl\:|2xl\:)? - self.log('jitcss'); - - for (cl of classesArr) { - self.log(cl); - let par = [...cl.matchAll(new RegExp('([^-]+)[\-][\[](.+)\]', 'g'))]; - self.log('jitcss'); - self.log(par); - } - } - - /* sm:w-1 - - .w-1 { - width: 1em; - } - - @media (min-width: 640px) { - .sm\:w-1 { width: 1em } - } - */ - }; - - this.compileClasses = function (string) { - - var classesString = string; - - // classes shortcuts - if (self.json.shortcuts && self.json.shortcuts.class) { - for (shortcut in self.json.shortcuts.class) { - if (string.indexOf(shortcut) > -1) { - classesString = self.replaceAll(string, shortcut, self.json.shortcuts.class[shortcut]); - } - } - } - - // dynamic classes - if (string.indexOf('(') >= 0) { - //self.log('compileClasses'); - classesString = ''; - let classesArr = string.split(' '); - for (cl of classesArr) { - /* self.log('cl'); - self.log(cl); */ - if (cl.indexOf('(') >= 0 && cl.endsWith(')')) { - let classArr = cl.split('('); - classArr[1] = classArr[1].slice(0, -1); // remove ) - - - - - - - - //let par = [...cl.match(new RegExp('([^\(]+)\(([^\)]+)\)$'))]; // doesn't work - /* self.log('classArr'); - self.log(classArr); - self.log('classArr[1]'); - self.log(classArr[1]); - self.log('self.js(classArr[1])'); - self.log(self.js(classArr[1])); */ - if (Boolean(self.js(classArr[1]))) { - if (classesString !== '') classesString += ' '; - classesString += classArr[0]; - } - - } else { - if (classesString !== '') classesString += ' '; - classesString += cl; - } - } - - if (string == classesString) { - self.log('wrong dynamic class syntax'); - self.log(string); - } - - } - - return classesString; - - }; - - this.createElement = function (params, selectorParams) { - - let selector = params.selector || params.container; - var container = selector || self.selector(selectorParams); - var containerElement = self.query(container); - var newSelector = self.selector(params, selectorParams); // from 0.9.6: must stay before document.createElement - - - - - - - /* console.log('append'); - console.log('selector:'+selector); - console.log('container:'+container); - console.log('newSelector:'+newSelector); */ - var newElements = []; - - //if (containerElement) - //containerElements.forEach(function (containerElement, index) { - if (containerElement) { - - if (!params) params = {}; - - var element = document.createElement(params.tag); - - containerElement.appendChild(element); - - if (params.attr) { - // shortcuts (windy property not in twind) and dynamic classes with js condition - if (params.attr.class) { - // replace shortcuts and dynamic classes: class(condition) - params.attr.class = self.compileClasses(params.attr.class); - } - } - - //if (container) element.setAttribute('data-selector', self.selector(params, selectorParams)); - //if (container) element.setAttribute('data-selector', newSelector); // from 0.9.6. removed 1.0.12 - // for IDE - self.dataStorage.set(element, 'code', params); - self.dataStorage.set(element, 'key', params.key); - - /* if (params.attr && params.attr.class) - self.jitcss(params.attr.class); */ - newElements.push(element); - - if (params.attr) self.setAttributes(newElements, params.attr); - if (params.style) self.css(params, newSelector); // TO DO: deprecated / to be removed; - - - - - - - - - /* // attributes TO DO: move up / call self.attr - if (params.attr) - for (var attrId in params.attr) - self.attribute(newElements, attrId, self.replaceProperties(params.attr[attrId])); - //self.log(self.replaceProperties(params.attr[attrId])); - //$(selector).attr(attrId, params.attr[attrId]); */ - } - - //}); - return newElements; - - /* for (let element of elements) { - element.appendChild(string); - } */ - }; - - /* this.newSelector = function (params, selectorParams) { - var container = self.selector(self.extend({}, params, selectorParams), undefined, true); - if (container) { - var selectorObj = { - container: container, - //class: params.class, - //value: params.value, - //'data-value': params['data-value'] - }; // , selectorParams); - self.log('container'); - self.log(container); - var index = document.querySelectorAll(container).length; - if (index > 1) selectorObj.index = index-1; - self.log('newSelector'); - self.log(selectorObj); - return selectorObj; - } else { - self.log('container undefine in newSelector'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } -*/ - /* - this.editor = function (params, selectorParams, args) { - self.log('editor'); - self.log('params'); - self.log(params); - var selector = self.selector(selectorParams, undefined, true); // self.selector(params, undefined, true) || - if (selector) { - var element = self.query(selector); - - if (element) { - - if (!self.quillElements[selector]) { - self.quillElements[selector] = new Quill(element, { - modules: params.modules || { // or default modules - toolbar: [ - [{ header: [1, 2, false] }], - ['bold', 'italic', 'underline'], - ['image', 'code-block'] - ] - }, - // scrollingContainer: '#scrolling-container', - placeholder: params.placeholder || 'Write here', - theme: params.theme || 'bubble' - }); - } - - if (self.quillElements[selector]) { - - if (params.setContents) { - var contents = self.replaceProperties(params.setContents, args); - self.quillElements[selector].setContents(contents); - } - - if (params.getContents) { - self.quillElements[params.getContents].getContents(); - } - - if (params.on) { - - for (var eventId in params.on) { - self.editorChangeFunctions[selector] = params.on; - - if (params.on[eventId]) { - - self.quillElements[selector].on(eventId, function(delta, oldDelta, source) { - var action = self.editorChangeFunctions[selector][eventId]; - var actionWithResult = self.replaceResult(action, delta); - //self.do(actionWithResult); - self.do(actionWithResult); - - }); - } - } - } - } - } else { - self.log('can\'t find the element "'+ selector + '" ("editor" function)'); - self.log(params); - } - } else { - self.log('the "editor" function has a wrong selector'); - self.log(params); - } - - } - */ - this.do = this.action = this.execute = function (params, selectorParams, args) { - /* self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - self.log('args'); - self.log(args); */ - - if (params !== undefined && params !== null) { // empty string is ok - - /* - // problematic for nested {args} / {selector} - if (selectorParams && typeof selectorParams == 'string') { - params = self.replaceProperty(params, 'selector', selectorParams); - } - if (args) { - params = self.replaceProperty(params, 'args', args); - } - */ - if (typeof params == 'string') - params = self.replaceProperties(params, args); - - let pluginsRequired = self.pluginsRequired(params); - /* self.log('pluginsRequired'); - self.log(pluginsRequired); */ - if (pluginsRequired.length > 0) - //let params = [params, args, selectorParams]; - self.pluginsLoader(pluginsRequired, self.do, [params, selectorParams, args]); - else { - - if (Array.isArray(params)) - for (var obj of params) - self.do(obj, selectorParams, args); // -> execute dopo aver portato qui pluginsLoaded - else if (typeof params == 'object') { - - /* if (params.after) { - let paramsAfter = params.after; - let paramsWithoutAfter = self.cloneObject(params); - delete paramsWithoutAfter.after; - self.timer({ - after: paramsAfter, - do: paramsWithoutAfter - }); - } else { - */ - if (params.if == undefined || self.if(params.if)) { // || Boolean(self.js(params.if))) { // , args - /* console.log('IF---------------'); - console.log(params.if); - console.log(params); */ - if (self.only(params.roles, params.user)) { - - //if (!params) params = {}; - //var newContainer; //self.newSelector(params, selectorParams); // {container: selector} - // Add an element in the DOM - if (params.tag) { - - var selector = self.selector(params, selectorParams); - - /* self.log('selector'); - self.log(selector); */ - self.extendJsonFromElement(params); // or selectorParams - - - - - - //newContainer = {selector: selector}; - //if (1) //self.user('uid') == 'L0y20rjPp6a6ejqVuDXuTWCU2rH3') //'ocXuFBV4aWcy7KZMAmi6mICFi872') - // create new html element - var newElements = self.createElement(params, selectorParams); - - /* if (params.key == 'text') - //let element = self.query(self.selector(params.selector)); - newElements.innerText = self.text(nested); */ - if (params.matchMedia) { - for (var mediaEvent in params.matchMedia) { - self.matchMedia(params.matchMedia[mediaEvent], mediaEvent); - } - } - - if (params.html) { - - self.html(params.html, selector, args); - - } else { - - // nested html tags as property - for (var par in params) // && (par !== 'attr') - if ((nodes.exclude.indexOf(par) < 0) && (nodes.params.indexOf(par) < 0)) - self.nested({ key: par, obj: params[par], selector: { selector: selector }, args: args }); - - } - - self.on(params.on, { selector: selector }); - - - } else { - - var selector = self.selector(params, selectorParams); - - for (var par in params) - if ((nodes.exclude.indexOf(par) < 0) && (nodes.params.indexOf(par) < 0)) - self.nested({ key: par, obj: params[par], selector: selector, args: args }); - - if (params.on) - self.on(params.on, { selector: selector }); - - } - - - } // end of self.only - - } - //} - } else if (typeof params == 'function') - return params(selectorParams); - - else - self.log('can\'t execute: ' + params); - } - - } - }; - - this.callback = function (params) { - /* console.log('callback'); - console.log(params); */ - // {do, find, replace} - if (params) { - var path = params.to; - if (params.var) path = 'var ' + params.var; // TO DO: remove - let selector; - let element = params.element; // elementToSelector ? - if (element && element.isConnected) params.value = self.elementToSelector(element); - if (path) { - var context = self.context(path); - self.element({ path: path, value: params.value, root: context }); - } - if (params.do) - self.do(params.do, selector); - } - }; - - this.nested = function (params) { - /* console.log('nested'); - console.log(params); */ - // check plugins required - let pluginsRequired = self.pluginsRequired(params.key); - if (pluginsRequired.length > 0) { - self.pluginsLoader(pluginsRequired, self.nested, [params]); - } else { - - - - // TO DO: regular expression like in this.element (should include setup and also :) - if (params.key.startsWith('set ')) { - self.setData({ key: params.key.substr(4), value: params.obj }); - } else if (params.key.startsWith('var ') || params.key.startsWith('data ') || params.key.startsWith('set ')) { - // TO DO: remove this option. Is too ambiguous for debug -> use set - // deprecated from 1.0.4 - console.log('%cdeprecated key: "' + params.key + '". Use "set key": "value"}', 'color:orange'); - - // Data setting prefix - // should be removed and replaced with the method "set" to improve the compatibility - // with the other possible keys (js functions, jsonic methods, html tags ex. ) - // https://www.w3schools.com/tags/tag_data.asp - self.setData({ key: params.key, value: params.obj }); - - } else { - - // CHECK IF KEY IS METHOD - //console.log('check if is a method'); - var method = self.element({ path: params.key, root: self.methods }); - - if (method) { // search in jsonic.methods - self.log('METHOD: ' + params.key, 'grey'); - var methodArgs = params.obj; - - /* if (params.key == 'swiper init') { - self.log('method: ' + params.key); - self.log('methodArgs'); - self.log(methodArgs); - self.log('params.selector'); - self.log(params.selector); - self.log('-----------'); - } */ - //methodArgs = self.replaceProperty(methodArgs, 'selector', params.selector); - method(methodArgs, params.selector, params.args); - - - /* } else if (params.key == 'set') { // TO DO: REMOVE - - // JS METHOD (old) - - var actionObj = {}; - actionObj[params.key] = params.obj; - self.do(actionObj, params.selector); */ - /* } else if (nodes.functions.indexOf(params.key) >= 0) { // TO DO: REMOVE - - // JS METHOD (old) - - var actionObj = {}; - actionObj[params.key] = params.obj; - //self.do(actionObj, undefined, params.selector); - self.do(actionObj, params.selector); */ - } else { - - // CHECK IF KEY IS A PARTS - //console.log('check if is a part'); - // shortcut: content - let nested; - let part; - - var jsonicPart = false; - if (self.json.parts) { // && par.match(/[.>]+/)) - part = self.element({ path: self.replaceAll(params.key, ':', '.'), root: self.json.parts }); - /* if (par.indexOf(':')>0 && !part) { - jsonicPart = true; - self.firebaseGetPart({localPath:localPath, container: params.selector, arg:params.obj}); - } */ - } - - if (part) { - self.log('PART: ' + params.key, 'grey'); - - /* console.log('params'); - console.log(params); */ - var partObj = params.obj; - //nested = self.replaceProperty(part, 'value', params.obj); // obsolete? - //nested = self.replaceProperty(part, 'arg', partObj); // obsolete - //if (typeof partObj == 'string' && partObj.indexOf('{') >= 0) { // obsolete? - // TO DO: this should be already inside self.do - partObj = self.replaceProperties(partObj); - // for backward compatibility can be partObj, null, true) // true is removeUndefined - //} - /* console.log('partObj'); - console.log(partObj); - */ - //var partSelector = params.selector || partObj.selector; - // TO DO: Check this - // seems a workaround for fantacards/ui:qrcode - // parts can receive the parameters {selector:..., setup:...} - partObj.selector = partObj.selector || params.selector; - - // TO DO: deprecated fantacards:setPlayer - if (partObj.setup) partObj = partObj.setup; - // overwrites partObj.selector but execute receive params.selector - // TO DO: replaceProperty should be improved to get also sub values like {arguments:on.success} - //nested = self.replaceProperty(part, 'setup', partObj); // {setup} -> {arguments} - //nested = self.replaceProperty(nested, 'arguments', partObj); - //nested = self.replacePropertyWithPrefix(part, 'setup:', partObj); // {setup} -> {arguments} - //nested = self.replacePropertyWithPrefix(nested, 'arguments:', partObj);// to tix - nested = self.replacePropertyWithPrefix(part, 'setup', partObj); // {setup} -> {arguments} - nested = self.replacePropertyWithPrefix(nested, 'arguments', partObj); // to tix - - - self.extendJsonFromElement(nested); // or selectorParams - - //self.do(nested, partSelector, partObj); - self.do(nested, params.selector, partObj); - - /* - self.log('nested'); - self.log(nested); - - self.log('part key'); - self.log(params.key); - self.log('part obj'); - self.log(part); - */ - } else { // if (!jsonicPart) { // should be if (par !== 'on', 'attr', 'style', 'items/data') - // params.key is not var/data, a method, a part - //var jsFunction = self.element({path: params.key, root: self.functions}); - if (self.json && self.json.functions && params.key && self.json.functions[params.key]) { - //if (self.json.functions[params.key]) { - self.log('FUNCTION: ' + params.key, 'grey'); - - - /* self.log('pluginsRequired'); - self.log(pluginsRequired); */ - let args = self.replaceProperties(params.obj, undefined, true); // undefined properties -> '' - - - - - /* console.log('%cargs', 'color:red'); - console.log(args); */ - if (!args || !Array.isArray(args)) args = [args]; - - if (self.json.functions[params.key].requires) { - let pluginsRequired = []; - for (let plugin of self.json.functions[params.key].requires) { - if (!self.pluginsLoaded[plugin]) - pluginsRequired.push({ "name": plugin, version: "" }); - } - - if (pluginsRequired.length > 0) - //self.pluginsLoader(pluginsRequired, self.functions[params.key], args); - self.pluginsLoader(pluginsRequired, self.function, [{ name: params.key, arguments: args }]); - else { - self.log('Plugins already loaded: ' + params.key, 'grey'); - self.function({ name: params.key, arguments: args }); - //self.functions[params.key](...args); - } - } else { - /* let args = self.replaceProperties(params.obj); - if (!args || !Array.isArray(args)) args = [args]; */ - self.log('Function without plugin required: ' + params.key, 'grey'); - self.function({ name: params.key, arguments: args }); // TO DO: check why here it can't have [] - - //self.functions[params.key](...args); - } - - } else { - var windowFunction = self.element({ path: params.key, root: window }); - if (typeof windowFunction === 'function') { - self.log('WINDOW function: ' + params.key, 'grey'); - windowFunction(self.replaceProperties(params.obj, undefined, true)); // undefined properties -> '' - - //windowFunction(self.replaceProperties(params.obj)); - } else if (windowFunction !== undefined) { - self.log('window.' + params.key + ' is not a function', 'red'); - //self.log(params.key + ' not found', 'red'); - // use set for window assignment - /* - self.element({path: params.key, value:params.obj, root: window}); */ - } else { - // NESTED HTML - // Need to be improved. with nestedAction and nestedTag - // here we can search only nestedAction - // and from html we can search only for nestedTag's - //nested = params.obj; // removed in 1.0.1 - // if is a nested html params.selector is required - // impossible to understand if we are inside an html method - // because the html tags can be nested and with any name - if (params.selector) { // added in 1.0.1 - self.log('TAG: ' + params.key, 'grey'); - // should be also in this.html function if params is an array - let pluginsRequired = self.pluginsRequiredByTag(params.obj, params.key); - if (pluginsRequired.length > 0) { - let htmlTagParams = [params.obj, params.selector, params.key]; - self.pluginsLoader(pluginsRequired, self.htmlTag, htmlTagParams); - } else { - self.htmlTag(params.obj, params.selector, params.key); // tagParam = params.key - - //if (nested.database) self.addFirebaseTag(self.extend({}, nested, params.selector)); - } - } else { - self.log(params.key + ' not found', 'red'); - } - } - } - } - } - } - - } - }; - - this.setData = function (params) { - //self.log('setData'); - let setObj = {}; - setObj[params.key] = params.value; - self.set(setObj); - - /* if (params.path.indexOf('{') >= 0) - params.path = self.replaceProperties(params.path); - - if (typeof params.value == 'string' && params.value.indexOf('{') >= 0) - params.value = self.replaceProperties(params.value); - - self.element({path: params.path, value: params.value}); */ - /* self.log(params.path); - self.log(self.element({path: params.path})); */ - }; - - this.partContainers = {}; - - - - this.pluginsRequiredByTag = function (params, tagKey) { - // self.log('pluginsRequiredByTag'); - /* self.log('params'); - self.log(params); - self.log('par'); - self.log(par); */ - - if (self.json.resources) { - - // analize function object or array of objects - const pluginsTags = self.json.resources.pluginsTags; - const pluginsAttr = self.json.resources.pluginsAttr; - var pluginsRequired = []; - - if (pluginsTags[tagKey] && !self.pluginsLoaded[pluginsTags[tagKey].name]) - pluginsRequired.push(pluginsTags[tagKey]); - - - - if (typeof params == 'string') { - // for example: "tagName": "string" where tagName requires a plugin - } else if (typeof params == 'object') { - - var objArray; - if (Array.isArray(params)) objArray = params; else objArray = [params]; - - for (var obj of objArray) { - if (obj.attr) { // attr - var attr = 'data-icon'; - if (obj.attr[attr]) { - if (pluginsAttr[attr] && !self.pluginsLoaded[pluginsAttr[attr].name]) - pluginsRequired.push(pluginsAttr[attr]); - } - } - } - } - return pluginsRequired; - } else { - // should load resources - return false; - } - }; - - /* - - 'locale': { - unit: month, weekday - format: long, short, narrow - index: 1, - lang: page:language - */ - this.calendar = function (params, args) { - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-US'; - let calendarArr, todayIndex; - - if (params.unit) { - switch (params.unit) { - case 'month': - const monthFormat = params.format || 'long'; - var format = new Intl.DateTimeFormat(localeName, { month: monthFormat }).format; - calendarArr = [...Array(12).keys()].map((m) => format(new Date(Date.UTC(2021, m)))); - todayIndex = new Date().getMonth(); - break; - case 'weekday': - const weekdayFormat = params.format || 'long'; - var format = new Intl.DateTimeFormat(localeName, { weekday: weekdayFormat }).format; - calendarArr = [...Array(7).keys()].map((day) => format(new Date(Date.UTC(2021, 5, day)))); - todayIndex = self.weekday(); - break; - default: - self.log('"calendar" function can\'t recognize "unit" parameter'); - self.log(params.unit); - break; - } - - if (calendarArr) { - if (params.index !== undefined) { - params.index = self.js(params.index); - let index = Number(self.replaceProperties(params.index, args)); - return calendarArr[index]; - } else { - return calendarArr[todayIndex]; - } - } else { - self.log('"calendar" function can\'t recognize "unit" or "format" parameters'); - } - - } else { - self.log('"calendar" function requires "unit" parameter'); - } - - }; - - - - this.month = function (params, monthFormat = 'long') { - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-GB'; - const format = new Intl.DateTimeFormat(localeName, { month: monthFormat }).format; - const weekdayArr = [...Array(12).keys()].map((m) => format(new Date(Date.UTC(2021, m)))); - if (params !== undefined) { - var index = Number(self.replaceProperties(params)); - return weekdayArr[index]; - } - else - return weekdayArr; - }; - - this.weekday = function (params, weekdayFormat) { - //weekdayFormat = weekdayFormat || 'long'; - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-GB'; - const format = new Intl.DateTimeFormat(localeName, { weekday: weekdayFormat }).format; - const weekdayArr = [...Array(7).keys()].map((day) => format(new Date(Date.UTC(2021, 5, day)))); - var result; - if (params !== undefined) { - var index = Number(self.replaceProperties(params)); - result = weekdayArr[index]; - } - else - result = weekdayArr; - - //if (weekdayFormat == 'short') result = result.substring(0,3); - return result; - - }; - - /* this.array = function (params, args) { // TO DO: to be removed - self.log('array'); - self.log(params); - - if (Array.isArray(params)) - return params; - else if (typeof params == 'string') - return self.docElement(params); - else if (typeof params == 'object') { - if (params && Object.keys(params).length > 0) { // actionObj !== {} - var actionKey = Object.keys(params)[0]; // -> for - var actionFunction = self.docElement('Array.prototype.' + actionKey); // method in window - var actionValue = params[actionKey]; - - //actionValue = self.compile(actionValue, args); // array -> undefined - if (!Array.isArray(actionValue)) - actionValue = [actionValue]; - - if (actionFunction) { - if (typeof actionFunction == 'function') - return actionFunction.call(actionValue); - else - return actionFunction; - } else { - self.log('unknown window function'); - return params; // return the same object - } - } else { - self.log('empty function'); - //self.log(actionObj); - return undefined - } - } - } */ - this.method = function (params, args) { - - var value; - - if (typeof params == 'string') { - return self.docElement(params); - } else { - - if ((params.if == undefined) || self.if(params.if, undefined, args)) { - - if (self.notEmptyObject(params)) { - var actionKey = Object.keys(params)[0]; // -> for - var actionFunction = self.docElement(actionKey); // method in window - var actionValue = params[actionKey]; - //actionValue = self.compile(actionValue, args); - if (!Array.isArray(actionValue)) - actionValue = [actionValue]; - if (actionFunction) { - if (typeof actionFunction == 'function') - return actionFunction(...actionValue); - - else - return actionFunction; - } else { - self.log('unknown function'); - self.log(params); - return params; // return the same object - } - } else { - //self.log('empty function'); - //self.log(params); - return undefined; - } - } - } - - /* - var methodArgs = self.compile(actionValue, args); - - if (value !== undefined) { - - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - - self.log('params'); - self.log(params); - - for (let method of methodArgs) { - for (let key in method) { - if (key !== 'args') { - self.log('key'); - self.log(key); - if (value[key]) - if (method[key] && method[key] !== '') { // va aggiunto? -> && value[key](method[key]) method[key] !== undefined && - methodArgs = method[key]; - self.log('methodArgs'); - self.log(methodArgs); - - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - for (let index in methodArgs) { - let methodArg = self.compile(methodArgs[index], args); - //if (typeof methodArg == 'string' && methodArg !== '' && methodArg == Number(methodArg)) // can be in compile - methodArgs[index] = methodArg; // Number(methodArg) - } - //try { - //} catch (error) { - // self.log('Dayjs function error'); - if (typeof value[key] == 'function') - value = value[key](...methodArgs); // ES6 way - } else - if (typeof value[key] == 'function') - value = value[key](); - else - value = value[key]; - } else { - self.log('Method ' + key + ' in ' + methodName + ' not exist'); - } - } - } - - } else { - self.log('method '+ methodName +' undefined'); - - } - */ - }; - - this.Number = function (params, args) { - self.log('Number'); - return self.method({ "Number": params }, args); - }; - - this.String = function (params, args) { - self.log('String'); - return self.method({ "String": params }, args); - - // jsonic.compile({String:{args:'1',padStart:[2, '0']}}) - /* - "text": { - "String": { - "args": "{hour}", - "padStart": [ - "0", - 2 - ] - } - } - */ - }; - - this.Math = function (params, args) { - return self.method(params, args, 'Math'); - - /* if (!Array.isArray(params)) - params = [params]; - - for (let method of params) { - for (let key in method) { - self.log(key); - if (method[key] && method[key] !== '' && value[key](method[key])) { - //methodArgs = self.compile(method[key]); - methodArgs = method[key]; - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - for (let index in methodArgs) { - let methodArg = self.compile(methodArgs[index]); - if (typeof methodArg == 'string' && methodArg !== '' && methodArg == Number(methodArg)) // can be in compile - methodArgs[index] = Number(methodArg); - } - value = value[key](...methodArgs); // ES6 way - } else - value = value[key](); - } - } - - return value; */ - }; - - - this.dayjs = function (params, args) { - - return self.method(params, args, 'dayjs'); - - /* self.log('dayjs'); - - var value = dayjs(); - if (params.time) - value = dayjs(params.time); - //value = self.compile(value); - - if (!Array.isArray(params)) - params = [params]; - - - for (let method of params) { - for (let key in method) { - - if (key == 'time') { - } else if (value[key]) { - if (method[key] && method[key] !== '' && value[key](method[key])) { - //methodArgs = self.compile(method[key]); - methodArgs = method[key]; - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - for (let index in methodArgs) { - let methodArg = self.compile(methodArgs[index]); - if (typeof methodArg == 'string' && methodArg !== '' && methodArg == Number(methodArg)) // can be in compile - methodArgs[index] = Number(methodArg); - } - value = value[key](...methodArgs); // ES6 way - } else - value = value[key](); - } else { - try { - } catch (error) { - self.log('Dayjs function error'); - self.log(error); - self.log('key'); - self.log(key); - self.log('method[key]'); - self.log(method[key]); - } - - } - } - self.log('value'); - self.log(value); - } - return value; */ - }; - - this.moment = function (params, args) { - - return self.method(params, args, 'moment'); - - /* self.log('moment'); - - var value = moment(); - if (params.time) - value = moment(params.time); - - if (!Array.isArray(params)) - params = [params]; - - for (let method of params) { - for (let key in method) { - if (key !== 'time') { - if (key == 'add') { - value = value.add(Number(method[key].value), method[key].unit); - } else if (key == 'subtract') { - value = value.add(Number(method[key].value), method[key].unit); - } else if (method[key] && method[key] !== '' && value[key](method[key])) { - value = value[key](method[key]); - } else { - self.log('Moment function error: '); - self.log('key'); - self.log(key); - self.log('method[key]'); - self.log(method[key]); - } - } - } - self.log('value'); - self.log(value); - - } - return value; - */ - }; - - - /* const methodsList = ['day, format', 'year', 'years', 'quarter', 'dayOfYear', 'month', 'months', 'date', 'minute', 'minutes', 'hour', 'hours', 'second', 'seconds', 'millisecond', 'milliseconds', 'weekday', 'weekdays', 'isoWeekday', 'weekYear', 'isoWeekYear', 'weeksInYear', 'week', 'isoWeek', 'set', 'max', 'min', 'local', 'parseZone', 'unix', 'utc', 'utcOffset', 'zone', 'isValid', 'invalid', 'valueOf', 'startOf', 'endOf', 'fromNow', 'toNow', 'from', 'to', 'calendar', 'diff', 'daysInMonth', 'toDate', 'toArray', 'toJSON', 'toString', 'toISOString', 'toObject', 'inspect', 'isBefore', 'isSame', 'isAfter', 'isSameOrBefore', 'isSameOrAfter', 'isBetween', 'isDST', 'isLeapYear', 'isDate', 'locale', 'localeData', 'lang', 'monthsShort', 'weekdaysShort', 'weekdaysMin', 'defineLocale', 'updateLocale', 'monthsParse', 'weekdaysParse', 'longDateFormat', 'isPM', 'meridiem', 'relativeTime', 'pastFuture', 'ordinal', 'preparse', 'postformat', 'invalidDate', 'firstDayOfWeek', 'firstDayOfYear', 'duration', 'clone', 'humanize', 'asMilliseconds']; - for (var method in methodsList) { - if (params[method]) value = value[method](params[method]); - } */ - /* for (let param in params) { - if (param !== 'time') { - if (typeof value == 'object') { - //if (param == 'day') value = value.day(Number(params[param])); - if (param == 'add') { - self.log('params.add.value'); - self.log(params.add.value); - self.log('params.add.unit'); - self.log(params.add.unit); - self.log('value'); - self.log(value); - value.add(Number(5), params.add.unit); - self.log('value.format(H)'); - self.log(value.format('H')); - } - else if (param == 'subtract') value.add(Number(params.subtract.value), params.subtract.unit); - else if (value[param] && value[param](params[param])) - value = value[param](params[param]); - else - self.log('Moment function error: '+ params[param]); - } - self.log('value'); - self.log(value); - } - } -*/ - /* this.addNestedTag = function (params, selectorParams) { - var selector = self.selector(self.extend({}, params, selectorParams)); - // remove tag params - var nestedParams = self.cloneObject(params); - var tagParams = ['tag', 'container', 'id', 'class', 'value', 'data-value', 'style', 'attr', 'title', 'text', 'animation', 'action', 'on', 'src', 'media', 'color', 'background', 'width', 'height', 'margin', 'padding', 'firebase']; - for (var par in nestedParams) { - if (tagParams.indexOf(par) >= 0) - delete nestedParams[par] - } - - // serach for nested params - var mainTags = ['div', 'ul', 'p', 'span', 'a', 'button', 'input', 'textarea', 'iframe', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'figure', 'figcaption', 'svg', 'small', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'icons']; - for (var par in nestedParams) { - self.log(par + ' NESTED IN ' + selector); - if (mainTags.indexOf(par) >= 0) { - self.htmlTag(nestedParams[par], {container: selector}, mainTags[mainTags.indexOf(par)]); - } - } - } */ - this.dynamicCss = function (selector, property, value) { - if (value.indexOf('{') >= 0) { - var resizeData = self.dataStorage.get(element, "resize"); - //var resizeData = $(selector).data('resize'); - if (!resizeData) resizeData = {}; - resizeData[property] = value; - var resizeData = self.dataStorage.set(element, "resize", resizeData); - //$(selector).data('resize', resizeData); - if (!self.resizeActions[selector]) self.resizeActions[selector] = {}; - self.resizeActions[selector][property] = value; - var result = self.replaceProperties(value) || ''; - //$(selector).css(property, result); // al cambio di pagina su this.page applichiamo self.resizeEvent() - /* self.log('----------------------'); - self.log('dynamicCss'); - self.log('selector'); - self.log(selector); - self.log('property'); - self.log(property); - self.log('value'); - self.log(value); - self.log('result'); - self.log(result); - self.log('----------------------'); - */ - } else { - var style = {}; - style[property] = value; - self.css({ - style: style - }); - //$(selector).css(property, value); - } - }; - - /* this.calc = function (selector, property, value) { - if (value.indexOf('{')>= 0) { - //var calcFunction = String(element.match(/calc\(([^\)]*)\)/)[0]); - var result = self.replaceProperties(value) || ''; - return result; - } else { - return value; - } - } */ - /* this.hTag = function (params, selectorParams, index) { // this.img already exist - if (Array.isArray(params)) { - for (var index in params) - self.hTag(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.hTag(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'h'+index; - var paramsReplaced = self.replaceProperties(params); - self.addTag(paramsReplaced, selectorParams); - } - } - } */ - /* this.img = function (params, selectorParams, args) { - //self.log('img'); - var tagParam = 'img'; - var mainParam = 'src'; - - if (Array.isArray(params)) { - for (var index in params) - self.img(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.img(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {src: params}}; - params.tag = 'img'; - //if (params.media) params.src = '{media:' + params.media + '}'; // can go under replaceProperties - var paramsReplaced = self.replaceProperties(params, args); - //var container = params.container || self.selector(selectorParams); - - self.addTag(paramsReplaced, selectorParams); - } - } - } */ - /* this.small = function (params, selectorParams) { // bootstrap - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.small(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.small(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'small'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* this.button = function (params, selectorParams) { // bootstrap - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.button(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.button(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'button'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* - this.input = function (params, selectorParams) { - var tagParam = 'input'; - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.input(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.input(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - self.addTag(self.createTagParams(params, tagParam, mainParam), selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } - - this.span = function (params, selectorParams) { - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.span(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.span(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - params.tag = 'span'; - // qui ci andrebbe replaceProperties - if (typeof params == 'string') {params = {text: params}}; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } - */ - /* this.a = function (params, selectorParams) { - var mainParam = 'text'; - var tagParam = 'a'; - if (Array.isArray(params)) { - for (var index in params) - self.a(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.a(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'a'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* this.p = function (params, selectorParams) { - var mainParam = 'html'; - if (Array.isArray(params)) { - for (var index in params) - self.p(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.p(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {html: params}}; - params.tag = 'p'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* this.lottie = function (params, selectorParams, args) { - self.htmlTag(params, selectorParams, 'lottie-player', 'src'); - } */ - //this.lottie = function (params, selectorParams, args) { - // self.htmlTag(params, selectorParams, 'lottie-player', 'src'); - /* self.log('lottie'); - var mainParam = 'src'; - var tagParam = 'lottie-player'; - if (Array.isArray(params)) { - for (var index in params) - self.lottie(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.lottie(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - var container = params.container || self.selector(selectorParams); - // qui ci andrebbe replaceProperties - //this.alert(self.selector(self.extend({}, params, selectorParams))); - self.addTag(self.createTagParams(params, tagParam, mainParam), {container: container}); - //if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } */ - //} - /* this.iframe = function (params, selectorParams) { - var mainParam = 'src'; - if (Array.isArray(params)) { - for (var index in params) - self.iframe(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.iframe(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {src: params}}; - params.tag = 'iframe'; - var paramsReplaced = self.replaceProperties(params); - self.addTag(paramsReplaced, selectorParams); - } - } - } */ - /* this.textarea = function (params, selectorParams) { - if (Array.isArray(params)) { - for (var index in params) - self.textarea(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.textarea(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (!params.tag) params.tag = 'textarea'; - //params.container = params.container || self.selector(selectorParams); - self.addTag(params, selectorParams); - } - } - } */ - /* - this.div = function (params, selectorParams) { - if (params.firebase) { - self.log('=========='); - self.log('div'); - self.log(params); - self.log('=========='); - } - - var tagParam = 'div'; - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.div(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.div(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - self.addTag(self.createTagParams(params, tagParam, mainParam), selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } - - this.ul = function (params, selectorParams) { - if (Array.isArray(params)) { - for (var index in params) - self.ul(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.ul(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - params.tag = 'ul'; - - var paramsReplaced = self.replaceProperties(params); - self.addTag(paramsReplaced, selectorParams); - if (params.firebase) self.addFirebaseTag(params); - } - } - } - */ - this.li = function (params, selectorParams) { - if (Array.isArray(params)) { - for (var index in params) - self.li(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = (typeof params.items == 'string') ? self.json.items[params.items] : params.items; - //var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - if (self.only(itemsArray[index].roles)) - self.li(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') { params = { html: params }; }; - params.tag = 'li'; - //params.container = params.container || self.selector(selectorParams); - self.do(params, selectorParams); - } - } - }; - - this.remove = function (params, selectorParams, args) { - var selector = self.selector(params.selector || self.selector(selectorParams)); - if (selector) { - var elements = self.queryAll(selector); - if (elements) { - elements.forEach(function (element, index) { - element.remove(); - }); - } - } - }; - - this.dispatchEvent = function (params, selectorParams, args) { - var selector = self.selector(params.selector || self.selector(selectorParams)); - if (selector) { - var elements = self.queryAll(selector); - if (elements) { - elements.forEach(function (element, index) { - element.dispatchEvent(new Event(params.name)); - }); - } - } - }; - - /* this.element with "selector" and "method": (remove/dispatchEvent) */ - this.html = function (params, selectorParams, args) { - /* self.log('html'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); */ - - // TO DO: update - // html properties can be only: - // selector, attr, html, on, for, if - // can't be: - // animate (should go inside on: init?) - // tags (div etc) because it should go inside html - // do - // functions, window functions... - // text should be alternative to html tag. if inside html, it should give an error - // TO DO: verificare se args viene portato agli elementi annidati (non andava con svg) - if (params) { - - if (Array.isArray(params)) { - - // TO DO: shoud check if params require plugins - for (var obj of params) - self.html(obj, selectorParams, args); - } else { - - //if (params.container == '#weatherReport') alert() - //var container = (selectorParams) ? self.selector(selectorParams) : params.container; // unused - //var selector = self.selector(self.extend({}, params, selectorParams), undefined, true); //), undefined, true); - /* - self.log('selector'); - self.log(selector); */ - var container = self.selector(params.selector || params.container) || self.selector(selectorParams); - //var container = self.selector(selectorParams, undefined, true) || self.selector(params, selectorParams, true); - /* self.log('container'); - self.log(container); */ - /* var element = self.query(container); - self.log('element'); - self.log(element); - */ - if (container) { - var element = self.query(container); - - // empty or not? probably yes (like jquery) but we need append/prepend method - // append only all the items in the array - // TO DO: queryAll -> elements - if (element) { - - if (typeof params == 'string') { - - //var paramsCompiled = self.compile(params, args); - var paramsCompiled = self.replaceProperties(params, args); - - //$(container).append(paramsCompiled); // should be .html not append - //element.appendChild(paramsCompiled); - if (paramsCompiled) { - if (typeof paramsCompiled == 'object') { - // should be a nested tag or actions on,for,if,empty - self.do(paramsCompiled, { selector: container }, args); - - } else if (typeof paramsCompiled == 'string') { - element.innerHTML += paramsCompiled; // TO DO: now is like append. Is it correct? - } - } - - } else { - - if (params.empty || params.do == 'empty') { - element.innerHTML = ''; - delete params.empty; - } - - if (params.tag) { - self.do(params, container, args); - //self.nested({key: params.tag, obj: params[par], selector: {selector: container}, args: args}); - } - else if (params.html) { - // replace \" to " - //var htmlCompiled = self.compile(params.html, args); // is undefined - // TO DO: replace all the following "compile" with replaceProperties? - /* self.log('params.html'); - self.log(params.html); */ - var htmlCompiled = self.replaceProperties(params.html, args); - /* self.log('htmlCompiled'); - self.log(htmlCompiled); */ - self.html(htmlCompiled, { selector: container }); - } else if (params.lang) { - //alert(self.json.setup.language); - var textLang = params.lang[self.json.setup.language] || params.lang['en'] || params.lang[Object.keys[0]]; - if (Array.isArray(textLang)) { - var paragraphs = []; - for (var paragraph of textLang) - paragraphs.push({ p: paragraph }); - self.html(paragraphs, selectorParams, args); - } - else - element.innerHTML = self.replaceProperties(textLang, args); - - if (element) { - self.attribute(element, 'data-text', true); // textKey instead of lang? - self.dataStorage.set(element, 'params', params); - } - - } else if (params.text) { // string - //params.text = self.replaceTags({text:params.text}); - //params.text = self.text(params.text); // verifica presenza di tags e traduzioni - //$(selector).text(self.compile(params.text, args)); - element.textContent = self.replaceProperties(params.text, args); - //} else if (params.empty || params.do == 'empty') { - // element.innerHTML = ''; - } else if (params.append) { // string - //params.append = self.replaceTags({text:params.append}); - //$(selector).append(self.compile(params.append, args)); - //element.appendChild(self.compile(params.append, args)); - element.innerHTML += self.replaceProperties(params.append, args); - - } else if (params.prepend) { // string - //params.prepend = self.replaceTags({text:params.prepend}); - //$(selector).prepend(self.compile(params.prepend, args)); - //element.insertBefore(self.compile(params.prepend, args)); - element.innerHTML = self.replaceProperties(params.prepend, args) + element.innerHTML; - - } else if (params.blocks) { // obsolete - self.blocks(params.blocks, { selector: container }, args); - } else { - - let nestedParams = self.cloneObject(params); - if (nestedParams.style) delete nestedParams.style; - if (nestedParams.attr) delete nestedParams.attr; - - console.warn('UNKNOWN TAG'); - console.warn(params); - // on, for, if... (can be changed to include also html) - self.do(nestedParams, { selector: container }, args); - - - if (element.isConnected) { - // case "html":{selector:... attr: } - // the wrong use "html":{selector, attr, html:...} - // now doesn't work (because is inside the last else) - /* if (params.on) { - alert(container); - self.on(params.on, { selector: container }, args); - } */ - - if (params.attr) self.setAttributes(element, params.attr, args); - if (params.style) self.css(params, selectorParams, args); // to be removed - - // TO DO: params.style is deprecated (now in attr or css) - } - //self.blocks(params, selectorParams, args); - } - - - - } - } else { // !element - } - } else { - self.log('"html" object requires selector property', 'red'); - self.log(params); - //self.log(selectorParams); - } - - //} - //} - } - } else { - self.log('"html" object without params'); - } - - }; - - /* this.add = function (params) { // obsoleto, sostituito da html - var selector = self.selector(params); - if (params.inverse) - $(selector).append(params.html); - else - $(selector).prepend(params.html); - } */ - /* this.attr = function (params, selectorParams, args) { - var selector = self.selector(params); - var element = self.query(selector); - for (var attribute in params.attr) - elements.forEach(function (element, index) { - element.setAttribute(attrId, attrValue); - }); - } - */ - /* this.empty = function (params) { - // { [container, class, value, id] } - var selector = self.selector(params); - $(selector).empty(); - } */ - /* this.addClass = function (params) { - var selector = self.selector(params); - $(selector).addClass(params); - } - - this.removeClass = function (params) { - self.log('removeClass'); - var selector = self.selector(params); - $(selector).removeClass(params); - } */ - /* this.toggleClass = function (params) { - var selector = self.selector(params); - $(selector).toggleClass(params); - } */ - //"#wifi > ul > li > span[data-field=share]:contains('Private')" - this.setAttributes = function (elements, attrs, args) { - for (var attribute in attrs) - if (attrs[attribute]) - self.attribute(elements, attribute, self.replaceResult(attrs[attribute], args)); - else - self.attribute(elements, attribute, ""); - //self.attribute(elements, attribute, attrs[attribute]); - //self.attribute(elements, attribute, self.replaceWithPrefix(attrs[attribute], 'result', args)); // TO DO: check - // before remove and check all the {result} occurrence (result excludes do/then/success etc.) - // replaceResult replace {result} from Alert (should be obsolete) - // check in the actual apps if {result} is used - }; - -/* this.setAttributes = function (elements, attrs, args) { - if (!Array.isArray(elements)) elements = [elements]; - elements.forEach(function (element, index) { - for (var attribute in attrs) { - if (typeof attrs[attribute] == 'boolean' && attrs[attribute]) { // it consider also firebase (empty values are removed) - element.setAttribute(attribute, ""); - } else { - //if (attrs[attribute] == undefined) attrs[attribute] = ''; - element.setAttribute(attribute, self.replaceProperties(attrs[attribute])); - } - } - }); - self.attribute(elements, attribute, self.replaceResult(attrs[attribute], args)); - }; */ - - // TO DO: distinguish setAttribute from getAttribute - // because we need to set attribute empty - this.attribute = function (elements, attrId, attrValue) { - if (typeof attrValue !== undefined) { - if (!Array.isArray(elements)) elements = [elements]; - elements.forEach(function (element, index) { - if (typeof attrValue == 'boolean' && attrValue) { // it consider also firebase (empty values are removed) - element.setAttribute(attrId, ""); - } else { - element.setAttribute(attrId, self.replaceProperties(attrValue)); - } - }); - } else { - if (!Array.isArray(elements)) - return elements.getAttribute(attrId); // todo: intercept the error "Cannot read properties of undefined (reading 'getAttribute" - - else - return elements[0].getAttribute(attrId); - } - }; - - this.attr = function (params, selectorParams, args) { - // deprecated. to be replaced with "css" {selector, style, addClass, removeClass, toggleClass} - // css is used as an action to apply addClass removeClass toggleClass - // and to apply style: {...} - //params = self.replaceProperties(params); - self.css(self.replaceProperties(params), selectorParams, args); - }; - - this.styleElement = function (params, element, args) { - for (var styleName in params) { - if (styleName.startsWith('--')) - element.style.setProperty(styleName, self.replaceProperties(params[styleName], args)); - - else - element.style[styleName] = self.replaceProperties(params[styleName], args); - } - }; - - this.css = function (params, selectorParams, args) { - // {selector, style, addClass, removeClass, toggleClass} - - /* console.log('selectorParams'); - console.log(selectorParams); - console.log('css'); - console.log(params); */ - if (Array.isArray(params)) { - for (var obj of params) - self.css(obj, selectorParams, args); - /* } else if (params.selector && Array.isArray(params.selector)) { - for (let selector of params.selector) { - let obj = self.cloneObject(params); - obj.selector = selector; - self.css(obj, selectorParams, args); */ - } else { - - var selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - - //var selector = params.selector || selectorParams; - //var elements = document.querySelectorAll(selector); - //console.log(elements); - if (elements) { - elements.forEach(function (element, index) { - - if (element) { - - if (typeof params.style == 'object') { - self.styleElement(params.style, element, args); - } - - if (params.addClass) - self.addClass(element, params.addClass); - if (params.removeClass) - self.removeClass(element, params.removeClass); - if (params.toggleClass) - self.toggleClass(element, params.toggleClass); - - } else { - self.log('the function "css" can\'t find the selector ' + selector); - self.log(params); - self.log(selectorParams); - } - }); - } else { - self.log('"css" function is unable to select: ' + selector); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } - }; - - /* this.class = function (params) { // obsolete -> css - self.log('self.class'); - self.log(params); - // { [container, class, value, id] - // [style, addClass, removeClass] } - var selector = self.selector(params); - if (params.style) - $(selector).css(params.style); - if (params.add) - $(selector).addClass(params.add); - if (params.remove) - $(selector).removeClass(params.remove); - if (params.toggle) - $(selector).toggleClass(params.toggle); - } */ - /* this.createPage = function (data) { - // SPOSTATA SOTTO fixo.pages.js - - //self.log('createPage'); - //self.log(data); - if (!$('#'+data.id).length) { - $(data.container).append('
    '); - if (data.background) { - $('#'+data.id).css({ - 'background-color': data.background - }); - } - } - } */ - /* this.iconPng = function(icon) { - return 'https://'+self.domain+'/app/files/icons/100white/'+icon+'.png'; - } */ - /* this.imgTag = function (data) { - // DIPENDENZA CON iconPng - - var imgId = data.id || ''; - var imgClass = data.class || ''; - var imgValue = data.value || ''; - var imgStyle = data.style || ''; // || 'width: 84px; margin:6px 10px;'; // ATTENZIONE: stile predefinito da rimuovere - var onClick = (data.action) ? 'onclick="javascript:self.do(\''+data.action+'\',\''+imgValue+'\')" ' : ''; - return ''; - } */ - /* this.setImg = function (data) { - // Sembra inutilizzata - // DIPENDENZA CON iconPng - - // data = {icon, style} - var selector = self.selector(data); - var imgValue = data.value || ''; - $(selector).attr('src', self.iconPng(data.icon)); - if (data.style) $(selector).css(style); - if (data.action) { - $(selector).attr('onclick', 'javascript:self.do(\''+data.action+'\',\''+imgValue+'\')'); - } - } */ - // -------------- - // SVG - // -------------- - /* this.svgSet = function (params) { - //self.log('svgSet'); - //self.log(params); - if (self.json && self.json.icons) { - //if (self.json.setup && self.json.setup.icons) { - - if (params.icon) { - var iconObj = {}; - iconObj.icon = (params.icon.indexOf(':')) ? params.icon.split(/:/)[1] : string; - iconObj.set = (params.icon.indexOf(':')) ? params.icon.split(/:/)[0] : undefined; - - var svgIcons = self.json.icons || {}; // {src, prefix, suffix} - //var svgIcons = self.json.setup.icons || {}; // {src, prefix, suffix} - if (iconObj.set) - if (svgIcons[iconObj.set]) - svgIcons = svgIcons[iconObj.set]; - else - self.log('Can\'t find the icons set "'+iconObj.set+'" in "icons"'); - iconObj.src = svgIcons.src || ''; // serve? - var svgPrefix = svgIcons.prefix || ''; - var svgSuffix = svgIcons.suffix || ''; - //if (iconObj.src !== '' && iconObj.icon) iconObj.src = '#' + svgPrefix + iconObj.icon + svgSuffix; - if (iconObj.icon) { - - if (!svgIcons.preload) - // siamo vicini - iconObj.src = svgIcons.src + '#' + svgPrefix + iconObj.icon + svgSuffix; - else - iconObj.src = '#' + iconObj.set + '_' + svgPrefix + iconObj.icon + svgSuffix; - } - iconObj.viewbox = svgIcons.viewbox; // || '0 0 25 25'; - return iconObj; // {src, set, name, viewbox} - } else { - self.log('icon "name" parameter undefined'); - } - } else { - self.log('Can\'t find "icons" in "setup"'); - } - } - - this.svgChange = function (data) { - self.log('svgChange'); - self.log(data); - - var selector = self.selector(data); //), undefined, true); - var containerElement = self.query(selector); - - var elementSvg = containerElement.querySelectorAll('svg')[0]; - var elementSvgUse = elementSvg.querySelectorAll('use')[0]; - var elementSvgText = elementSvg.querySelectorAll('text')[0]; - var elementSvgCircle = elementSvg.querySelectorAll('circle')[0]; - - var iconObj = self.svgSet(data); // {src, set, name, viewbox} - - if (iconObj.src) - elementSvgUse.setAttribute('xlink:href', iconObj.src); - //$(data.container + ' > svg > use').attr('xlink:href', iconObj.src); - - if (data.text !== undefined) { - elementSvgText.textContent = data.text; - // $(data.container + ' > svg > text').text(data.text); - - var textY = 6.5; // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor - if (data.textSize !== undefined) {textY = data.textSize/2;} - - if (data.textPosition == 'bottom') { // textPosition should be removed - elementSvgUse.setAttribute('transform', 'translate(0, -20) scale(0.80)'); - //$(data.container + ' > svg > use').attr("transform", "translate(0, -20) scale(0.80)"); - textY += 26; - } - - elementSvgText.setAttribute('y', textY); - //$(data.container + ' > svg > text').attr('y',textY); - elementSvgText.style['font-size'] = data.textSize+'px'; - //$(data.container + ' > svg > text').css('font-size',data.textSize+'px'); - - } else { - elementSvgText.textContent = ''; - //$(data.container + ' > svg > text').text(''); - - } - if (data.background !== undefined){ - - elementSvgCircle.setAttribute('fill', data.background); - elementSvgCircle.setAttribute('fill-opacity', 1); - elementSvgCircle.style['stroke'] = data.background; - } - if (data.border !== undefined) { - elementSvgCircle.setAttribute('stroke-opacity', 1); - elementSvgCircle.style['stroke'] = data.border; - } - - if (data.color !== undefined && data.color !== 'colored') { - elementSvgUse.style['fill'] = data.color; - } - if (data.textColor !== undefined){ - elementSvgText.style['fill'] = data.textColor; - } else if (data.color) { - elementSvgText.style['fill'] = data.color; - } - - } - - this.svgImage = function (data) { - //$(data.container).hide(); - //$(data.container).css({opacity:0}); - - var selector = self.selector(data); //), undefined, true); - var containerElement = self.query(selector); - //var containerElement = self.query(data.container); - - //if (data.value !== undefined) $(data.container).data('value', data.value); - - var iconObj = self.svgSet(data); // {src, set, name, viewbox} - var viewBox = iconObj.viewbox || '-50 -50 100 100'; - var htmlString = ''; - - if (containerElement) { - containerElement.innerHTML = htmlString; - - //$(data.container).append(''); - - var elementSvg = containerElement.querySelectorAll('svg')[0]; - var elementSvgUse = elementSvg.querySelectorAll('use')[0]; - var elementSvgText = elementSvg.querySelectorAll('text')[0]; - var elementSvgCircle = elementSvg.querySelectorAll('circle')[0]; - - elementSvgUse.setAttribute('xlink:href', iconObj.src); - //$(data.container + ' > svg > use').attr('xlink:href', iconObj.src); - - if (data.text !== undefined) { - - elementSvgText.textContent = data.text; - // $(data.container + ' > svg > text').text(data.text); - - var textY = 6.5; // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor - if (data.textSize !== undefined) {textY = data.textSize/2;} - - if (data.textPosition == 'bottom') { // textPosition should be removed - elementSvgUse.setAttribute('transform', 'translate(0, -20) scale(0.80)'); - //$(data.container + ' > svg > use').attr("transform", "translate(0, -20) scale(0.80)"); - textY += 26; - } - - elementSvgText.setAttribute('y', textY); - //$(data.container + ' > svg > text').attr('y',textY); - elementSvgText.style['font-size'] = data.textSize+'px'; - //$(data.container + ' > svg > text').css('font-size',data.textSize+'px'); - } - - - if (data.background !== undefined) { - - elementSvgCircle.setAttribute('fill', data.background); - elementSvgCircle.setAttribute('fill-opacity', 1); - elementSvgCircle.style['stroke'] = data.background; - } - if (data.border !== undefined){ - elementSvgCircle.setAttribute('stroke-opacity', 1); - elementSvgCircle.style['stroke'] = data.border; - - //$(data.container + ' > svg > circle').attr('stroke-opacity', 1); - // FORSE DEVE DIVENTARE attr ANZICHE' css - //$(data.container + ' > svg > circle').css({'stroke': data.border}); - } - - //if ((data.color === undefined) && (data.color !== 'colored')) {data.color = '#fff';} - if (data.color !== undefined && data.color !== 'colored') { - elementSvgUse.style['fill'] = data.color; - //$(data.container + ' > svg > use').css({'fill': data.color}); - //$(data.container + ' > svg > text').css({'fill': data.color}); - } - if (data.textColor !== undefined){ - elementSvgText.style['fill'] = data.textColor; - //$(data.container + ' > svg > text').css({'fill': data.textColor}); - } else { - elementSvgText.style['fill'] = data.color; - //$(data.container + ' > svg > text').css({'fill': data.color}); - } - - - - self.css({style: data.style}, {container: data.container + ' > svg'}); - } - - } - - this.svg = function (params, selectorParams, args) { - var paramsReplaced = self.replaceProperties(params, args); - - //var container = self.selector(self.extend({}, params, selectorParams)); - - var container = self.selector(paramsReplaced, undefined, true) || self.selector(selectorParams, undefined, true); - - var element = self.query(container); - var color = paramsReplaced.color || getComputedStyle(element).color; - //if (element.getElementsByTagName('SVG').length == 0) { - //if (element.querySelectorAll('svg').length == 0) { - - self.svgImage({ - container: container, - - // special param - icon: paramsReplaced.icon, - text: paramsReplaced.text, - textSize: paramsReplaced.textSize, // verify (obsolete when span will be nested) - textPosition: paramsReplaced.textPosition, // verify (obsolete when span will be nested) - textColor: paramsReplaced.textColor, // verify (obsolete when span will be nested) - background: paramsReplaced.background, - border: paramsReplaced.border, - color: paramsReplaced.color || color, // $(container).css("color"), - style: paramsReplaced.style, // da fare css in svgImage - class: paramsReplaced.class - //hoverBackground: data.hoverBackground, // verify - //hoverBorder: data.hoverBorder, // verify - //hoverColor: data.hoverColor, // verify - }); - - } */ - // -------------- - // ITEM - // -------------- - /* - this.checkItem = function (data) { - - var selectedIconClass = data.selection || 'selectedIcon'; // self.json.setup.classes.selectedIcon; - - //self.log('checkItem'); - //self.log(data); - var checked = 0; - // var selector = ''; - var selector = self.selector(data); - - if (data.style === undefined) {data.style = selectedIconClass;} - if (data.checked !== undefined) { - checked = self.replaceProperties(data.checked); - //checked = self.replaceTags({text:data.checked}); - checked = data.checked; - if (data.checked) { - $(selector).addClass(data.style); - } else { - $(selector).removeClass(data.style); - } - } else { - checked = $(selector).hasClass( data.style ); - } - return checked; - } */ - /* - this.toggleItem = function (data) { // modificato 20180709 da changeCheckItem in toggleItem - self.log('toggleItem'); - //self.log(data); - var checked; - checked = self.checkItem({ - id: data.id, - class: data.class, - value: data.value - //style: data.style - }); - checked = !checked; // inverte il valore - self.checkItem({ - id: data.id, - class: data.class, - value: data.value, - checked: checked - //style: data.style, - }); - return checked; - } - */ - /* this.selectItem = function (data) { - - var selectedIconClass = self.json.setup.classes.selectedIcon; - - - var selector = self.selector({container: data.container, class: data.class}); - if (data.style === undefined) {data.style = selectedIconClass;} - $(selector).removeClass(data.style); - - self.log('selector'); - self.log(selector); - - - if (data.value || data.id) { - selector = self.selector(data); - - $(selector).addClass(data.style); - } - - } - - this.unselectItems = function (data) { - var selectedIconClass = self.json.setup.classes.selectedIcon; - //if (data.style) - if (data.style === undefined) {data.style = selectedIconClass;} - if (data.class.indexOf('.') < 0) {data.class = '.' + data.class} - $(data.class).removeClass(data.style); - } - */ - /* this.removeImage = function (data) { - var selector = self.selector(data); - $(selector).css({'background-image':'url()'}); - } - - this.loadImage = function (data) { - var selector = self.selector(data); - //if (!data.style) data.style = {}; - //if (data.background) data.style['background-color'] = data.background; - if (data.image || data.image === '') { - self.getImage({ // ex fixo.loadImage - object: selector, - url: data.image - //style: data.style, - //animation: data.animation, - }); - } else { - self.removeImage(data); - } - } */ - /* this.changeItem = function (data, selectorParams, args) { - self.log('changeItem'); - self.log(data); - var container = (selectorParams) ? self.selector(selectorParams) : data.container; - var selector = self.selector(self.extend({}, data, selectorParams)); - - var iconClass = ''; //self.json.setup.classes.icon || ''; - var badgeClass = 'iconBadge'; //self.json.setup.classes.badge || ''; - - if (data.svg || data.text || data.background || data.border || data.color) { - $(selector + ' > svg').css({opacity:1}); - self.svgChange({ - container: selector, - name: data.svg, - text: data.text, - background: data.background, - border: data.border, - color: data.color, - }); - } else { - $(selector + ' > svg').css({opacity:0}); - } - - // IMMAGINE - if (data.image && data.image !== '') { - var imgData = data; - imgData.style = { - width: '82px', - height: '82px', - 'margin-bottom': '27px' - }; - if (data.background) imgData.style['background-color'] = data.background; - self.loadImage(imgData); - $(selector + ' > svg').css({opacity:0}); - } else { - self.removeImage(data); - $(selector + ' > svg').css({opacity:1}); - } - - if (data.badgeIcon || data.badgeText) { - if (!$('.'+badgeClass).length) - $(selector).append('
    '); - self.svgImage({ - container: selector + ' > .'+badgeClass, - icon: data.badgeIcon, - text: data.badgeText, - background: data.badgeBackground, - border: data.badgeBorder, - color: data.badgeColor, - }); - } else { - $(selector + ' > .'+badgeClass).remove(); - } - - - if (data.titleColor) - $(selector + ' > span').css({'color':data.titleColor}); - else if (data.color) - $(selector + ' > span').css({'color':data.color}); - - if (data.titleSize) $(selector + ' > span').css({'font-size':data.titleSize}); - if (data.title) { - $(selector+' > span').text(data.title); - if ($(selector+' > span').hasClass('textFitted')) { - self.textFit($(selector+' > span'), { - alignHoriz: false, - multiLine: false, - alignVert: false, - minFontSize: 10, - maxFontSize: data.titleSize || 12, - }); - } - } - - if (data.checked !== undefined) { - self.checkItem({ - container: data.container, - class: data.class, - value: data.value, - id: data.id, - checked: data.checked - //style: data.style, - }); - } - - // action (obsolete) - if (data.action) { - var onData = $(selector).data('onData'); - onData.action = data.action; - $(selector).data('onData', onData); // nuova versione - } - // events - if (data.on) self.on(data.on, {container: selector}); - - } */ - /* this.enableIcon = function (params, selectorParams) { - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - $(selector).css({'opacity':'1'}); - $(selector).off().on(self.touch, function(event){ - event.stopPropagation(); - self.onEvent(this, event); - }); - } - - this.disableIcon = function (params, selectorParams) { - var badgeClass = self.json.setup.classes.badge || ''; - - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - $(selector + ' > .'+badgeClass).remove(); - $(selector).css({'opacity':'0.5'}); - $(selector).off(); - } - */ - /* this.getFileExtension = function (path) { - var dotPosition=path.lastIndexOf("."); - var stringLength=path.length; - var extensionFile=path.substring(dotPosition+1,stringLength); - return extensionFile; - } */ - // -------------------- - // SLIDER - // -------------------- - /* var slides = {}; - - var sliderLib = 'fixoSlider'; - var sliderWrapperClass = 'fixoSlider'; - //var sliderSlideClass = 'fixoSlidez'; - var sliderSelectedClass = 'slideSelected'; */ - /* - var sliderLib = 'flickity'; - var sliderWrapperClass = 'fixoSlider'; - var sliderSlideClass = 'fixoSlide'; - var sliderSelectedClass = 'is-selected'; - */ - /* - var sliderLib = 'sliderpro'; - var sliderWrapperClass = 'sp-slides'; - var sliderSlideClass = 'sp-slide'; - var sliderSelectedClass = 'sp-selected'; - */ - /* - var sliderLib = 'swiper'; - var sliderWrapperClass = 'swiper-wrapper'; - var sliderSlideClass = 'swiper-slide'; - var sliderSelectedClass = 'swiper-slide-active'; - */ - /* - this.sliderResume = function (data) { - var selector = self.selector(data); - if (slides[selector]) slides[selector].object.resume(); - } - - this.sliderFreeze = function (data) { - var selector = self.selector(data); - if (slides[selector]) slides[selector].object.freeze(); - } - - this.sliderNext = function(data) { - var selector = self.selector(data); - if (sliderLib == 'fixoSlider') slides[selector].object.next(); - //if (sliderLib == 'flickity') slides[selector].object.flickity('next'); - } - - this.sliderPrev = function(data) { - var selector = self.selector(data); - if (sliderLib == 'fixoSlider') slides[selector].object.prev(); - //if (sliderLib == 'flickity') slides[selector].object.flickity('previous'); - } - - this.autoSliderEvent = function() { - var selector = self.selector(data); - if (self.sliderSelected) - slides[self.sliderSelected].object.autoSliderEvent(); - } - - this.addSlideIcon = function(data) { - // creata per rendere più leggibile createSlide - var selector = self.selector(data); - var isImage = self.getFileExtension(data.icon); - if (isImage == 'gif' || isImage == 'jpg' || isImage == 'jpeg' || isImage == 'png') - fixo.loadImage({ - object: selector + ' > .slideIcon', - url: data.icon, - style: {height: '150px', - width: '150px', - marginTop: '25px', - marginLeft: '-75px', - backgroundSize: 'cover' - } - }); - else - //if (data.icon) - self.svgImage({ - container: selector + ' > .slideIcon', - icon: data.icon, - color: '#fff', - }); - if (data.iconName) - $(selector + ' > .slideIconName').html(data.iconName); // da cancellare? - if (data.iconAction) { - var value = data.iconValue || ''; - $(selector + ' > .slideIcon').attr('onclick', 'javascript:self.do(\''+data.iconAction+'\', \''+value+'\')'); - } - } - - this.changeSlideIcon = function(data) { - var selector = self.selector(data); - // verificare se si può usare changeItem - if (data.icon) - self.svgChange({ - container: selector + ' > .slideIcon', - name: data.icon, - color: '#fff', - }); - if (data.iconName) - $(selector + ' > .slideIconName').html(data.iconName); - } - - this.updateSlide = function(data) { - self.log('updateSlide'); - if (!data.class) data.class = 'fixoSlide'; - var selector = self.selector(data); - // ICONA - self.changeSlideIcon(data); - // BACKGROUND - if (data.background) $(selector).css({'background-color':data.background}); - // TITOLO E TESTO - var alertTitleObj = $(selector).children('.slideTitle'); - var alertTextObj = $(selector).children('.slideText'); - var titleAndText = (alertTitleObj.text() !== '' && alertTextObj.text() !== ''); - if (titleAndText) { - alertTitleObj.css({'margin-top':'-225px'}); - } else { - alertTitleObj.css({'margin-top':'-60px'}); - } - if (data.title !== undefined) { - alertTitleObj.html(data.title); - self.textFit(titleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 40, maxFontSize: 56}); - } - if (data.text !== undefined) { - alertTextObj.html(data.text); - self.textFit(textObj, {alignHoriz: true, multiLine: false, alignVert: !titleAndText, minFontSize: 17, maxFontSize: 40}); - } - // BOTTONE - if (data.button !== undefined) { - if (data.button) { - if (data.buttonLabel) { - $(selector + ' > .slideButton').html(data.buttonLabel); - } - if (data.buttonAction) { - $(selector + ' > .slideButton').data('action', data.buttonAction); - $(selector + ' > .slideButton').data('value', data.value); - $(selector + ' > .slideButton').attr('onclick', 'javascript:self.do(\'' + data.buttonAction + '\',\''+data.value+'\')'); - } - $(selector + ' > .slideButton').show(); - } else { - $(selector + ' > .slideButton').hide(); - } - // aggiungere changeItem dell'icona - } - } - - this.slideTextFit = function() { - //self.log('slideTextFit'); - - //if (!data.class) data.class = 'fixoSlide'; - //var selector = self.selector(data); - var slideSelector = self.sliderSelected + ' > .' + sliderSelectedClass; - - titleObj = $(slideSelector).children('.slideTitle'); - textObj = $(slideSelector).children('.slideText'); - - var titleAndText = (titleObj.text() !== '' && textObj.text() !== ''); - if (titleAndText) { - titleObj.css({'margin-top':'-225px'}); - //textObj.css({'top':(384+125-30)+'px'}); - } else { - titleObj.css({'margin-top':'-60px'}); - } - self.textFit(titleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 40, maxFontSize: 56}); - - self.textFit(textObj, {alignHoriz: true, multiLine: false, alignVert: !titleAndText, minFontSize: 17, maxFontSize: 40}); - - } - - this.sliderTo = function(data) { - // apre la slide data.index - self.log('sliderTo'); - var selector = self.selector(data); - if (data.index !== undefined) // comprende il caso = 0 - if (slides[selector] && slides[selector].object) - slides[selector].object.to(data.index); - - //if (sliderLib == 'swiper') - // slides[selector].object.slideToLoop(data.index); // slideToLoop - //if (sliderLib == 'flickity') - // slides[selector].object.flickity('select', data.index); - //if (sliderLib == 'extraslider') - // $(selector+' > .extra-slider').trigger('extra:slider:goto', data.index); - - if (data.value !== undefined) { // comprende il caso = 0 - self.log(self.selector(data)); - if (!data.class) data.class = 'fixoSlide'; - var slideToSelect = self.selector(data); - var index = $(slideToSelect).index(); - if (index > -1) slides[selector].object.to(index); - //var slideToSelect = '.' + sliderSlideClass + '[data-value="' + data.prefix + data.value + '"]'; - } - - //if (sliderLib == 'flickity') - // slides[selector].object.flickity('selectCell', slideToSelect); - } - - this.sliderExist = function(data) { // si può cancellare? - var selector = self.selector(data); - //alert(($(selector + ' > .extra-slider').length > 0)); - return ($(selector + ' > .extra-slider').length > 0) - // return (slides[selector]) - } - - this.createSlide = function(data) { - self.log('createSlide'); - //if (!data.prefix) data.prefix = ""; - if (!data.class) data.class = "fixoSlide"; - //var containerSelector = self.selector(data); - var slideContent = '
    '; - - if (data.inverse) { - $(data.container).prepend(slideContent); - } else { - $(data.container).append(slideContent); - } - var selector = self.selector(data); - var infoButtons = data.infoButtons || {}; - - // STORE DATA - $(selector).data('container', data.container); - if (data.value) $(selector).data('value', data.value); - //if (data.id) $(selector).data('id', data.id); - //if (data.prefix) $(selector).data('prefix', data.prefix); - - var textHtml = (data.text) ? data.text.replace(/\r?\n/g, '
    ') : ''; - - // PRICE - //if(data.price && data.price !== '') textHtml += '
    € '+data.price; - - // BACKGROUND - if (data.background) $(selector).css({'background-color':data.background}); - - // IMAGE - if (data.image && data.image !== '') { - if (data.title !== '' || textHtml !== '' ) - { - //$(selector).css({'background-image':'linear-gradient(to right,rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('+data.image+')'}); - //} else { - //$(selector).css({'background-image':'url('+data.image+')'}); - $(selector).append('
    ') - } - - if (sliderLib == 'fixoSlider') { - $(selector).css({'background-image':'url('+data.image+')'}); - // DA GESTIRE INTERNAMENTE A fixo.slider.js - // DOVRA' CARICARE SOLO SLIDE ATTUALE, PREC. E SUCC - - //fixo.loadImage({ - // object: selector, - // url: data.image, - // animation: 'fadeIn', - //}); - - } - - //if (sliderLib == 'swiper') { - // $(selector).addClass('swiper-lazy'); - // $(selector).attr('data-background', data.image); - //} - //if (sliderLib == 'flickity') { - // $(selector).attr('data-flickity-bg-lazyload', data.image); - //} - - } else { - - $(selector).css({'background-image':'none'}); - // SERVICE ICON - //$(selector).append('
    '); - //self.addSlideIcon(data); - - // if (data.icon) - // self.svgImage({ - // container: selector + ' > .slideIcon', - // icon: data.icon, - // color: '#fff', - // }); - // if (data.iconName) - // $(selector + ' > .slideIconName').html(data.iconName); - - // if (data.icon) - // self.svgImage({ - // container: selector + ' > .slideIcon', - // icon: data.icon, - // color: '#fff', - // }); - // if (data.iconName) - // $(selector + ' > .slideIconName').html(data.iconName); - } - - // ICONA - $(selector).append('
    '); - self.addSlideIcon(data); - - // TITLE & TEXT - $(selector).append('
    '); - - var alertTitleObj = $(selector + ' > .slideTitle'); - var alertTextObj = $(selector + ' > .slideText'); - var alertInfoObj = $(selector + ' > .slideInfo'); - - // BOTTONI INFO - - var btnInfo = ''; - for (var i in infoButtons) { - if (infoButtons[i].icon !== '') - btnInfo += self.imgTag({ - icon: infoButtons[i].icon, - action: infoButtons[i].action, - class: infoButtons[i].class, - value: infoButtons[i].value, - //style: 'width: 84px; margin:6px 10px;' - }); - //alertInfoObj.html(btnInfo); - } - alertInfoObj.html(btnInfo); - - // TESTO - - if (data.title && data.title !== '') { - alertTitleObj.html(data.title); - } else { - alertTitleObj.html(data.iconName); - } - alertTextObj.html(textHtml); - - //alertInfoObj.html() - - - // if (data.link && data.link !== '') { // serviva a costruire il div con il qrcode, sostituito dal link per aprire lo swal alert - // var link = data.link; - - // self.log('DATALINK: '+link); - - // if (link.indexOf('musement.com') || link.indexOf('booking.com')) { - // link = link.replace(/^https?:\/\//,''); //rimuovo https dal link - // self.log('link: '+link); - // link = 'https://c83.travelpayouts.com/click?shmarker=219111&promo_id=2015&source_type=customlink&type=click&custom_url=' + link; - // } - - // self.log('DATALINK1: '+link); - - // $(selector).append('
    '); - // self.qrCode({ - // container: selector, - // class: 'slideQrCode', - // text: link, - // size: 100 - // }); - // // attributo sul Codice QR per la visualizzazione dell'alert - // $('.slideQrCode > img').attr('onclick','javascript:self.do(\'app.hot.alertQRCode\')'); - // } else { - - - $(selector).append(''); - if (data.button) { - if (data.buttonLabel) { - $(selector + ' > .slideButton').html(data.buttonLabel); - } - if (data.buttonAction) { - $(selector + ' > .slideButton').data('action', data.buttonAction); - $(selector + ' > .slideButton').data('value', data.value); - $(selector + ' > .slideButton').attr('onclick', 'javascript:self.do(\'' + data.buttonAction + '\',\''+data.value+'\')'); - } - $(selector + ' > .slideButton').show(); - - // $(selector + ' > .slideButton').off().on(self.touch, function(){ - // var action = $(this).data('action'); - // var key = $(this).data('value'); - // self.do(action, value); - // }); - - } else { - $(selector + ' > .slideButton').hide(); - } - //} chiude l'IF del data.link - var titleAndText = (alertTitleObj.text() !== '' && alertTextObj.text() !== ''); - - // POSIZIONE TITOLO - var titleTop = -70 -170 * (titleAndText); - alertTitleObj.css({'margin-top': titleTop + 'px'}); - self.textFit(alertTitleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 30, maxFontSize: 56}); - - // ALTEZZA TESTO - var textHeight = 340 - 100 * (infoButtons.length > 0); - alertTextObj.css({'height': textHeight + 'px'}); - - - //self.textFit(alertTitleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 30, maxFontSize: 56}); - - //self.textFit(alertTextObj, {alignHoriz: true, multiLine: false, alignVert: !titleAndText, minFontSize: 15, maxFontSize: 45}); - //self.log('END createSLIDE'); - - - } - - this.createSlider = function (data) { - self.log('createSlider'); - //if (!data.prefix) data.prefix = ""; - var selector = self.selector(data); - var startIndex = data.index || 0; - //self.log('pre DATAINDEX: '+data.index); - - // RIMUOVE ISTANZA PRECEDENTE - - if (slides[selector] && slides[selector].object) { - // Memorizza posizione - var slideSelector = selector + ' > .' + sliderSelectedClass; - //self.log('slideSelector di self.createSlider: '+slideSelector); - startIndex = data.index || $(slideSelector).index(); - // Rimuove slider precedente - //self.log('startIndex: di '+data.index+' .index() '+$(slideSelector).index()); - $(selector).empty(); - delete slides[selector].object; - } - - slides[selector] = {}; - - - // FRECCE - // if (data.buttons) { - // if (sliderLib == 'swiper') { - // $(selector).append('
    '); - // $(selector).append('
    '); - // } - // } - - for (var key in data.slides) { - var slide = data.slides[key]; - slide.inverse = data.inverse; - //slide.container = selector; //+' > .' + sliderWrapperClass; - slide = self.extend({ - container: selector, - class: 'fixoSlide', //sliderSlideClass, - value: data.value, //data.prefix + data.value - }, slide); - self.createSlide(slide); - - } - - // CREAZIONE OGGETTO SLIDER - - if (sliderLib == 'fixoSlider') { - - var params = { - container: selector, //+' > .' + sliderWrapperClass, - play: data.play, - interval: data.interval, // ms - onChange: data.onChange, - onChangeStart: self.slideTextFit, - index: startIndex // prima slide - // direction: 1, // from right to left - // opts.swipeDuration: 0.6, // sec - // opts.swipeTreshold: 0.2, // Swipe from +/-20% - }; - - slides[selector].object = $.fn.slide(params); - } - //self.log('END createSlider'); - } -*/ - /* - this.getSelectedSlide = function (data) { - self.log('getSelectedSlide'); - //self.log(data); - var selector = self.selector(data); - if (sliderLib == 'fixoSlider') { - var slideSelector = selector + ' > .' + sliderSelectedClass; - - self.log($(slideSelector).data('value')); - return $(slideSelector).data('value'); - } - - } - - var sliderSelect = function (currentItem, currentIndex) { //si può cancellare? - var id = $(currentItem).parent().parent().parent().attr('id'); - self.log('slideId:'+id); - self.log('currentItem:'+currentItem); - self.log('currentIndex:'+currentIndex); - slides[id].currentItem = currentItem; - slides[id].currentIndex = currentIndex; - } - - var sliderPause = function (currentItem, currentIndex) { // si può cancellare? - $(currentItem).parent().parent().trigger('extra:slider:pause'); - var id = $(currentItem).parent().parent().parent().attr('id'); - self.log('slideId:'+id); - self.log('currentItem:'+currentItem); - self.log('currentIndex:'+currentIndex); - slides[id].currentItem = currentItem; - slides[id].currentIndex = currentIndex; - } - - var sliderPlay = function (currentItem, currentIndex) { // si può cancellare? - $(currentItem).parent().parent().trigger('extra:slider:pause'); - $(currentItem).parent().parent().trigger('extra:slider:resume'); - var id = $(currentItem).parent().parent().parent().attr('id'); - self.log('slideId:'+id); - self.log('currentItem:'+currentItem); - self.log('currentIndex:'+currentIndex); - slides[id].currentItem = currentItem; - slides[id].currentIndex = currentIndex; - } - - var sliderResume = function (currentItem, currentIndex) { //si può cancellare? - var id = $(currentItem).parent().parent().parent().attr('id'); - if (slides[id].active) { - sliderPlay(currentItem, currentIndex); - } else { - sliderPause(currentItem, currentIndex); - } - } - - var sliderClick = function (currentItem, currentIndex) { // si può cancellare ? - var id = $(currentItem).parent().parent().parent().attr('id'); - if (slides[id].active) { - slides[id].active = false; - } else { - slides[id].active = true; - } - } */ - /* this.addItem = function (data, selectorParams) { // obsolete - - var container = (selectorParams) ? self.selector(selectorParams) : data.container; - var selector = self.selector(self.extend({}, data, selectorParams)); - - // app default - // aggiungere anche dimensione di default - - var iconClass = self.json.setup.classes.icon || ''; - var badgeClass = self.json.setup.classes.badge || ''; - - var style = (data.style) ? data.style : {}; - - // retro-compatibility - if (data.size) { - if (data.size == 'small') - style.width = '50px'; - else if (data.size == 'medium') - style.width = '80px'; - else if (data.size == 'big') - style.width = '120px'; - else if (data.size) - style.width = data.size; - } - - style = self.extend({}, style, { // retrocompatibilità / obsoleto - color: data.color, - background: data.background, - border: data.border, - display: data.display, - margin: data.margin, - padding: data.padding, - width: data.width, - height: data.height - }); - - - // Create - if (data.id === undefined) {data.id = '';} - if (data.value === undefined) {data.value = data.id}; - if (data.class === undefined) {data.class = iconClass} else if (data.class !== iconClass) {data.class += ' ' + iconClass}; - - var itemDiv = '
    '; - - if (data.prepend) { - $(data.container).prepend(itemDiv); - } else { - $(data.container).append(itemDiv); - } - - self.css({style: { - width: style.width, - display: style.display, - padding: style.padding, - margin: style.margin - }}, {container: selector}); - - // SVG - - if (data.svg || data.text) { - self.svgImage({ - container: selector, - icon: data.svg, - text: data.text, - textSize: data.textSize, // verify (obsolete when span will be nested) - textPosition: data.textPosition, // verify (obsolete when span will be nested) - textColor: data.textColor, // verify (obsolete when span will be nested) - background: style.background, - border: style.border, - color: style.color - //hoverBackground: data.hoverBackground, // verify - //hoverBorder: data.hoverBorder, // verify - //hoverColor: data.hoverColor, // verify - }); - } else { - - } - - // image - - if (data.image) { - var imgData = data; - imgData.style = { - width:'82px', - height:'82px', - 'margin-bottom':'27px' - }; - if (style.background) imgData.style['background-color'] = style.background; - self.loadImage(imgData); - } - - // badge - - if (data.badgeIcon || data.badgeText) { - $(selector).append('
    '); - self.svgImage({ - container: selector + ' > .'+badgeClass, - icon: data.badgeIcon, - text: data.badgeText, - background: data.badgeBackground, - border: data.badgeBorder, - color: data.badgeColor, - }); - } - - - if (data.title) { - //data.title = self.text(data.title); - data.titleColor = data.titleColor || style.color; - if (data.titleColor == undefined) {data.titleColor = ''} - if (data.titleSize == undefined) {data.titleSize = ''} - //if (data.titleSizeMin == undefined) {data.titleSize = '7px'} - - $(selector).append(''); - $(selector + ' > span').css({ - color: data.titleColor, - 'font-size': data.titleSize - }); - //if (typeof data.title == 'object') alert(data.title.text); - self.text(data.title, {container: selector + ' > span'}); - //var title = self.text(data.title); - //$(selector + ' > span').text(title); - - //self.text(data.title); - - // itemSelectedBorderWhite GESTITO IN INDEX.CSS - - // questo stile dovrebbe essere fisso e con posizione assoluta - if (data.image) - $(selector + ' > span').css({ - 'margin-top':'89px', - position: 'absolute' - }); - - - if (data.textFit !== false) { - self.textFit($(selector+' > span'), { - alignHoriz: false, - multiLine: false, - alignVert: false, - minFontSize: 10, - maxFontSize: data.titleSize, - }); - } - } - - // action (obsolete) - if (data.action || data.functions) { - var.functions[selector] = data.functions || data.action; // obsoleto - $(selector).data('onData', data); // nuova versione - $(selector).off().on(self.touch, function(event){ - event.stopPropagation(); - self.onEvent(this, event); - }); - } - - // matchMedia - if (data.matchMedia) { - for (var mediaEvent in data.matchMedia) { - self.matchMedia(data.matchMedia[mediaEvent], mediaEvent); - } - } - - // events - if (data.on) self.on(data.on, {container: selector}); - - if (data.checked !== undefined) { - self.checkItem({ - container: data.container, - class: data.class, - value: data.value, - id: data.id, - checked: data.checked - //style: data.style, - }); - } - } */ - // -------------- - // TABS - // -------------- - /* this.addTab = function (data, selectorParams) { - //self.log('addTab'); - //self.log(data); - - var containerParams = self.cloneObject(selectorParams); - - data.container = containerParams.container; - var selector = self.selector(data); - - var tabClass = ''; //self.json.setup.classes.button || ''; - var badgeClass = 'iconBadge'; //self.json.setup.classes.badge || ''; - - var style = (data.style) ? data.style : {}; - - // span height - //style["line-height"] = (style.height) ? style.height : '42px'; - - style = self.extend({}, style, { - color: data.color, - background: data.background, - border: data.border, - display: data.display, - margin: data.margin, - padding: data.padding, - width: data.width, - height: data.height - }); - - if (data.id === undefined) {data.id = '';} - if (data.value === undefined) {data.value = data.id}; - if (data.class === undefined) {data.class = tabClass} else if (data.class !== tabClass) {data.class += ' ' + tabClass}; - - var tabDiv = '
    '; - - $(data.container).append(tabDiv); - - self.css({style: style}, {container: selector}); - - //if (data.key) {$(selector).data('key', data.key);} - - //var iconColor = style.color || $(selector).css("color"); - - // ICON - if (data.icon) { - self.addItem({ - class: 'icon', - value: data.value, - svg: data.icon, - image: data.image, - style: { - color: style.color || $(selector).css("color"), - width: style.height - } - }, {container: selector}); - } - - // TEXT - if (data.text !== undefined) { - //alert(JSON.stringify(data.text)); - - $(selector).append(''); - - self.text(data.text, {container: selector + ' > span'}); - - - } else { - //alert(JSON.stringify(data.text)); - } - - if (data.icon) $(selector + ' > span').css({'padding-left': '0px'}); - - // SPAN - if(style.color) $(selector + ' > span').css({'color':style.color}); - - // BADGE - if (data.badgeIcon || data.badgeText) { - if (!$('.'+badgeClass).length) - $(selector).append('
    '); - self.svgImage({ - container: selector + ' > .'+badgeClass, - icon: data.badgeIcon, - text: data.badgeText, - background: data.badgeBackground, - border: data.badgeBorder, - color: data.badgeColor, - }); - } else { - $(selector + ' > .'+badgeClass).remove(); - } - - // data - if (data.action || data.functions){ - var.functions[selector] = data.functions || data.action; // obsoleto - $(selector).data('onData', data); // nuova versione - $(selector).off().on(self.touch, function(event){ - event.stopPropagation(); - self.onEvent(this, event); - //$(this).data('value') - //var selector = $(this).data('selector'); - //var action = var.functions[selector]; - //self.do($(this).data('onData').action, $(this).data('value')); - }); - } - - // matchMedia - if (data.matchMedia) { - for (var mediaEvent in data.matchMedia) { - self.matchMedia(data.matchMedia[mediaEvent], mediaEvent); - } - } - - // events - if (data.on) self.on(data.on, {container: selector}); - - if (data.selected) self.selectTab(data); - - } */ - /* this.changeTab = function (data, selectorParams) { - - var container = (selectorParams) ? self.selector(selectorParams) : data.container; - var selector = self.selector(self.extend({}, data, selectorParams)); - - if (data.icon && data.value) { - self.changeItem({ - container: selector, - class: 'icon', - value: data.value, - svg: data.icon, - color: data.color, - background: data.background - }); - } - - if(data.background) $(selector).css({'background':data.background}); - if(data.color) $(selector + ' > span').css({'color':data.color}); - - if (data.text) { - //$(selector + ' > span').text(self.text(data.text)); - self.text(data.text, {container: selector + ' > span'}); - } - - if (data.action){ - $(selector).off().on(self.touch, function(){ - data.action(data.value) - }); - } - // events - if (data.on) self.on(data.on, {container: selector}); - - if (data.selected) self.selectTab(data); - } */ - /* this.unselectTabs = function (data) { - - var selectionClass = data.selection || 'selectedButton'; - //var selectionClass = self.json.setup.classes.selectedButton; - if (data.style) selectionClass = data.style; - $(data.class).removeClass(selectionClass); - } - - this.toggleTab = function (data) { - data.toggle = true; - return self.selectTab(data); - } - - this.selectTab = function (data) { - var selectionClass = data.selection || 'selectedButton'; - //var selectionClass = self.json.setup.classes.selectedButton; - if (data.style) selectionClass = data.style; - var selector = self.selector(data); - - if (data.deselectClass) - if (data.class) $('.'+data.class).removeClass(selectionClass); - - if (data.checked !== undefined) { - if (data.checked == false) $(selector).removeClass(selectionClass); - else $(selector).addClass(selectionClass); - } else if (data.toggle !== undefined) { - // da toggleTab - if ($(selector).hasClass(selectionClass)) { - $(selector).removeClass(selectionClass); - return false; - } else { - //if (data.class) $('.'+data.class).removeClass(selectionClass); - $(selector).addClass(selectionClass); - return true; - } - } else { - //if (data.class) $('.'+data.class).removeClass(selectionClass); - $(selector).addClass(selectionClass); - } - } */ - // --------------------------- - // FUNZIONI DATEPICKER - // --------------------------- - /* - // basato su: http://www.daterangepicker.com/#options - - this.createDatePicker = function (data) { - self.log('createDatePicker'); - var calendarVisible = false; - if (!data.field) data.field = data.container + ' > .daterange'; - - if (!$(data.field).length) { - calendarVisible = true; // Crea e nasconde campo testo e mostra calendario - $(data.container).html(''); - } - - var weekD = self.weekdaysShort(1, capitalize); - weekD = weekD.unshift(weekD[6]); - var monthsOfYear = ["January","February","March","April","May","June","July","August","September","October","November","December"]; - if (data.language) { - monthsOfYear = moment.localeData(data.language).months(); - for (var index in monthsOfYear) { - monthsOfYear[index] = - monthsOfYear[index].substr(0,1).toUpperCase() - + monthsOfYear[index].substr(1); - } - } - //var datarange = $('#daterange'); - - $(data.field).daterangepicker({ - singleDatePicker: data.single, - parentEl: data.container, - startDate: data.start, - endDate: data.end, - autoApply: true, - autoUpdateInput: false, - locale: { - format: 'DD/MM/YYYY', - daysOfWeek: weekD, - monthNames: monthsOfYear, - firstDay: 1 // monday - } - }); - - - $(data.field).on('cancel.daterangepicker', function(ev, picker) { - data.onCancel(); - }); - - $(data.field).on('apply.daterangepicker', function(ev, picker) { - data.onChange({ - start: picker.startDate.format('YYYYMMDD'), - end: picker.endDate.format('YYYYMMDD') - }); - if (picker.startDate && picker.endDate && picker.startDate !== picker.endDate) { - $(data.field).val(picker.startDate.format('DD/MM/YYYY') + '-' + picker.endDate.format('DD/MM/YYYY')); - } else { - $(data.field).val(picker.startDate.format('DD/MM/YYYY')); - } - }); - - self.unselectDatePicker({container: data.container}); - - - } - - var disableDates = []; - this.updateDatePicker = function(data) { - var datePicker = $(data.container + ' > .daterange').data('daterangepicker'); - if (data.disableDates) {disableDates = data.disableDates;} - // alert(datePicker+'-'+data.container); - datePicker.isInvalidDate = function(date) { - return (disableDates.indexOf(date.format('YYYYMMDD')) >= 0) - } - datePicker.updateView(); - if (data.start && data.end) { - self.setDatePicker({ - container: data.container, - start: data.start, - end: data.end, - }); - } else { - self.unselectDatePicker({container: data.container}); - } - } - - this.unselectDatePicker = function(data) { - $(data.container).find('.start-date').removeClass('start-date active'); - $(data.container).find('.end-date').removeClass('end-date active'); - $(data.container).find('.in-range').removeClass('in-range'); - - } - - this.setDatePicker = function (data) { - var datePicker = $(data.container + ' > .daterange').data('daterangepicker'); - datePicker.setStartDate(data.start); - datePicker.setEndDate(data.end); - datePicker.updateView(); - } - - this.getDatePicker = function (data) { - var start = $(data.container + ' > .daterange').data('daterangepicker').startDate(data.start); - var end = $(data.container + ' > .daterange').data('daterangepicker').endDate(data.end); - //alert('ok: '+data.container); - return {start: start, end: end} - } - - // --------------------------- - // FUNZIONI TIMEPICKER - // --------------------------- - - this.createTimePicker = function (data) { - $(data.container).html('
    '); - - $(data.container + ' > .datetimepicker').datetimepicker({ - icons: { - up: "fixoNavUp", - down: "fixoNavDown", - previous: "fixoNavBackward", - next: "fixoNavForward" - }, - inline: true, - sideBySide: true, - //locale: 'it' - locale: { - format: 'DD/MM/YYYY', - daysOfWeek: weekD, - monthNames: monthsOfYear, - firstDay: 1 // monday - } - }); - - //self.log('now: '+Date.now()+' moment: '+moment()); - - self.setTimePicker({ - container: data.container, - time: data.time - }); - - - $(data.container + ' > .datetimepicker').off().on('dp.change', function(event) { - var datePicked = moment(event.date).unix(); - //alert(datePicked); - data.onChange(datePicked); - }); - - } - - this.setTimePicker = function (data) { - //self.log('>>> setTimePicker --> data container: '+data.container+' data time: '+data.time+' moment: '+moment.unix(data.time).calendar()); - $(data.container + ' > .datetimepicker').data('DateTimePicker').date(moment.unix(data.time));//.format('LLL')); - } - - this.getTimePicker = function (data) { - //alert('ok: '+data.container); - $(data.container + ' > .datetimepicker').data('DateTimePicker').date(); - } - */ - // --------------------------- - // TIME SLIDER - // --------------------------- - /* - this.createTimeSlider = function(data){ - var container = data.container; - var id = data.id; - - // c'è un'anomalia nella libreria bootstrap-slider - // crea il contenitore dello slider con lo stesso id del campo input - // va verificata la possibilità di configurazione della funzione .slider - - $('#'+data.container).append(''); - $('#'+id).slider(); - $('#'+id).off().on("slide slideStop", function(event) { - - self.log(event); - self.changeItem({ - id:'stepbackwardSlider'+id, - text: self.numberToHour({value: event.value[0], max: 48}) - }); - self.changeItem({ - id:'stepforwardSlider'+id, - text: self.numberToHour({value: event.value[1], max: 48}) - }); - - if (data.onChange) { - data.onChange({ - start: self.numberToHour({value: event.value[0], max: 48}), - end: self.numberToHour({value: event.value[1], max: 48}) - }) - } - - }); - - // ICONS Slider - self.addItem({ - container:'#'+id+' > .min-slider-handle', - class: 'sliderIconLeft', - id: 'stepbackwardSlider'+id, - background: '#fff', - color: 'black', - border: 1, - text: '00:00' - }); - self.addItem({ - container:'#'+id+' > .max-slider-handle', - class: 'sliderIconRight', - id: 'stepforwardSlider'+id, - background: '#fff', - color: 'black', - border: 1, - text: '24:00' - }); - //$('#'+sliderId+' .slider-selection').css({'background': '#fff'}); - - } - - this.setTimeSlider = function(data){ - //Change value on slider left/right icon - self.changeItem({ - id:'stepbackwardSlider'+data.id, - text: data.start - }); - self.changeItem({ - id:'stepforwardSlider'+data.id, - text: data.end - }); - //Convert value in 0-48 format - var start = self.hourToNumber({value: data.start, max: 48}); - var end = self.hourToNumber({value: data.end, max: 48}); - // Set value on slider - $('input[id="'+data.id+'"]').slider('setValue',[start,end]); - - } - - this.getTimeSlider = function(data){ - var slideStart = $('input[id="'+data.id+'"]').slider('getValue')[0] || 0; - var slideEnd = $('input[id="'+data.id+'"]').slider('getValue')[1] || 48; - var start = self.numberToHour({value: slideStart, max: 48}); - var end = self.numberToHour({value: slideEnd, max: 48}); - if (start == '24:00') {start = '00:00'} - var timetable = { - start: start || '00:00', - end: end || '24:00' - } - return timetable; - } - */ - this.numberToHour = function (data) { - var fraction = data.value / data.max; - var dayMin = Math.round(24 * 60 * fraction); - var hour = parseInt(dayMin / 60); - var min = dayMin - hour * 60; - var hourString = String(hour < 10 ? '0' : '') + String(hour); - var minString = String(min < 10 ? '0' : '') + String(min); - return hourString + ':' + minString; - }; - - this.hourToNumber = function (data) { - var timeArr = data.value.split(':'); - var dayMin = (60 * Number(timeArr[0])) + Number(timeArr[1]); - var fraction = dayMin / (24 * 60); - return Math.round(fraction * data.max); - }; - - this.pannellum = function (params, selectorParams, args) { - self.log('pannellum'); - var container = params.selector || params.container; - var selector = self.selector(container) || self.selector(selectorParams); - var element = self.query(selector); - pannellum.viewer(element, params); - }; - - this.qrcode = function (params, selectorParams, args) { - self.log('qrcode'); - var container = params.selector || params.container; - var selector = self.selector(container) || self.selector(selectorParams); - var element = self.query(selector); - // var obj = self.compile(data); - self.log(selector); - self.log('element'); - self.log(element); - - var QRCodeOptions = { - text: self.replaceProperties(params.text, args) || 'jsonic.io', - width: params.size || 128, - height: params.size || 128, - useSVG: true, - colorDark: params.colorDark || '#000000', - colorLight: params.colorLight || '#ffffff', - correctLevel: QRCode.CorrectLevel.H - }; - self.log('QRCodeOptions'); - self.log(QRCodeOptions); - - element.textContent = ''; - var qrcode = new QRCode(element, QRCodeOptions); - self.log('qrcode'); - self.log(qrcode); - return qrcode; - //qrcode.clear(); // clear the code. - //qrcode.makeCode(text); // make another code - }; - - /* this.qrcode = function (data) { - self.log('qrcode'); - var selector = self.selector(data); - - var options = { - // render method: 'canvas', 'image' or 'div' - render: 'image', - - // version range somewhere in 1 .. 40 - minVersion: 1, - maxVersion: 40, - - // error correction level: 'L', 'M', 'Q' or 'H' - ecLevel: 'L', - - // offset in pixel if drawn onto existing canvas - left: 0, - top: 0, - - // size in pixel - size: data.size || 200, - - // code color or image element - fill: data.color || '#000', - - // background color or image element, null for transparent background - background: data.background || null, - - // content - text: self.replaceProperties(data.text) || 'no text', - - // corner radius relative to module width: 0.0 .. 0.5 - radius: 0, - - // quiet zone in modules - quiet: 0, - - // modes - // 0: normal - // 1: label strip - // 2: label box - // 3: image strip - // 4: image box - mode: 0, - - mSize: 0.1, - mPosX: 0.5, - mPosY: 0.5, - - label: data.label || 'no label', - fontname: data.fontname || 'sans', - fontcolor: data.fontcolor || '#000', - - image: null - } - $(selector).empty().qrcode(options); - } */ - this.weekdaysShort = function (length, caseFunction) { - if (!caseFunction) caseFunction = caseUp; - var language = 'en'; - var fixoLang = fixo.getFixoLanguage(); - var userLang = fixo.getUserLanguage(); - if (fixo.device) language = fixoLang; else language = userLang; - var weekDays = self.cloneObject(moment.localeData(language).weekdays()); - - weekDays[7] = weekDays[0]; - weekDays.shift(); - - for (var i = 0; i < 7; i++) { - if (length) weekDays[i] = weekDays[i].substr(0, length); - if (caseFunction) weekDays[i] = caseFunction(weekDays[i]); - } - return weekDays; - }; - - - this.weekDaysToString = function (days) { - var text = ''; - for (var i in days) { - if (days[i]) { - if (text !== '') text += '/'; - text += self.weekdaysShort(3, capitalize)[i]; - } - } - return text; - }; - - // ----------- - // DRAG - // ----------- - /* - var draggingData; - - this.sortable = function (data) { - var rootEl = $(data.container)[ 0 ]; - var dragEl; - - draggingData = data; - var selector = self.selector(data); - $(selector).attr('draggable', 'true'); - $(data.exclude).attr('draggable', 'false'); - - // Function responsible for sorting - function onDragOver(event) { - event.preventDefault(); - event.dataTransfer.dropEffect = 'move'; - - var dragTarget = event.target; // target.nextSibling || - if ($(dragTarget).hasClass(draggingData.class)) - $( dragEl ).insertAfter( $(dragTarget) ); - if ($(dragTarget).parent().hasClass(draggingData.class)) - $( dragEl ).insertAfter( $(dragTarget).parent() ); - } - - // End of sorting - function onDragEnd(event){ - event.preventDefault(); - - $(dragEl).css({'opacity':'100%'}); - rootEl.removeEventListener('dragover', onDragOver, false); - rootEl.removeEventListener('dragend', onDragEnd, false); - - // Notification about the end of sorting - draggingData.target = dragEl; - draggingData.onDragEnd(draggingData); - } - - // Sorting starts - rootEl.addEventListener('dragstart', function (event){ - dragEl = event.target; // Remembering an element that will be moved - - $(dragEl).css({'opacity':'50%'}); - - // Limiting the movement type - event.dataTransfer.effectAllowed = 'move'; - event.dataTransfer.setData('Text', dragEl.textContent); - - - // Subscribing to the events at dnd - rootEl.addEventListener('dragover', onDragOver, false); - rootEl.addEventListener('dragend', onDragEnd, false); - - - setTimeout(function () { - // If this action is performed without setTimeout, then - // the moved object will be of this class. - $(dragEl).css({'opacity':'100%'}); - }, 0) - }, false); - } - - */ - /* - this.setWeekDays = function(data){ - - if (!data.days) data.days = {}; - - for (var i=1; i<7; i++){ - self.selectTab({ - container: data.container, - class: 'fixoTabsWeekDays', - value: String(i), - checked: data.days[String(i)] || false - }); - } - } - - this.createWeekDays = function(data){ - //var selector = self.selector(data); - var weekDays = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]; - self.log('data.language '+data.language); - if (data.language) weekDays=moment.localeData(data.language).weekdaysShort(); - for (var i=0; i<7; i++){ - var weekDay = weekDays[i]; - self.addTab({ - container: data.container, - class: data.class, - value: String(i), - id: data.container + i, - background: 'black', - color: 'white', - border: '1px solid rgba(0, 0, 0, 1)', - text: weekDay, - action: function(value){ - //alert($(this).attr(id)); - // il toggleTab deselezionava sempre gli altri giorni - // risolto usando il selectTab col parametro checked - // va sistemato toggleTab - if (!data.days) data.days = {}; - var checked = !Boolean(data.days[value]); - self.selectTab({ - container: data.container, - class: 'fixoTabsWeekDays', - value: value, - checked: checked - }); - data.days[value] = checked; - } - }); - } - } - */ - //-------------------------- - // DA FIXO.JS - //-------------------------- - /*--------------------- - UTILS - ---------------------*/ - var sortField; - - var dynamicSort = function (data) { - var sortOrder = 1; - if (data.reverse) { sortOrder = -1; } - sortField = data.field; - return function (a, b) { - var result = (a[sortField] < b[sortField]) ? -1 : (a[sortField] > b[sortField]) ? 1 : 0; - return result * sortOrder; - }; - }; - - this.sort = function (data) { - // fixo.sort({object:{}, add: {}, field:'time', reverse:true}) - if (data.object !== undefined) { - if (Array.isArray(data.object)) { - return data.object.sort(dynamicSort({ - field: data.field, - reverse: data.reverse - })); - } else { - var arr = self.objectToArray({ - object: data.object, - add: data.add, - }); - return arr.sort(dynamicSort({ - field: data.field, - reverse: data.reverse - })); - } - } else { - self.log('sort of undefined'); - return []; - } - }; - - this.objectToArray = function (data) { - // data: {object:{}, add: {}} - var arr = []; - var obj = data.object; - if (obj !== undefined) { - for (var key in obj) { - obj[key].id = key; // aggiunge la chiave dell'oggetto come proprietà - if (data.add) obj[key] = Object.assign(obj[key], data.add); - arr.push(obj[key]); - } - } - return arr; - }; - - - - /* - this.itemsFound = function(items, field, value) { - return $.grep(items, function(e){ return e.name == value; }); - } - - */ - /* this.itemFound = function(items, field, value) { - var itemFound = false; - for (var i=0; i 0); - } else { - return ($(data.class).length > 0); - } - } */ - this.equal = function (obj1, obj2) { - if (obj1 && obj2) { - return (JSON.stringify(obj1).replace('"', '') == JSON.stringify(obj2).replace('"', '')); - } else { - return (obj1 == obj2); - } - }; - - /* this.arraysEquals = function(arr1,arr2) { - return ($(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0); - } */ - var escapeRegExp = function (str) { - return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); - }; - this.replaceAll = function (str, find, replace) { - - if (str !== undefined) { - let result; - if (typeof str == 'string') result = str; else result = JSON.stringify(str); - - if (str) { - if (find) { // && replace - //if (typeof str !== 'string') self.log(str); - result = String(str).replace(new RegExp(escapeRegExp(find), 'g'), replace); - //if (typeof str == 'string') return result; else return JSON.parse(result); - if (typeof str == 'object' && result) return JSON.parse(result); - else - return result; - } else { - /* self.log('str:'+str); - self.log('find:'+find); - self.log('replace:'+replace); */ - return str; - } - } - } else { - return str; - } - }; - - this.capitalize = function (str) { - return str.replace(/\b\w/g, l => l.toUpperCase()); - }; - - - /*--------------------- - URL UTILS ----------------------*/ - this.getPageName = function (url) { - var index = url.lastIndexOf("/") + 1; - var filenameWithExtension = url.substr(index); - var filename = filenameWithExtension.split(".")[0]; // <-- added this line - return filename; // <-- added this line - }; - - this.goToMainUrl = function () { - window.location = self.mainUrl; - }; - - this.getParameterByName = function (name, url) { - if (!url) url = window.location.href; - name = name.replace(/[\[\]]/g, "\\$&"); - var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url); - if (!results) return null; - if (!results[2]) return ''; - return decodeURIComponent(results[2].replace(/\+/g, " ")); - }; - - var paramsToObject = function (params) { - params = params.split('#')[0]; - return JSON.parse('{"' + params.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}'); - }; - - var objectToParams = function (object) { - var str = ''; - for (var key in object) str += '&' + key + '=' + object[key]; - if (str) str = str.substr(1); - return encodeURI(str); - }; - - this.getParams = function () { - var params = {}; - var url = window.location.href.split('#')[0]; - if (url.indexOf('?') > -1) { - var urlParams = decodeURI(url.split('?')[1]); - self.log(urlParams); - if (urlParams) { - var k = self.getParameterByName('k', url); - //self.log(k); - if (k) { - params = self.atob(k); - } else { - params = paramsToObject(urlParams); - } - } - } - return params; - }; - - this.atob = function (k) { - self.log('atob'); - var params = paramsToObject(atob(k)); // base64 -> query -> object - - // decompress params - if (params.h) // hotel - params.h = String(parseInt(String(params.h), 36)); // base36 - if (params.c) // customer - params.c = String(parseInt(String(params.c), 36)); // base36 - if (params.n) { // phone - params.n = String(parseInt(String(params.n), 36)); // base36 - params.n = '+' + params.n; - } - //if (params.s) params.s = var.services.id[params.s]; - self.log(params); - return params; - }; - - this.btoa = function (params) { - self.log('btoa'); - //if (params.s) params.s = var.services.id.indexOf(params.s); - if (params.h) // hotel - params.h = Number(params.h).toString(36); // base36 - if (params.c) // customer - params.c = Number(params.c).toString(36); // base36 - - if (params.n) { // phone - if (params.n.startsWith('+')) params.n = params.n.substr(1); - params.n = params.n.replace(/ /g, ''); - params.n = params.n.replace(/-/g, ''); - params.n = Number(params.n).toString(36); // base36 - } - self.log(params); - return btoa(objectToParams(params)); // query -> base64 - }; - - /* - var encodeNum = function(num) { // 0..1296 es:customer - var hex = c.toString(36); - return c.toString(36); - } - - var decodeNum = function(str) { - return str.parseInt(36); // .length == 1 ? "0" + hex : hex - } - */ - this.colorToRgba = function (hex, opacity) { - if (hex == 'white') { hex = '#fff'; } - if (hex == 'black') { hex = '#000'; } - var c; - if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) { - c = hex.substring(1).split(''); - if (c.length == 3) { - c = [c[0], c[0], c[1], c[1], c[2], c[2]]; - } - c = '0x' + c.join(''); - return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ',' + opacity + ')'; - } else { - self.log('Bad Hex:' + hex); - } - }; - var hueToRGB = function (m1, m2, h) { - h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); - if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; - if (h * 2 < 1) return m2; - if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; - return m1; - }; - - var HSLToRGB = function (hsl) { - var m1, m2, r, g, b; - var h = hsl[0], s = hsl[1], l = hsl[2]; - m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s; - m1 = l * 2 - m2; - return [hueToRGB(m1, m2, h + 0.33333), - hueToRGB(m1, m2, h), - hueToRGB(m1, m2, h - 0.33333)]; - }; - - var packRGB = function (rgb) { - var r = Math.round(rgb[0] * 255); - var g = Math.round(rgb[1] * 255); - var b = Math.round(rgb[2] * 255); - // '#' + - return (r < 16 ? '0' : '') + r.toString(16) + - (g < 16 ? '0' : '') + g.toString(16) + - (b < 16 ? '0' : '') + b.toString(16); - }; - - this.degToRGB = function (deg) { - return packRGB(HSLToRGB([deg / 360, 1, 0.5])); - }; - - this.stripHtml = function (html) { - var tmp = document.createElement("DIV"); - tmp.innerHTML = html; - return tmp.textContent || tmp.innerText || ""; - }; - - //-------------------------- - // TASK MANAGER - //-------------------------- - this.log = function (value, color) { - if (self.json.setup && self.json.setup.log) { // log enabled - if (typeof value === 'string') - console.log('%c' + value, 'color:' + color); - - else - console.log(value); - } - }; - - var varlog = function (str) { - self.log(str); - self.log(window[str]); // 'var' -> var - }; - - this.logJson = function (jsonPar) { self.log(JSON.stringify(jsonPar)); }; - - this.getTimestamp = function () { - // we need also an API to get the time - // like .getTime()? - return Math.floor(Date.now()); - }; - - this.cloneObject = function (obj) { - var newObj = JSON.stringify(obj); - return self.parse(newObj); - }; - - - /*------------------------ - TEXT - ------------------------*/ - /* var caseUp = function (string) { - if (!string) string = ''; - return string.toUpperCase(); - } - - var caseDown = function (string) { - if (!string) string = ''; - return string.toLowerCase(); - } - - var capitalize = function(string) { - if (!string) string = ''; - return self.capitalize(string); - } - - var text = function (key, caseFunction) { - var t = self.json.text[key] || ''; - if (caseFunction) return caseFunction(t); else return t; - } */ - this.setElement = function (elementString, elementValue) { - var context = window; - var namespaces = elementString.split("."); - var func = namespaces.pop(); - - if (namespaces[0] == 'frame') { - namespaces.shift(); - var frameName = namespaces.shift(); - if (frameName && document.getElementById(frameName) !== null) - context = document.getElementById(frameName).contentWindow; - } else if (namespaces[0] == 'admin') { // fixo - namespaces.shift(); - context = fixoAdmin; - } - - - for (var i = 0; i < namespaces.length; i++) { - if (context[namespaces[i]]) { // var - context = context[namespaces[i]]; - } else { - if (elementValue) // scrittura - context[namespaces[i]] = {}; // crea contesto inesistente - } - } - - context[func] = elementValue; - }; - - this.context = function (path) { - const re = /^(setup|var|data|texts|parts)[\.\s]/; // reserved namespaces - if (re.test(path)) { - /* self.log('MATCHED setup|var|data|parts'); - console.log(params); */ - return self.json; - } else { - return window; - } - }; - - this.element = function (params) { - // {root, path, value} - // in respect to docElement, it includes replaceProperties for path and value - // but only if value is a string. TO DO: check it - let context; - let path = self.replaceProperties(params.path, params.args); - let value = (params.value && typeof params.value == 'string') ? self.replaceProperties(params.value, params.args) : params.value; - - // NOTE: log error if the params.root is equal to the first element of the path? (window.window works) - if (!params.root) { - context = self.context(path); - } else { - context = params.root; - } - - return self.docElement(path, value, context, params.delete); - - //self.log(value); - /* if (value && typeof value == 'string') { - if (value.startsWith('js:')) value = self.js(value.substr(3)); - else if (value.startsWith('+=')) value = self.element({path: path}) + self.js(value.substr(2)); - else if (value.startsWith('-=')) value = self.element({path: path}) - self.js(value.substr(2)); - else if (value.startsWith('/=')) value = self.element({path: path}) / self.js(value.substr(2)); - else if (value.startsWith('*=')) value = self.element({path: path}) / self.js(value.substr(2)) - } */ - // self.log(value); - /* if (value.startsWith('number:')) value = Number(self.js(value.substr(6))); - alert('dopo number:'+value); - if (value.startsWith('boolean:')) value = Boolean(self.js(value.substr(7))); - if (value.startsWith('string:')) value = String(self.js(value.substr(6))); - if (value.startsWith('+:')) value = self.element({path: path}) + self.js(value.substr(2)); - if (value.startsWith('-:')) value = self.element({path: path}) - self.js(value.substr(2)); - if (value.startsWith('/:')) value = self.element({path: path}) / self.js(value.substr(2)); - if (value.startsWith('*:')) value = self.element({path: path}) / self.js(value.substr(2)); */ - /* // verificare... - if (value.startsWith('push:')) {var obj = self.docElement(path, undefined, root); return obj.push(value.substr(3));} - if (value.startsWith('unshift:')) {var obj = self.docElement(path, undefined, root); return obj.unshift(value.substr(3));} - if (value.startsWith('pop:')) {var obj = self.docElement(path, undefined, root); return obj.pop(value.substr(3));} - if (value.startsWith('shift:')) {var obj = self.docElement(path, undefined, root); return obj.shift(value.substr(3));} */ - }; - - this.docElement = function (elementString, elementValue, context, elementDelete) { - - if (!context) context = window; // TO DO: remove - var namespaces = elementString.split(/[.\s]+/); // path nodes separed by dot or spaces - - - - - - - - - - - /* console.log('<-------'); - console.log('context'); - console.log(context); - console.log('path'); - console.log(elementString); - console.log('value'); - console.log(elementValue); - console.log('------>'); -*/ - var lastElement = namespaces.pop(); - - /* if (namespaces[0] == 'self') { - namespaces.shift(); - context = self; - } else if (namespaces[0] == 'frame') { - namespaces.shift(); - var frameName = namespaces.shift(); - if (frameName && document.getElementById(frameName) !== null) - context = document.getElementById(frameName).contentWindow; - } */ - /* console.log('namespaces'); - console.log(namespaces); */ - for (var i = 0; i < namespaces.length; i++) { - if (context[namespaces[i]]) { // var - context = context[namespaces[i]]; - } else { - if (elementValue !== undefined && elementValue !== null) { // wants to assign a value - context[namespaces[i]] = {}; // it create the context context[namespaces[i]] if it doesn't exist - context = context[namespaces[i]]; - /* self.log('crea context inesistente'); - self.log('namespaces[i]: '+namespaces[i]); */ - /* self.log('elementValue'); - self.log(elementValue); - self.log('context[namespaces[i]]'); - self.log(context[namespaces[i]]); */ - } else { - /* self.log(elementString + ' undefined'); - self.log('lastElement:' + lastElement); - self.log(elementValue); */ - } - //break; // perché? rendeva impossibile creare un listener su un nodo secondario (solo su app e non su app/dev) - } - } - - if (elementValue !== undefined) { // write - - //self.log(lastElement+'='+elementValue); - if (typeof elementValue == 'string') elementValue = self.js(elementValue); // 1.0.3 - context[lastElement] = elementValue; - - // elementValue can be a js function - /* self.log('context'); - self.log(context); - self.log('context[lastElement]'); - self.log(context[lastElement]); - self.log('====='); */ - } - - if (elementDelete) delete context[lastElement]; - - /* self.log('context'); - self.log(context); */ - /* console.log('namespaces'); - console.log(namespaces); - self.log('lastElement'); - self.log(lastElement); - self.log('context[lastElement]'); - self.log(context[lastElement]); */ - if (context[lastElement] && context[lastElement].isConnected) - return self.elementToSelector(context[lastElement]); - - else - return context[lastElement]; - }; - - /* this.openCloseDropdown = function(key) { - self.log('openCloseDropdown'); - self.log("key"); - self.log(key); - //$('.dropdown-menu').css('display','none'); - var selector = self.selector({ - "id": "dropdown" +key, - "class": 'points', - "value": key, - }); - self.log("selector"); - self.log(selector); - if ($(selector + ' > .dropdown-menu').css('display') == 'none') { - $(selector + ' > .dropdown-menu').css('display', 'block'); - } else { - $(selector + ' > .dropdown-menu').css('display', 'none'); - } - } */ - this.timeToMs = function (string) { - // bug - var timeArray = string.match(/(\d+)(\w+)/); // es: 1s / 100ms - if (timeArray) { - var value = Number(timeArray[0]); - var unit = timeArray[1]; - var unitInMs = { - ms: 1, - s: 1000, - m: 1000 * 60, - h: 1000 * 60 * 60, - d: 1000 * 60 * 60 * 24, - milliseconds: 1, - seconds: 1000, - minutes: 1000 * 60, - hours: 1000 * 60 * 60, - days: 1000 * 60 * 60 * 24 - }; - if (value) - if (unitInMs[unit]) - return value * unitInMs[unit]; - - else - self.log('wrong unit in the time string [value][unit]: ' + string); - - else - self.log('wrong value in the time string [value][unit]: ' + string); - } - else - return Number(string); - }; - - this.intervals = {}; - - this.timer = function (params, args) { - // can go in "browser.json / functions (JS Browser BOM) - // https://www.w3schools.com/js/js_window.asp - let name = self.replaceProperties(params.name); - if (!name) - name = self.getTimestamp() + Math.random(1000); - - if (params.play !== undefined && params.play == 0) { - if (self.intervals[name]) { - self.clearInterval({ - name: name - }, args); - } - if (self.timeouts[name]) { - self.clearTimeout({ - name: name - }, args); - } - } - else if (params.every !== undefined) { - let every = self.replaceProperties(params.every); - if (every) { - self.setInterval({ - name: name, - duration: every, - do: params.do - }, args); - } - } - else if (params.after !== undefined) { - let after = self.replaceProperties(params.after); - if (after) { - self.setTimeout({ - name: name, - duration: after, - do: params.do - }, args); - } else { - self.do(params.do, null, args); - } - } - }; - - this.setInterval = function (params, args) { - // could include the param "fromNow": true to execute the function - /* self.log('setInterval'); - self.log(params); */ - if (params.name && params.duration) { - if (self.intervals[params.name]) - clearInterval(self.intervals[params.name]); - - //self.do(params.do); - self.do(params.do); - self.intervals[params.name] = setInterval(function () { - //self.do(params.do); - self.do(params.do); - return params.name; - }, Number(params.duration)); // self.timeToMs - } - else - self.log('"setInterval" function requires "name" and "duration" parameters'); - }; - - this.clearInterval = function (params, args) { - /* self.log('params'); - self.log(params); - self.log('self.intervals[params.name]'); - self.log(self.intervals[params.name]); */ - if (self.intervals[params.name]) { - clearInterval(self.intervals[params.name]); - delete self.intervals[params.name]; - } - // else - // self.log('"clearInterval" name not found: ' + params.name); - }; - - this.timeouts = {}; - - this.setTimeout = function (params, args) { - // could include the param "fromNow": true to execute the function - /* self.log('setTimeout'); - self.log(params); */ - if (params.name && params.duration) { - if (self.timeouts[params.name]) - clearInterval(self.timeouts[params.name]); - - //self.do(params.do); - //self.do(params.do); - self.timeouts[params.name] = setTimeout(function () { - //self.do(params.do); - self.do(params.do); - return params.name; - }, Number(params.duration)); // self.timeToMs - } - else - self.log('"setTimeout" function requires "name" and "duration" parameters'); - }; - - this.clearTimeout = function (params, args) { - /* self.log('params'); - self.log(params); - self.log('self.timeouts[params.name]'); - self.log(self.timeouts[params.name]); */ - if (self.timeouts[params.name]) { - clearTimeout(self.timeouts[params.name]); - delete self.timeouts[params.name]; - } - //else - // self.log('"clearInterval" name not found: ' + params.name); - }; - - - - - this.on = function (params, selectorParams) { - //let selector = params.selector || params.container; - - var container = (selectorParams) ? self.selector(selectorParams) : params.selector; // 1.0.9 instead of params.container - - - - - - - - - - - /* self.log('on'); - self.log(params); - self.log('container'); - self.log(container); */ - //var selector = self.selector(self.extend({}, params, selectorParams)); - //$(container).data('onData', {events: params, container: container}); - var element; - - if (container) { - element = self.query(container); // shoud be foreach elements... - if (element) - self.dataStorage.set(element, "onData", { on: params, selector: container }); - else { - self.log('can\'t find the element "' + container + '" ("on" function)'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } /* else { - self.log('"on" function with selector undefined'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } */ - - - - - - - - for (var eventId in params) { - //var eventAction = params[eventId]; - //$(selector).data('onData').action = eventAction; - /* if (eventId == 'thunkable') { - self.thunkable(params[eventId]); - } else */ - if (eventId == 'init') { - //self.log(params.init); - //self.do(params.init, undefined, selectorParams); - self.do(params.init, selectorParams); - } else if (eventId == 'hashchange') { - self.onHashChange.push(params.hashchange); - window.addEventListener('hashchange', function () { - self.json.setup.page.hash = window.location.hash.substr(1); // potrebbe essere esplicitato sulla app - - - - //var action = self.cloneObject(params.app.on.hashchange); - //self.replaceAll("{result}", window.location.hash); - //self.do(self.onHashChange); - self.do(self.onHashChange); - self.uiUpdate(); - }); - } else if (eventId == 'scroll') { - self.onScroll.push(params.scroll); - window.addEventListener('scroll', function () { - //self.do(self.onScroll); - self.do(self.onScroll); - }); - } else if (eventId == 'resize') { - self.onResize.push(params.resize); - window.addEventListener('resize', function () { - //self.do(self.onResize); - self.do(self.onResize); - }); - } else if (eventId == 'in') { // like inViewport but only one time - if (container) { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - /* self.log('entry'); - self.log(entry); - self.log('entry.target'); - self.log(entry.target); */ - /* self.log(entry); - self.log(entry.intersectionRatio); - self.log(entry.isIntersecting); - self.log(entry.isVisible); */ - // isIntersecting, isVisible - //var element = self.query(entry.target); - //self.log(entry.intersectionRatio); - if (entry.intersectionRatio == 1) { // .isIntersecting? - var el = entry.target; - if (el.getAttribute('in') !== 'true') { - el.setAttribute('in', 'true'); // change with dataStorage - self.onEvent(entry.target, { type: 'in' }); - } - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] // if 0.5 is the half-height of the elmement - }); - //const element = self.query(container); - observer.observe(self.query(container)); - } - } else if (eventId == 'inViewport') { - if (container) { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - /* self.log('entry'); - self.log(entry); - self.log('entry.target'); - self.log(entry.target); */ - /* - self.log(entry.intersectionRatio); - self.log(entry.isIntersecting); - self.log(entry.isVisible); */ - // isIntersecting, isVisible - //var element = self.query(entry.target); - //self.log(entry.intersectionRatio); - if (entry.intersectionRatio > 0) { - self.onEvent(entry.target, { type: 'inViewport' }); - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] // if 0.5 is the half-height of the elmement - }); - //const element = self.query(container); - observer.observe(self.query(container)); - } - } else if (eventId == 'outViewport') { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - /* self.log(entry); - self.log(entry.isIntersecting); - self.log(entry.isVisible); */ - // isIntersecting, isVisible - //var element = self.query(entry.target); - //self.log(entry.intersectionRatio); - if (entry.intersectionRatio == 0) { - self.onEvent(entry.target, { type: 'outViewport' }); - /* var el = entry.target; - if (el.getAttribute('in') == 'true') { - el.setAttribute('in', 'false'); - self.onEvent(entry.target, {type: 'out'}); - } */ - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] // if 0.5 is the half-height of the elmement - }); - const element = self.query(container); - observer.observe(element); - - - } else if (eventId !== 'selector') { - - /* if (container == '.nav-link[data-value="docs"]') { - alert(JSON.stringify(params)); - //element = element[0]; - $(element).hide(); - } */ - //element.removeEventListener(eventId); - // $(container).off(eventId); - if (element) { - - // TO DO: verify - //if (element.getAttribute('listener') !== 'true') { // only one mouse event - //self.log('addEventListener: ' + eventId); - element.addEventListener(eventId, function (event) { - //$(container).off(eventId).on(eventId, function (event) { - /* self.log('event'); - self.log(event); */ - element.setAttribute('listener', 'true'); - //event.preventDefault(); - //event.stopPropagation(); - self.onEvent(this, event); - }); - //} - if (eventId == 'mousedown' || eventId == 'mouseup' || eventId == 'click') - element.style.cursor = 'pointer'; - } - - /* $(container).off(eventId).on(eventId, function (event) { - //$(container).off(eventId).on(eventId, function (event) { - self.log('event'); - self.log(event); - event.preventDefault(); - event.stopPropagation(); - self.onEvent(this, event); - }); */ - //$(container).css({cursor: 'pointer'}); - } - } - - }; - - /* this.addAction = function (params, selectorParams) { - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - $(selector).data('onData', params); - //$(selector).data('onData', {action: params.action, params: params.args}); - $(selector).off().on(this.touch, function (event) { - event.stopPropagation(); - self.onEvent(this, event); - }); - $(selector).css({cursor: 'pointer'}); - } */ - /* this.ace = function (params) { - params.container = 'blockCode'; - var editor = ace.edit("blockCode"); - var langTools = ace.require('ace/ext/language_tools'); - editor.setTheme("ace/theme/monokai"); // ambiance - editor.getSession().setMode("ace/mode/json"); - //editor.renderer.setOption('showLineNumbers', false); - editor.container.style.background="rgba(255,255,255,0)"; - - var staticWordCompleter = { - getCompletions: function(editor, session, pos, prefix, callback) { - var wordList = ["app", "setup", "pages"]; - callback(null, wordList.map(function(word) { - return { - caption: word, - value: word, - meta: "static" - }; - })); - - } - } - editor.completers = [staticWordCompleter]; - - // https://github.com/ajaxorg/ace/wiki/Configuring-Ace - editor.setOptions({ - fontSize: "11pt", - selectionStyle: "text", - highlightActiveLine: true, - wrap: true, - showLineNumbers: false, - showGutter: false, - fixedWidthGutter: false, - readOnly: true, - //enableBasicAutocompletion: true, - //enableSnippets: true, - //enableLiveAutocompletion: true, - }); - editor.setValue(var.code, -1); - } */ - /* this.edit = function (item) { - //var.code = JSON.stringify(item, null, '\t'); - - self.do( { - "alert": { - "background": "rgba(255,255,255,0.9)", - "width": "93%", - "showCancelButton": true, - "cancelButtonText": 'Cancel', - "confirmButtonText": 'Save', - "html": '
    ' - } - }); - //self.code(JSON.stringify(item, null, '\t'),); - self.code(item, {container: '#blockCode'}); - - //setTimeout(function () { - - //alert(var.blockCode); - // https://codepen.io/jjsjjja/pen/VoGYRB - //}, 100); - } */ - this.money = function (value) { - /* if (value && value.indexOf(',') == -1 && value.indexOf('.') == -1) { - value = value + '.00'; - } */ - var rounded = Math.round(Number(value) * 100) / 100; - var string = String(rounded); - if (rounded == Math.floor(rounded)) - string += ',00'; - string = String(string).replace('.', ','); - return string; - }; - - - this.offcanvas = function (params) { - self.log('offcanvas'); - self.log('params'); - self.log(params); - // https://getbootstrap.com/docs/5.0/components/offcanvas/ - // to add: toggle, getInstance, getOrCreateInstance - var container = params.selector || params.container; - var selector = self.selector(container); - var element = self.query(selector); - self.log('offcanvas'); - self.log(params); - self.log('selector'); - self.log(selector); - self.log('element'); - self.log(element); - // do: show (default) / hide (see boostrap Offcanvas docs) - if (element) { - if (params.do == 'hide') { - self.css({ - removeClass: 'show' - }, params); - //new bootstrap.Offcanvas(element).hide(); // doesn't work - } else { - new bootstrap.Offcanvas(element).show(); - } - } else { - self.log('"offcanvas" method can\'t find the selected element'); - } - }; - - /** - * Converts a DOM element to its CSS selector string representation - * @param {HTMLElement} element - The DOM element to convert - * @returns {string} The CSS selector string that uniquely identifies the element - */ - this.elementToSelector = function (element) { - // 1. Use ID if available - if (element.id) { - return '#' + element.id; - } - - // 2. Use data-value if unique - if (element.dataset?.value) { - const sameDataValue = document.querySelectorAll(`[data-value="${element.dataset.value}"]`); - if (sameDataValue.length === 1) { - return `[data-value="${element.dataset.value}"]`; - } - } - - // 3. Use class if unique - if (element.classList && element.classList.length > 0) { - for (const className of element.classList) { - if (className) { - const sameClass = document.querySelectorAll('.' + className); - if (sameClass.length === 1) { - return '.' + className; - } - } - } - } - - // 4. Use tag if unique - const tagName = element.tagName.toLowerCase(); - const sameTag = document.querySelectorAll(tagName); - if (sameTag.length === 1) { - return tagName; - } - - // 5. Fallback to tag + nth-child path - let path = []; - while (element.parentNode) { - let selector = element.tagName.toLowerCase(); - const index = Array.from(element.parentNode.children).indexOf(element) + 1; - selector += `:nth-child(${index})`; - - path.unshift(selector); - element = element.parentNode; - } - return path.join(' > '); - }; - - - this.onEvent = function (element, event) { - //self.log('element'); - //self.log(element); - /* self.log('event'); - self.log(event); */ - /* if (event) { - event.preventDefault(); // verify - event.stopPropagation(); - } */ - /* var item = {}; - if (self.dataStorage.has(element, 'onData')) - item = self.dataStorage.get(element, 'onData'); */ - var item = self.dataStorage.get(element, 'onData'); - var code = self.dataStorage.get(element, 'code') || ''; - //var item = $(element).data('onData'); - //var code = $(element).data('code'); - //var value = String($(element).data('value')); - //var selector = $(element).data('selector'); - //var value = String(self.dataStorage.get(element, 'value')); - var value = element.getAttribute('data-value'); - //var selector = element.getAttribute('data-selector'); - var selector = self.elementToSelector(element); // 1.0.12 - - - - - - - - - /* self.log('value'); - self.log(value); - self.log('args'); - self.log(args); */ - var eventType = (event.type && item.on) ? item.on[event.type] : undefined; - - /* self.log('onEvent'); - self.log('item'); - self.log(item); - self.log('selector'); - self.log(selector); - self.log('event.type'); - self.log(event.type); */ - /* - if (event) { - args = { - value: value, - event: eventType - } - } - */ - /* self.log('event.type'); - self.log(event.type); - self.log('event'); - self.log(event); */ - var action, specialKey; - - if (item.on) { - - if (event.button == '2' && event.type == 'mousedown') { // right click / long touch - - if (item.on['contextmenu']) - action = item.on['contextmenu']; - - } else if (event.type && item.on[event.type]) { - - var eventAction = item.on[event.type]; - - //const specialKeys = ['shiftKey', 'altKey', 'cmdKey']; - if (eventAction) { - if (eventAction.shiftKey && event.shiftKey) { - specialKey = 'shiftKey'; - action = eventAction.shiftKey; - } else if (eventAction.altKey && event.altKey) { - specialKey = 'altKey'; - action = eventAction.altKey; - } else if (eventAction.cmdKey && event.cmdKey) { - specialKey = 'cmdKey'; - action = eventAction.cmdKey; - } else if (!eventAction.shiftKey && !eventAction.altKey && !eventAction.cmdKey) { - action = item.on[event.type]; - } - } - } - } - - if (action) { - //console.dir(action); - //action = self.replaceProperty(action, '{on:target}', targetId); - if (event.target) { - //self.log(event); - var actionString; - var targetId = event.target.id; - var targetClass = event.target.className; - var targetValue = event.target.dataset.value; - var targetSelector = event.target.dataset.selector; // deprecated - - - - /* self.log('event'); - self.log(event); */ - //if (targetValue) alert(targetValue); - targetSelector = self.replaceAll(targetSelector, '"', '\''); // TO DO: if JSON5? - action = self.stringify(action); - if (typeof targetId !== 'string') targetId = ''; - if (typeof targetClass !== 'string') targetClass = ''; - - /* actionString = self.replaceAll(action, '{event.target.id}', targetId); - actionString = self.replaceAll(actionString, '{event.altKey}', event.altKey); - actionString = self.replaceAll(actionString, '{event.target.className}', targetClass); - actionString = self.replaceAll(actionString, '{event.target.data-value}', targetValue); // obsolete - actionString = self.replaceAll(actionString, '{event.target.dataset.value}', targetValue); - actionString = self.replaceAll(actionString, '{event.target.dataset.selector}', targetSelector); */ - actionString = self.replaceAll(action, '{on:target.id}', targetId); - actionString = self.replaceAll(actionString, '{on:altKey}', event.altKey); - actionString = self.replaceAll(actionString, '{on:target.className}', targetClass); - actionString = self.replaceAll(actionString, '{on:target.data-value}', targetValue); // obsolete - actionString = self.replaceAll(actionString, '{on:target.dataset.value}', targetValue); - actionString = self.replaceAll(actionString, '{on:target.dataset.selector}', targetSelector); // deprecated - actionString = self.replaceAll(actionString, '{on:which}', event.which); - actionString = self.replaceAll(actionString, '{on:clientY}', event.clientY); - actionString = self.replaceAll(actionString, '{on:clientX}', event.clientX); - - // custom - actionString = self.replaceAll(actionString, '{on:value}', targetValue); - actionString = self.replaceAll(actionString, '{on:dragging}', (event.which > 0)); - //actionString = self.replaceProperty(actionString, 'on', event); - if (this.isJson(actionString)) - action = self.parse(actionString); - - else - action = actionString; - } - - // TODO: let decide to the user the parameter to pass - var args = item.args; // || item.params || item.value || value; - - - - - //args.event = event; - //if (args) - // action = self.replaceResult(action, args); - let specialKeyLog = (specialKey) ? ' + ' + specialKey : ''; - //self.log('event ' + event.type + specialKeyLog); - //self.log('action'); - //self.log(action); - /* self.log('args'); - self.log(args); - self.log('{container: selector}'); - self.log({container: selector}); */ - //self.do(action, args, {selector: selector}); // TO DO: only if mouse over or - self.do(action, { selector: selector }, args); - } // (action) - - }; - - this.pluginsFunctionAvailable = []; // should use pluginsLoaded - - self.pluginsLoader = function (packs, callback, params) { - /* self.log('pluginsLoader'); - self.log('packs'); - self.log(packs); - self.log('callback'); - self.log(callback); - self.log('params'); - self.log(params); */ - //self.pluginsFunctionAvailable.push(name); // posizione giusta - var filesToLoad = []; - - for (pack of packs) { - /* self.log('pack'); - self.log(pack); */ - if (self.pluginsLoaded[pack.name] == undefined) { - - self.log('require plugin ' + pack.name, 'grey'); - var plugin = self.findPlugin(pack.name); - let version; - var pluginsFiles; - if (plugin) { - pluginsFiles = plugin.files || plugin; - version = plugin.version; - } else { - pluginsFiles = self.json.resources.pluginsFiles[pack.name]; // TO DO: obsolete, remove - version = pack.version; - } - - /* if (params) { - if (!Array.isArray(params[0])) params[0] = [params[0]]; - if (!self.pluginsCallbacks[pack.name]) self.pluginsCallbacks[pack.name] = []; - self.pluginsCallbacks[pack.name].concat(params[0]); - } */ - self.pluginsLoaded[pack.name] = version; // should contain the queue of actions to do after the plugin loads - - - - - // TO DO: move in Promise.all(promises).then(function() { - // it needs to feed a queue of actions to do after the plugin loads - if (!Array.isArray(pluginsFiles)) // multi-file plugin - pluginsFiles = [pluginsFiles]; - - /* self.log('pluginsFiles'); - self.log(pluginsFiles); */ - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({ name: item.name, url: url, type: item.type }); - } - } - - } - - //self.log(filesToLoad); - if (filesToLoad.length > 0) { - - let promises = []; - - filesToLoad.forEach(function (item) { - promises.push(loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content })); - //promises.push(loadPlugin(url)); - }); - - Promise.all(promises).then(function (files) { - // all filesToLoad are loaded (all the Promise in loadPlugin are solved) - /* self.log('all plugin files are loaded'); - self.log(files); - self.log(params); */ - callback(...params); // change with ... - - - //callback(params[0], params[1], params[2]); // change with ... - }).catch(function (script) { - self.log('failed to load error'); - self.log(item); - self.log(script); - }); - } - }; - - - this.pluginsRequired = function (params) { - /* self.log('pluginsRequired'); - self.log(params); */ - // analize function object or array of objects - if (self.json.resources) { - const pluginsFunctions = self.json.resources.pluginsFunctions; - var pluginsRequired = []; - if (typeof params == 'string') { - /* self.log('params'); - self.log(params); */ - if (pluginsFunctions[params]) { - if (!self.pluginsLoaded[pluginsFunctions[params].name]) - pluginsRequired.push(pluginsFunctions[params]); - } - } else if (typeof params == 'object') { - var objArray; - if (Array.isArray(params)) objArray = params; else objArray = [params]; - /* self.log('objArray'); - self.log(objArray); */ - for (var obj of objArray) { - /* self.log('obj'); - self.log(obj); */ - for (var key in obj) { - var mainFunction = (key.indexOf('.') >= 0) ? key.substr(0, key.indexOf('.')) : key; - //self.log('mainFunction'); - //self.log(mainFunction); - if (pluginsFunctions[mainFunction]) { - if (!self.pluginsLoaded[pluginsFunctions[mainFunction].name]) - pluginsRequired.push(pluginsFunctions[mainFunction]); - } /* else if (key == 'var') { - const functionName = self.functionName(obj.var.value); - if (functionName) { - if (!self.pluginsLoaded[pluginsFunctions[functionName].name]) - pluginsRequired.push(pluginsFunctions[functionName]); - } - } */ - - - - - - - } - } - } - return pluginsRequired; - } else { - return []; - } - }; - - this.functionName = function (obj) { - if (obj == 'object') { - const name = Object.keys(obj)[0]; - const pluginFunctions = ['database', 'ace', 'moment', 'dayjs']; - if (pluginFunctions.indexOf(name) >= 0) - return name; - } - }; - - /* - this.runParts = function (actionObj, container, argumentsPar, handleOtherActions) { - console.log('runParts'); - console.log(actionObj); - if (Array.isArray(actionObj)) { - for (var action in actionObj) - self.runParts(action); - } else { - var otherMethods = false; - var otherActions = {}; - for (var partKey in actionObj) { - - if (partKey.startsWith('var ') || partKey.startsWith('data ') || partKey.startsWith('set ')) - self.setData({path: partKey, value: actionObj[partKey]}); - else { - var methodOrPart = false; - var method = self.element({path: partKey, root: self.methods}); - if (method) { // search in jsonic.methods - methodOrPart = true; - if (typeof method == 'function') { - //self.docElement(actionObj[partKey]); - self.log('method: ' + partKey); - method(actionObj[partKey], container, argumentsPar); - } - } else if (self.json.parts) { // search in self.json.parts - var part = self.element({path: 'parts.'+self.replaceAll(partKey,':','.')}); - if (part) { - part = self.replaceProperty(part, 'arg', actionObj[partKey]); - if (actionObj[partKey].setup) - part = self.replaceProperty(part, 'setup', actionObj[partKey].setup); - console.log('part'); - console.log(part); - self.run(part, container); - methodOrPart = true; // if (!actionFound) { will go in the else (!part) - } - } - if (!methodOrPart) otherActions[partKey] = actionObj[partKey]; - else otherMethods = true; - } - } - - //if (handleOtherActions) handleOtherActions(otherActions, container, argumentsPar); - return otherMethods; - } - } - */ - /* this.jsonicMethods = function (actions, container, argumentsPar) { - - // 'icons' should be removed from the json files - - var withContainer; - var functionFound = false; - - for (var actionKey in actions) { - - //if (nodes.functions.indexOf(actionKey) >= 0) { - - switch (actionKey) { - - case 'for': - case 'editor': - case 'ace': - case 'code': - case 'qrcode': - case 'lottie': - case 'animate': - case 'html': - case 'hide': - case 'show': - case 'toggle': - case 'in': - case 'out': - case 'if': - case 'ajax': - case 'attr': - case 'run': - case 'delay': - case 'css': withContainer = true; break; - default: withContainer = false; - } - var functionObj = actions[actionKey]; - if (functionObj) { - functionFound = true; - if ((functionObj.if == undefined) || self.if(functionObj.if, container, argumentsPar)) { - return self.doFunction({ - name: nodes.functions[actionKey], - function: functionObj, - args: argumentsPar, - selector: container, - withContainer: withContainer - }); - } else { - if (functionObj.if !== undefined) { - self.log(self.js(functionObj.if, argumentsPar)); - } - } - } else if (nodes.params.indexOf(actionKey) < 0) - return self.method(actions[actionKey], argumentsPar); - - } - - - } */ - /* this.do = function (actionPar, argumentsPar, selectorParams) { // ex this.action - - if (actionPar !== undefined && actionPar !== null) { // !== undefined - - // check plugins required - let pluginsRequired = self.pluginsRequired(actionPar); - if (pluginsRequired.length > 0) { - let params = [actionPar, argumentsPar, selectorParams]; - self.pluginsLoader(pluginsRequired, self.do, params); - - } else { - - if (Array.isArray(actionPar)) { - - if (actionPar.length > 0) { - var actionArray = []; - for (var index in actionPar) - if (typeof actionPar[index] == 'object') - actionArray[index] = self.cloneObject(actionPar[index]); - else - actionArray[index] = actionPar[index]; - //actionArray = actionArray.concat(actionPar); - //actionArray = self.cloneObject(actionPar); - var actionFunction = actionArray.shift(); - self.do(actionFunction, argumentsPar, selectorParams); - if (actionArray.length > 0) - self.do(actionArray, argumentsPar, selectorParams); - } - } else { - - if (typeof actionPar == 'function') { - - return actionPar(argumentsPar); - - } else if (typeof actionPar == 'string') { - - var actionPart = self.element({path: 'parts.' + actionPar}); // it includes replaceProperties - self.log('actionPar stringa'); - self.log(actionPar); - if (actionPart) - return self.do(actionPart, argumentsPar); - //else if (json.actions[actionPar]) // obsolete - // return self.do(json.actions[actionPar], argumentsPar); - else - return actionPar; //return self.js(actionPar); // TO DO: finisce qui anche una stringa di un tag p ("p": "string") - - - } else if (typeof actionPar == "object") { - - var actionObj = actionPar; - var container = actionObj.selector || actionObj.container || selectorParams; - - // events - if (actionObj.on) {self.on(actionObj.on, container);} - - - if (self.notEmptyObject(actionObj)) { - - - var actionFound = self.runParts(actionObj, container, argumentsPar, self.jsonicMethods); - - - if (!actionFound) { - - var functionFound = false; - - for (var index in nodes.functions) { - //if (nodes.params.indexOf(actionKey) < 0) - - //var action = Object.keys(actionObj)[0]; - var withContainer = (nodes.functionsWithContainer.indexOf(nodes.functions[index]) >=0 ); - var functionObj = actionObj[nodes.functions[index]]; - if (functionObj) { - functionFound = true; - if ((functionObj.if == undefined) || self.if(functionObj.if, container, argumentsPar)) { - //if ((functionObj.if == undefined) || Boolean(self.js(functionObj.if, argumentsPar))) { - return self.doFunction({ - name: nodes.functions[index], - function: functionObj, - args: argumentsPar, - selector: selectorParams, - withContainer: withContainer - }); - } else { - if (functionObj.if !== undefined) { - - self.log(self.js(functionObj.if, argumentsPar)); - } - } - } - } - - if (!functionFound) { - self.log('actionPar'); - self.log(actionPar); - self.log('!functionFound'); - self.log(actionObj); - return self.method(actionObj, argumentsPar); - } - - } - } - - } else { - //self.log('Function not found'); - //self.log(actionPar); - //self.log(argumentsPar); - return actionPar; - // functions from this.do - //actionPar(argumentsPar); - } - } - } - } else { - // TO DO: check - //self.log('function with actionPar undefined'); - } - - } - */ - /* this.jsonicMethod2 = function (actionObj, selectorParams, argumentsPar) { - - var functionFound = false; - - for (var action in actionObj) { - var functionObj = actionObj[action]; - if (functionObj) { - var withContainer = (nodes.functionsWithContainer.indexOf(action) >=0 ); - functionFound = true; - if ((functionObj.if == undefined) || Boolean(self.js(functionObj.if, argumentsPar))) { - return self.doFunction({ - name: action, - function: functionObj, - args: argumentsPar, - selector: selectorParams, - withContainer: withContainer - }); - } - } - - if (!functionFound) { - self.log('!functionFound'); - self.log('actionObj'); - self.log(actionObj); - return self.method(actionObj, argumentsPar); - } - } - - - } */ - this.for = function (params, selectorParams, args) { - /* self.log('for'); - self.log(params); */ - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - - // TO DO: doesn't go as an automous function (needs to be inside a div) - /* self.log('for'); - self.log('container'); - self.log(container); */ - //if (params.html) { // new version - let itemsName = params.id || params.name; - //self.log('itemsArray'); - //self.log(itemsArray); - /* if (params.reverse) { - var itemsReversed = {}; - for (var key in Object(itemsArray).keys().reverse()) { - itemsReversed[key] = itemsArray[key]; - } - itemsArray = itemsReversed; - } */ - if (params.of) { - //var itemsArray = self.cloneObject(params.of); // value is the previous array id - //if (typeof itemsArray == 'string') - //itemsArray = self.compile(itemsArray, args); // compile includes functions and create bugs - //self.log('params.of'); - //self.log(params.of); - var itemsArray = self.replaceProperties(params.of, args); - - - /* self.log('itemsArray'); - self.log(itemsArray); */ - /* if (typeof itemsArray == 'string') { - itemsArray = self.js(itemsArray); // TO DO: check - } */ - if (itemsArray) { - - /* if (typeof itemsArray == 'string') { - if (itemsArray.startsWith('js:')) itemsArray = self.js(itemsArray.substr(3)); - //else itemsArray = self.replaceProperties(itemsArray, args); - } */ - /* else { - itemsArray = self.actionResult(itemsArray, args); - itemsArray = self.replaceProperties(itemsArray, args); - } */ - /* self.log('itemsArray replaced'); - self.log(itemsArray); */ - /* self.log('for'); */ - /* self.log(itemsName); */ - /* self.log(itemsArray); */ - if (params.html) { // 1.0.6 html in for is deprecated - if (!params.do) params.do = []; - else if (!Array.isArray(params.do)) params.do = [params.do]; - params.do.push({ html: params.html }); - } - - - //delete params; // needed to avoid infinite loop - if (typeof itemsArray == 'object') { - - let indexNum = 0; - - for (var index in itemsArray) { - - var item = itemsArray[index]; - - if (typeof item == 'object') { - item.key = index; // obsolete - item.index = index; // obsolete - } - - if (typeof item.output == 'object') { // TO DO: obsolete - - /* self.log('item.for.output'); - self.log(item.for.output); */ - for (let key in item.output) { - - var output = item.output[key]; - if (typeof output == 'string') { - output = self.js(output, args); - } else if (typeof output == 'object') { - //output = self.compile(output, args); - output = self.replaceProperties(output, args); - } - - item = self.replaceItems(item, output, key); // replace - - - - //item = self.replaceProperty(item, key, output); - } - } - - if (params.do.length > 0) { - - //alert(JSON.stringify(params.do)); - //self.do(self.replaceProperty(params.do, itemsName, item), undefined, {selector: container}); - //let objWithIndex = self.replaceStringInObject(params.do, '{' + params.index + '}', index); - let objWithIndex = params.do; - - if (params.var) { // TO DO: obsolete (remove when used) - self.element({ path: params.var, value: item, root: self.json.var }); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, 'index:' + params.var, index); - //objWithIndex = self.replaceStringInObject(objWithIndex, '{index:'+params.var+'}', index); - } - - if (itemsName) { - //objWithIndex = self.replaceStringInObject(objWithIndex, '{index:'+itemsName+'}', index); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, 'index:' + itemsName, index); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, itemsName, item); - //objWithIndex = self.replaceProperty(objWithIndex, 'value:'+itemsName, item); - //objWithIndex = self.replaceProperty(objWithIndex, itemsName, item); // obsolete - } - - if (params.delay) { - params.delay = self.replaceProperties(params.delay); - - let forId = params.var || itemsName; - self.timer({ - name: 't' + forId + index, - after: indexNum * params.delay, - do: objWithIndex - }); - } else { - self.do(objWithIndex, { selector: container }); - } - } - - /* if (params.html) { // should be inside a do // commented from 1.0.6 - let indexName = params.index || 'index'; - let objWithIndex = self.replaceStringInObject(params.html, '{'+indexName+':'+itemsName+'}', index); - objWithIndex = self.replaceProperty(objWithIndex, itemsName, item); - self.do(objWithIndex, {selector: container}); - } */ - indexNum += 1; - - } - } - } - - } else if (params.from !== undefined && params.to !== undefined) { - - /* var step = Number(params.step) || 1; - var from = Number(params.from) || 0; - var to = Number(params.to); */ - var step = self.js(self.replaceProperties(params.step)) || 1; - var from = self.js(self.replaceProperties(params.from)) || 0; - var to = self.js(self.replaceProperties(params.to)); - /* var step = Number(self.replaceProperties(params.step)) || 1; - var from = Number(self.replaceProperties(params.from)) || 0; - var to = Number(self.replaceProperties(params.to)); */ - /* self.log('from'); - self.log(from); - self.log('to'); - self.log(to); - self.log('step'); - self.log(step); */ - if (to !== undefined) { - - for (var index = Number(from); index <= Number(to); index += Number(step)) { - - if (params.var) - self.element({ path: params.var, value: index, root: self.json.var }); - - // TO DO: find "if (params.html) { // 1.0.6" and modify also the following code - var item = self.replaceItems(params, String(index), itemsName); // obsolete: replaced with {index:itemsName} - - - - - - - - - - - //var item = self.replaceProperty(params, itemsName, String(index)); - /* self.log('itemsName'); - self.log(itemsName); - self.log('index'); - self.log(index); - self.log('item'); - self.log(item); */ - if (item.output && typeof item.output == 'object') { //} !== undefined) { - - /* self.log('item.for.output'); - self.log(item.for.output); */ - for (let key in item.output) { - - var output = item.output[key]; - if (typeof output == 'string') { - output = self.js(output, args); - } else if (typeof output == 'object') { - //output = self.compile(output, args); - output = self.replaceProperties(output, args); - } - - item = self.replaceItems(item, output, key); - //item = self.replaceProperty(item, key, output); - } - } - - // item = self.replaceItems(item, itemValue, itemsName); old version - //delete item.for; // needed to avoid infinite loop - if (item.do) { - params.do = self.replacePropertyWithPrefix(item.do, 'index:' + itemsName, index); - //params.do = self.replaceStringInObject(item.do, '{index:'+itemsName+'}', index); - self.do(item.do, selectorParams, args); // return? - - //self.do(item.do, args, selectorParams); // return? - } - if (item.html) { - //params.html = self.replaceStringInObject(item.html, '{index:'+itemsName+'}', index); - params.html = self.replacePropertyWithPrefix(item.html, 'index:' + itemsName, index); - self.html(item.html, selectorParams); - } - } - } - } else { - self.log('"for" element requires "value" or "from" and "to" parameters'); // link to see the documentation - self.log(params); - } - //} - // } - }; - - this.htmlTag = function (params, selectorParams, tagParam, mainParam) { - /* self.log('htmlTag'); - self.log(tagParam); */ - if (Array.isArray(params)) { - for (var index in params) - self.htmlTag(params[index], selectorParams, tagParam, mainParam); - } else { - - //---------------------------------- - // attributes of the tag in the key - // example: "div id=btn btn" - // (classes are without identifier) - //---------------------------------- - let htmlTagSplitter = tagParam.indexOf(' '); - if (htmlTagSplitter > 0) { - let tagClass = tagParam.substr(htmlTagSplitter + 1); - tagParam = tagParam.slice(0, htmlTagSplitter); - if (tagClass) { - if (typeof params !== 'object') params = { 'text': String(params) }; - if (!params.attr) params.attr = {}; - - // attributes in key: attribute=value - let tagArr = tagClass.split(' '); - var attrClass = ''; - for (let tagProp of tagArr) { - let tagAttr = new RegExp("([_a-zA-Z]+[_a-zA-Z0-9-]*)=(.+)"); // [_a-zA-Z0-9-/] - if (tagAttr.test(tagProp)) { - //console.log('attribute found '+tagProp); - let tagPropArr = tagProp.split('='); - params.attr[tagPropArr[0]] = tagPropArr[1]; - } else { - attrClass += ' ' + tagProp; - } - } - - // classes - if (params.attr.class) - params.attr.class = params.attr.class + attrClass; - else { - params.attr.class = attrClass; - } - //alert(tagParam + '/'+ tagClass+ '#'); - } - } - - let htmlTagObj = self.createTagParams(params, tagParam, mainParam); - - self.do(htmlTagObj, selectorParams); - - if (params.database) self.addFirebaseTag(self.extend({}, params, selectorParams)); - - } - }; - - this.createTagParams = function (params, tagParam, mainParam) { - if (!mainParam) { - switch (tagParam) { - case 'header': - case 'main': - case 'footer': - case 'div': - case 'p': - mainParam = 'html'; - break; - case 'img': - mainParam = 'src'; - break; - default: - mainParam = 'text'; // TO DO: -> html (to test with actual apps) - break; - } - } - var paramsObj = {}; - if (typeof params == 'string') paramsObj[mainParam] = params; else paramsObj = params; - paramsObj.tag = tagParam; - return paramsObj; - }; - - - - this.onResize = []; - this.onHashChange = []; - this.onScroll = []; - //let swup; - this.notEmptyObject = function (obj) { - return (obj // null and undefined check - && Object.keys(obj).length > 0); - // && Object.getPrototypeOf(obj) === Object.prototype - // https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object - }; - - this.run = function (params, selectorParams, args) { - /* self.log('run'); - self.log(params); */ - if (Array.isArray(params)) { - for (var index in params) - self.run(params[index], selectorParams, args); - } else { - - - var codeToRun; - if (typeof params == 'object') - codeToRun = self.cloneObject(params); - else if (typeof params == 'string') - codeToRun = self.replaceProperties(params); - else if (typeof params == 'function') - return params(args); - - else - return params; - - /* self.log('codeToRun'); - self.log(codeToRun); */ - if (typeof codeToRun == 'object') { - var selector = codeToRun.selector || codeToRun.container; - if (!selector) selector = selectorParams; - if (typeof selector == 'string') selector = { selector: selector }; - - - - var actions = {}; - for (key in codeToRun) { - - if (nodes.extend.indexOf(key) >= 0) { - var obj = {}; - obj[key] = codeToRun[key]; - self.extendJson(self.json, obj); - } else if (['setup', 'container', 'selector', 'resources', 'on', 'do'].indexOf(key) < 0) - actions[key] = codeToRun[key]; - } - - /* self.log('codeToRun.on'); - self.log(codeToRun.on); - - self.log('selector'); - self.log(selector); */ - // actions - //if (codeToRun.container) {self.empty(codeToRun.container);} // reset - // .in SIGNIFICA CONTENITORE (select) - if (codeToRun.on) { self.on(codeToRun.on, selector); } - if (codeToRun.do) { self.do(codeToRun.do, selector, args); } - - if (self.notEmptyObject(actions)) { - /* self.log('notEmptyObject actions'); - self.log(actions); - self.log('selector'); - self.log(selector); */ - return self.do(actions, selector, args); - //return self.do(actions, args, codeToRun.in); - } - } - } - - //self.extendJsonFromElement(codeToRun); // style, actions, texts, data, var. no setup, on, do, blocks, container - }; - /* - this.execute = function (params, selectorParams, args) { // obsolete - - // should create a new jsonicApp instance and assign it to jsonic[id] - // jsonicApp should load the plugins required and not are already loaded - // jsonicApp should import the json not already imported - // jsonicApp should load the icons not already loaded - - // jsonicApp should init the database if not already initialized - // otherwise should copy the db object from window.jsonic? - - // to have app relative var and data these should be called as var:clock.... / var:calendar.... - - // or each app should have an ID (without id the ID is "app") - - // to have exclusive setup, var, data/items, pages and to reset var on the second execution - // for example: window.jsonic['container'] = new jsonicObject(options); - self.log('execute'); - - if (params) { - - if (params.do == 'init') { - - self.log('init'); - window.removeEventListener('hashchange'); - window.removeEventListener('resize'); - window.removeEventListener('beforeinstallprompt'); - - // PWA - if ('serviceWorker' in navigator) { - // Register a service worker hosted at the root of the - // site using the default scope. - navigator.serviceWorker.register('/app/assets/pwa/sw.js').then(function(registration) { - self.log('Service worker registration succeeded:', registration); - }, function(error) { - self.log('Service worker registration failed:', error); - }); - } else { - self.log('Service workers are not supported.'); - } - - let deferredPrompt; - - window.addEventListener('beforeinstallprompt', (e) => { - // Prevent Chrome 67 and earlier from automatically showing the prompt - e.preventDefault(); - // Stash the event so it can be triggered later. - deferredPrompt = e; - }); - - self.json.setup.page.hash = window.location.hash.substr(1); - - // we consider json.setup.modules instead of self.modules - // to be sure to follow the right order of execution - - var modules = []; // we need it to keep the order of the modules given in the setup - for (key in json.setup.modules) { - var mod = self.replaceProperties(json.setup.modules[key]); - modules = modules.concat(self.cloneObject(mod)); - } - - //modules.push({name: 'ide', url: 'https://jsonic.io/app/modules/ide.json'}); // TO DO if admin - // or can execute global before all the rest - // modules can contain {libs and apps} - // ide module can be loaded only if required - - for (var mod of modules) { - //self.log(mod.name); - var params = self.modules[mod.name]; - //self.log(params); - - if (params.html) { - - var container = selectorParams || 'body'; - - //if (params.app.html) { - - //var documentTitle = self.json.setup.title; - //if (documentTitle) - // document.title = documentTitle; - //if (document.querySelector('meta[name="description"]')) - // document.querySelector('meta[name="description"]').setAttribute("content", documentDescription); - - self.html(params.html, {container: container}); - - // window events - - //} - } - - if (params.on) { // -> this.on - - // hashchange - - if (params.on.hashchange) { - self.onHashChange.push(params.on.hashchange); - window.addEventListener('hashchange', function() { - self.json.setup.page.hash = window.location.hash.substr(1); // potrebbe essere esplicitato sulla app - //var action = self.cloneObject(params.app.on.hashchange); - //self.replaceAll("{result}", window.location.hash); - self.do(self.onHashChange); - self.uiUpdate(); - }); - } - - // resize - - window.addEventListener('resize', self.resizeEvent); - if (params.on.resize) { - self.onResize.push(params.on.resize); - window.addEventListener('resize', function () { - self.do(self.onResize); - }); - } - - - // receiveMessage - - if (params.on.thunkable && params.on.thunkable.receiveMessage) - window.receiveMessage(function (message) { - //document.querySelector('#message').value = message; - jsonic.functions(params.on.thunkable.receiveMessage, message, undefined); - }); - - - self.on(params.on, {container: container}); // init included - } - - //else - //self.log('The node "app" requires "container" and "html" properties'); - } - - - } else { - - //if (params.setup) args = self.extend(args, params.setup); // or params.args? - if (params.blocks) self.extendJson(json, {blocks: params.blocks}); - //if (params.library) self.extendJson(json, {library: params.library}); // obsolete - if (params.media) self.extendJson(json, {media: params.media}); // obsolete - if (params.functions) self.extendJson(json, {functions: params.functions}); // obsolete - if (params.actions) self.extendJson(json, {actions: params.actions}); - if (params.css) self.extendJson(json, {css: params.css}); - //if (params.styles) self.extendJson(json, {styles: params.styles}); - //if (params.iconset) self.extendJson(json, {iconset: params.iconset}); - if (params.data) self.extendJson(json, {data: params.data}); - if (params.items) self.extendJson(json, {items: params.items}); - if (params.var) self.extendJson(json, {var: params.var}); - - if (params.html) { - var container = selectorParams || 'body'; // is an object - if (typeof container == 'string') - container = {container: container}; - - - //if (self.inputValue({id: 'module'}) == 'base') { - // icons will be obsolete - - //} else { - //var setup = extendParams.setup || params.setup; - //if (container || html.container) { - - - //if (params.app.html) { - var code = self.cloneObject(params.html); - //self.log('code'); - //self.log(code); - //self.log(JSON.stringify(code)); - - self.html(code, container); - //} - //} else { - // self.log('execute method requires container parameter'); - //} - - if (params.on && params.on.init) { - self.do(params.on.init, undefined, container); - } - // args can be params.setup - //} - } else if (params.module) { - var moduleId = self.replaceProperties(params.module); - return self.do(self.modules[moduleId]); - } - - - } - - } - } */ - /* this.createApp = function (data) { - self.log('createApp'); - //self.log(self.modules); - - let deferredPrompt; - - window.addEventListener('beforeinstallprompt', (e) => { - // Prevent Chrome 67 and earlier from automatically showing the prompt - e.preventDefault(); - // Stash the event so it can be triggered later. - deferredPrompt = e; - }); - - self.json.setup.page.hash = window.location.hash.substr(1); - - for (var file in self.modules) { - var params = self.modules[file]; - - //if (params.on) self.extendJson(json, {media: params.media}); - // if (params.icons) self.extendJson(json, {icons: params.icons}); - //if (params.functions) self.extendJson(json, {functions: params.functions}); - //if (params.styles) self.extendJson(json, {styles: params.styles}); - //if (params.items) self.extendJson(json, {items: params.items}); - //if (params.var) self.extendJson(json, {var: params.var}); - //if (params.library) self.extendJson(json, {library: params.library}); - - if (params.app && params.app.container) { - - //var documentTitle = self.json.setup.title; - //if (documentTitle) - // document.title = documentTitle; - //if (document.querySelector('meta[name="description"]')) - // document.querySelector('meta[name="description"]').setAttribute("content", documentDescription); - - //alert(document.querySelector(params.app.container).isConnected); - self.html(params.app.html, {container: params.app.container}); - - // window events - - if (params.app.on) { // -> this.on - - // hashchange - - if (params.app.on.hashchange) { - self.onHashChange.push(params.app.on.hashchange); - window.addEventListener('hashchange', function() { - self.json.setup.page.hash = window.location.hash.substr(1); // potrebbe essere esplicitato sulla app - //var action = self.cloneObject(params.app.on.hashchange); - //self.replaceAll("{result}", window.location.hash); - self.do(self.onHashChange); - self.uiUpdate(); - }); - } - - // resize - - window.addEventListener('resize', self.resizeEvent); - if (params.app.on.resize) { - self.onResize.push(params.app.on.resize); - window.addEventListener('resize', function () { - self.do(self.onResize); - }); - } - - // receiveMessage - - if (params.app.on.thunkable && params.app.on.thunkable.receiveMessage) - window.receiveMessage(function (message) { - //document.querySelector('#message').value = message; - jsonic.functions(params.app.on.thunkable.receiveMessage, message, undefined); - }); - - // init - self.log('params.app.on'); - self.log(params.app.on); - self.log('params.app.container'); - self.log(params.app.container); - - self.on(params.app.on, {container: params.app.container}); - } - - } - //else - //self.log('The node "app" requires the "container" property'); - } - - - if (self.pluginsLoaded['swup'] && self.json.setup.swup) { - let swup = new Swup(self.json.setup.swup); - } - - - self.do(data); - } */ - /* this.menuToggle = function () { - self.log('menuToggle'); - //$('.offcanvas-collapse').toggleClass('open'); - $('#header').toggleClass('headerMenuOpen'); - var.menuOpen = (!var.menuOpen); - self.log(var.menuOpen); - } - - this.menuOpen = function () { - self.log('menuOpen'); - $('#menu').addClass('menuOpen'); - var.menuOpen = true; - self.log(var.menuOpen); - } - - this.menuClose = function () { - self.log('menuClose'); - $('#menu').removeClass('menuOpen'); - var.menuOpen = false; - self.log(var.menuOpen); - } */ - /* this.createMenu = function (data) { - self.log('createMenu'); - // self.userRole - var menuId = (typeof data.id == 'function') ? data.id() : data.id; - var container = data.container || '#header > ul'; - $(container).empty(); - - for (var index in self.json.menu[menuId]) { - var selector = container + ' > li:eq(' + index + ')'; // > span'; - var item = self.json.menu[menuId][index]; - // action - //if (item.page && !item.action) item.action = {page: item.page}; - if (!var.functions[container]) - var.functions[container] = {}; - var.functions[container][index] = item; - - $(container).append('
  • '); - item.color = item.color || 'inherit'; - item.background = item.background || 'transparent'; - item.border = item.border || 'transparent'; - - self.tab(item, {container: selector}); - - } - self.do(data); - } */ - /* this.changeMenu = function (menuId) { - } - */ - /* this.form = function (params, selectorParams) { - // replaceProperties può essere passato all'inizio di ogni costruttore - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var container = params.container || self.selector(selectorParams); - //var elementContainer = self.query(container); - //var selector = self.selector(self.extend({}, params, selectorParams)); - //var element = self.query(selector); - - //params.tag = 'form'; - //if (params.id === undefined) {params.id = '';} - //if (params.value === undefined) {params.value = ''}; - //if (params.class === undefined) {params.class = ''}; - - //$(container).append('<'+params.tag+' id="'+params.id+'" class="'+params.class+'" data-value="'+params.value+'" data-selector="'+selector+'">'); - for (var itemKey in params.items) { - var item = params.items[itemKey]; - - self.html({ - "form": { - "attr": { - "id": params.id, - "class": params.class, - "data-value": params.data-value || params.value - }, - "div": [ - { - "attr": { - "class": "form-group", - "data-value": itemKey - }, - "html": [ - { - "label": { - "attr": { - "for": itemKey, - "text": item.title - } - } - }, - { - "input": { - "attr": { - "id": itemKey, - "class": "form-control", - "data-value": "formInput" + itemKey, - "value": item.inputValue, - "type": item.type, - "text": item.title, - "aria-describedby": "note"+itemKey, - "placeholder": "", - "disabled": disabled - } - } - }, - { - "small": { - "attr": { - "class": "form-text text-muted", - "data-value": "formNote"+itemKey, - "text": item.note - } - } - }, - ] - } - ] - } - }, { - container: container - }); - - } - - } */ - /* this.addList = function (params, selectorParams) { - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - if (params.id === undefined) {params.id = '';} - if (params.value === undefined) {params.value = ''}; - if (params.class === undefined) {params.class = ''}; - $(container).append('
      '); - - self.list(params, {container: container}); - - } */ - /* - this.addBlock = function (params, selectorParams) { - - if (params.icons) self.icons(params.icons, selectorParams); - if (params.tab) self.tab(params.tab, selectorParams); - if (params.html) self.html(params.html, selectorParams); - if (params.div) self.div(params.div, selectorParams); - if (params.ul) self.ul(params.ul, selectorParams); - if (params.li) self.li(params.li, selectorParams); - if (params.span) self.span(params.span, selectorParams); - if (params.img) self.img(params.img, selectorParams); - if (params.form) self.form(params.form, selectorParams); - if (params.list) self.addList(params.list, selectorParams); - //if (params.img) alert(JSON.stringify(params.img.src)); - } - */ - /* this.blocks = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.blocks(params[index], selectorParams, args); - } else { - if (typeof params == 'string') { - var blocksObj = self.get('self.json.library.'+params); - if (blocksObj) - self.blocks(blocksObj.blocks, selectorParams); - } else { - if (params.library) { - self.library(params.library, selectorParams, args); // {container: container} - } else { - self.addTag(params, selectorParams, args); // {container: container} - } - } - } - } - */ - this.inputValue = function (params) { - var selector = self.selector(params.selector || params.container); - var element = document.querySelector(selector); // self.query(p2); - return element.value; - }; - - - /* this.layout = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.layout(params[index], selectorParams, args); - } else { - if (typeof params == 'string') { - var libraryObj = self.get('self.json.layouts.'+params); // todo: get? - //var libraryHtml = libraryObj.html || libraryObj.blocks; - if (libraryObj) - self.layout(libraryObj, selectorParams, args); // TODO warning potential infinite loop (if string) - else - self.log('"theme" not found: ' + params); - } else { - var libraryHtml = params.html; - // can a library component be an object? - if (params.setup) args = self.extend(args, params.setup); // or params.args? - if (params.functions) self.extendJson(json, {functions: params.functions}); - if (params.css) self.extendJson(json, {css: params.css}); - //if (params.styles) self.extendJson(json, {styles: params.styles}); - if (params.items) self.extendJson(json, {items: params.items}); - if (params.var) self.extendJson(json, {var: params.var}); - self.html(libraryHtml, selectorParams, args); // {container: container} - //self.(params, selectorParams, args); - } - } - } */ - this.part = this.block = function (params, selectorParams, args) { - - let nested; - let part; - let partArguments; - - if (typeof params.do == 'string' && self.json.parts) { // && par.match(/[.>]+/)) - - self.log('PART: ' + params.do, 'brown'); - - params.do = self.replaceProperties(params.do); - - if (typeof params.do == 'object') - part = params.do; - - else - part = self.element({ path: self.replaceAll(params.do, ':', '.'), root: self.json.parts }); // TO DO: . -> space? - - - - /* if (par.indexOf(':')>0 && !part) { - self.firebaseGetPart({localPath:localPath, container: params.selector, arg:params.obj}); - } */ - } else if (typeof params.do == 'object') - part = params.do; - - if (part) { - //if (!params.arguments) params.arguments = {}; - // TO DO: Check this. seems a workaround for fantacards/ui:qrcode - if (params.arguments) - partArguments = self.replaceProperties(params.arguments); - - if (typeof params.arguments == 'object') { - partArguments = (params.arguments.setup) ? params.arguments.setup : params.arguments; // compatibility - partArguments.selector = partArguments.selector || params.selector; - } - - nested = self.replacePropertyWithPrefix(part, 'setup', partArguments); // {setup} -> {arguments} - nested = self.replacePropertyWithPrefix(nested, 'arguments', partArguments); // to tix - - self.extendJsonFromElement(nested); - self.do(nested, params.selector, partArguments); - } - }; - - this.blocks = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.blocks(params[index], selectorParams, args); - } else { - //self.log('blocks'); - //self.log(params); - if (typeof params == 'string') { - - var blockName = self.replaceProperties(params, args); // self.compile(params, args); - - - - //self.log('blockName'); - //self.log(blockName); - var libraryObj = self.element({ path: 'self.json.blocks.' + blockName }); // todo: get? - - - - - - //self.log('libraryObj'); - //self.log(libraryObj); - //var libraryHtml = libraryObj.html || libraryObj.blocks; - if (libraryObj) - //self.html(libraryObj, selectorParams, args); - self.run(libraryObj, selectorParams, args); - - - //self.blocks(libraryObj, selectorParams, args); // TODO warning potential infinite loop (if string) - else - self.log('library component not found: ' + params); - } else { - self.run(params, selectorParams, args); - //self.run(params, selectorParams, args); - //var libraryHtml = params.html || params.app.html; - /* // can a library component be an object? - if (params.setup) args = self.extend(args, params.setup); // or params.args? - if (params.parts) self.extendJson(json, {parts: params.parts}); - if (params.actions) self.extendJson(json, {actions: params.actions}); - if (params.css) self.extendJson(json, {css: params.css}); - if (params.data) self.extendJson(json, {data: params.data}); - if (params.var) self.extendJson(json, {var: params.var}); - if (params.texts) self.extendJson(json, {texts: params.texts}); - - self.html(params.html, selectorParams, args); // {container: container} - //self.do(params, selectorParams, args); */ - } - } - }; - - this.uiUpdate = function (option) { - window.dispatchEvent(new Event('resize')); // workaround known ACE bug - - //self.updateCodeEditors(); // workaround known ACE bug - }; - - this.resizeEvent = function (event) { - //self.log('resizeEvent'); - for (var selector in self.resizeActions) { - var element = self.query(selector); - for (var property in self.resizeActions[selector]) { - if (property == 'action') { - self.do(self.resizeActions[element].action, { selector: selector }); - //self.do(self.resizeActions[element].action, {selector: selector}); - } else { - var value = self.resizeActions[selector][property]; - var result = self.replaceProperties(value) || ''; - //$(selector).css(property, result); - element.style[property] = result; - } - } - } - }; - - - - /* var pages = {}; - var pagesSlider; - - this.createPages = function (data) { - self.log('createPages'); - - //backLink = (self.json.setup && self.json.setup.home && self.json.setup.home[var.mode]) ? self.json.setup.home[var.mode] : ''; - // class="container-fluid px-0" style="margin-top:'+self.json.setup.main.top+'" - - var pageContainer = '#pages'; // 'main > div' - - for (var pageKey in self.json.pages) { - params = self.json.pages[pageKey]; - var pageRoles = (params.roles) ? String(params.roles).split(',') : undefined; - - // se il ruolo dell'utente permette la vista della pagina e se non è stata già creata - if (!params.roles || (pageRoles.indexOf(self.userRole()) >= 0 && document.querySelectorAll('#'+pageKey).length == 0)) { // $('#'+pageKey).length == '#'+pageKey doesn't exist - - //if (params.preload) { - - params.tag = 'div'; - //params.id = pageKey; - params.class = 'page'; - params.value = pageKey; - - // the previous definition should be in layout.page - - self.addTag(params, {container: pageContainer}); - //} - - - } else { - self.log('' + self.userRole() + ' users can\'t access to the page '+pageKey); - } - } - - self.do(data); - } */ - this.pageFullScreen = function (onOff) { - self.log('pageFullScreen'); - if (onOff) - self.addClass(document.querySelector('body'), 'fullscreen'); - - else - self.removeClass(document.querySelector('body'), 'fullscreen'); - }; - - //var backLink = 'stage'; - /* this.pageBack = function () { - self.gotoPage(backLink); - //window.location.href = '?p='+backLink; - //$('body').removeClass('nav-open'); // chiude menu - } */ - this.link = function (link, args) { - /* function link() { - [native code] - } */ - //alert(link); - link = self.replaceProperties(link, args); - window.location.href = link; - }; - - this.reload = function () { - location.reload(); - }; - - this.gotoHomePage = function () { - self.gotoPage(self.homePage()); - }; - - this.homePage = function () { - //alert('homePage'); - if (self.json.pages) { - if (Object.keys(self.json.pages).length > 0) { - //var homeKey = Object.keys(self.json.pages).find(key => self.json.pages[key] === 'home'); - if (self.json.pages.home) - return 'home'; - - else - return Object.keys(self.json.pages)[0]; - } else { - self.log('No pages in "pages" node'); - } - } else { - self.log('Can\'t find the "pages" node'); - } - }; - - /* this.activePage = function () { // to check if obsolete - return var.page; - } */ - /* this.slideIndex = function (id) { - return $('#'+id).index()+1; - } */ - /* this.slideTo = function (params) { - if (pagesSlider) pagesSlider.goTo(self.slideIndex(params.id)); - $('#pages > .seq-canvas > .seq-in').addClass(params.transition); - } */ - this.updateCodeEditors = function () { - // workaround known ACE bug: - // setValue doesn't work if editor is hidden - // http://jsfiddle.net/e4r7byLn/ - var elements = document.querySelectorAll('.ace_editor'); - if (elements) { - elements.forEach(function (element, index) { - var editor = ace.edit(element); - editor.renderer.updateFull(true); - //AceColorPicker.load(ace, editor); - //AceColorPicker.load(ace, editor); // works after some ms - }); - } - }; - - this.gotoPage = function (pageId, fromHash) { - self.log('page'); // changePage - self.log('pageId'); - self.log(pageId); - self.log('fromHash'); - self.log(fromHash); - //self.log("var.page"); - //self.log(var.page); - if (pageId) { - - if (self.json.pages) { - if (self.json.pages[pageId]) { - var page = self.json.pages[pageId]; - - if (pageId !== self.json.setup.page.id || fromHash !== self.json.setup.page.hash) { - - if (fromHash) { - //var.pagePath = fromHash; // obsolete - self.json.setup.page.hash = fromHash; - } else { - //delete var.pagePath; - delete self.json.setup.page.hash; - } - - //var.page = pageId; // activePage - //var newHash = pageId; - //if (!fromHash) window.location.hash = newHash; - var fullScreen = self.json.pages[pageId].fullscreen || false; - //self.pageFullScreen(fullScreen); - var pageRoles = (page.roles) ? String(page.roles).split(',') : undefined; - - if (self.params.d || !page.roles || pageRoles.indexOf(self.userRole()) >= 0) { - - if (pageId !== self.json.setup.page.id) { - - /* self.out({ - "class": "page", - "data-value": self.json.setup.page.id, - "transition": "fadeOutLeft" - }); */ - self.json.setup.page.id = pageId; - self.json.setup.page.title = page.title; - self.json.setup.page.roles = page.roles; - - /* // TO DO: don't change document title and description - - // window title - var documentTitle = self.json.setup.title; - if (page.title) - documentTitle += ' ' + self.text(page.title); - var documentDescription = self.json.setup.description || ''; - if (documentTitle) - document.title = documentTitle; - if (document.querySelector('meta[name="description"]')) - document.querySelector('meta[name="description"]').setAttribute("content", documentDescription); */ - //$('title').text(windowTitle); - // change page - self.hide({ - "class": "page" - }); - self.in({ - "class": "page", - "data-value": pageId, - "transition": "fadeIn" - }); - - /* $('.page').hide(); - $('.page[data-value='+pageId+']').fadeIn(); */ - //self.resizeEvent(); - self.uiUpdate(); // resize event trigger - - - - - - - - - - /* // page back icon - if (page.back) { - backLink = page.back; - $('#headerLeftIcons').show((page.back)); - } else { - $('#headerLeftIcons').hide(); - } */ - } - - if (page.update) { // obsolete - self.do(page.update); //, {container: '.page[data-value='+pageId+']'}); - - //self.do(page.update); //, {container: '.page[data-value='+pageId+']'}); - } - - if (page.init) self.do(page.init); - - self.log(page); - if (page.on) - self.on(page.on, { selector: '.page[data-value=' + pageId + ']' }); - - //$('body').removeClass('nav-open'); // chiude menu - //$('.offcanvas-collapse').removeClass('open'); - } else { - if (self.userRole() == 'guest') { - /* self.do({ - "login": { - "success": { - "reload": true - } - } - }); */ - } else { - self.alert('Non hai i privilegi per accedere a questa pagina'); - } - - } - } else { - // pagina non trovata - } - } else { - self.log('Can\'t find the page "' + pageId + '"'); - } - } else { - self.log('Can\'t find the main node "pages"'); - } - } else { - return self.json.setup.page; - } - }; - - var alertInterval; - - this.getTime = function (ms) { - var sec = parseInt(ms / 1000); - var min = parseInt(sec / 60); - sec = sec - min * 60; - if (min < 10) min = '0' + min; - if (sec < 10) sec = '0' + sec; - return min + ':' + sec; - }; - - this.sortablejs = function (params, selectorParams, args) { - let container = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - let query = self.query(container); - self.log('container'); - self.log(container); - self.log('query'); - self.log(query); - var sortable = Sortable.create(query); - }; - - this.alert = function (params, args) { - /* self.log('alert'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - var paramsReplaced = self.cloneObject(params); - - //paramsReplaced = self.replaceProperties(paramsReplaced, args); - //self.log('paramsReplaced'); - //self.log(paramsReplaced); - if (paramsReplaced) { - if (paramsReplaced.do && paramsReplaced.do !== 'fire') { - return Swal[paramsReplaced.do](params); - // more info on https://sweetalert2.github.io/#methods - } else { - if (typeof paramsReplaced == 'string') paramsReplaced = self.text({ string: paramsReplaced, args: args }); // verify - - - - //self.log('paramsReplaced string replaced'); - //self.log(paramsReplaced); - if (typeof paramsReplaced == 'number') paramsReplaced = String(paramsReplaced); // avoid bug - if (paramsReplaced.title !== undefined) paramsReplaced.title = self.text({ string: paramsReplaced.title, args: args }); - - //self.log('paramsReplaced2'); - //self.log(paramsReplaced); - if (paramsReplaced.html && typeof paramsReplaced.html == 'string') paramsReplaced.html = self.replaceProperties(paramsReplaced.html, args); - if (paramsReplaced.text !== undefined) paramsReplaced.text = self.text({ string: paramsReplaced.text, args: args }); - //self.log('paramsReplaced string replaced 2'); - if (paramsReplaced.inputValue) paramsReplaced.inputValue = self.text({ string: paramsReplaced.inputValue, args: args }); - - //if (paramsReplaced.html) paramsReplaced.html = self.text({string: paramsReplaced.html, args: args}); // verify - if (paramsReplaced.cancelButtonText) paramsReplaced.cancelButtonText = self.text({ string: paramsReplaced.cancelButtonText, args: args }); - if (paramsReplaced.confirmButtonText) paramsReplaced.confirmButtonText = self.text({ string: paramsReplaced.confirmButtonText, args: args }); - if (paramsReplaced.denyButtonText) paramsReplaced.denyButtonText = self.text({ string: paramsReplaced.denyButtonText, args: args }); - //if (paramsReplaced.showConfirmButton) paramsReplaced.showConfirmButton = self.text({string: paramsReplaced.showConfirmButton, args: args}); - if (paramsReplaced.inputPlaceholder) paramsReplaced.inputPlaceholder = self.text({ string: paramsReplaced.inputPlaceholder, args: args }); - if (paramsReplaced.validationMessage) paramsReplaced.validationMessage = self.text({ string: paramsReplaced.validationMessage, args: args }); - //if (paramsReplaced.inputOptions) paramsReplaced.inputOptions = self.text({string: paramsReplaced.inputOptions, args: args}); - if (paramsReplaced.footer) { - paramsReplaced.footer = self.text({ string: paramsReplaced.footer, args: args }); - } - - //if (paramsReplaced.upload) alert('paramsReplaced.upload: '+paramsReplaced.upload); - if (paramsReplaced.upload) { - paramsReplaced.html = '
      ' + self.text('dragAndDropFiles') + '
      ' + self.text('chooseFiles') + '
      '; - // - //if (paramsReplaced.onUpload) var.onUpload = paramsReplaced.onUpload; - //var.uploadingTarget = paramsReplaced.uploadingTarget; - } - - //self.log('paramsReplaced3'); - //self.log(paramsReplaced); - alertObj.confirm = paramsReplaced.confirm; // deprecated - alertObj.cancel = paramsReplaced.cancel; // deprecated - alertObj.deny = paramsReplaced.deny; // deprecated - alertObj.on = paramsReplaced.on; - alertObj.id = paramsReplaced.id; - delete paramsReplaced.on; - - - - var alertHtml = paramsReplaced.html || paramsReplaced.blocks; - if (alertHtml) - paramsReplaced.html = " "; - - var swalParams = self.replaceProperties(paramsReplaced, args); - - // animate - if (paramsReplaced.animate) { - var animationIn = paramsReplaced.animate.in || paramsReplaced.animate; - var animationOut = paramsReplaced.animate.out || paramsReplaced.animate; - if (paramsReplaced.animate.in) - animationIn = paramsReplaced.animate.in.transition || paramsReplaced.animate.in; - if (paramsReplaced.animate.out) - animationOut = paramsReplaced.animate.out.transition || paramsReplaced.animate.out; - swalParams.showClass = { - popup: 'animate__animated animate__faster animate__animated animate__' + animationIn - }; - swalParams.hideClass = { - popup: 'animate__animated animate__faster animate__animated animate__' + animationOut - }; - } - - var customIcon; - if (swalParams.icon) { - //swalParams.icon = self.replaceProperties(swalParams.icon, args); - if (typeof swalParams.icon !== 'string') { - customIcon = self.cloneObject(swalParams.icon); - delete swalParams.icon; - } - /* var swalIcons = []; //"warning", "error", "success", "info", "question"]; - if (swalIcons.indexOf(params.icon)<0) { - customIcon = params.icon; - - //if (!params.customClass) params.customClass = {}; - //params.customClass.icon = "customIcon"; - } */ - } - - - - //if (swalParams.showConfirmButton) delete swalParams.showConfirmButton; - // swalParams.update = function() { - // self.log('swalParams.update'); - // self.log(var.updateSwal); - // } - // onRender is obsolete - /* swalParams.onRender = function () { - startUploadListeners({ - container: '.drop-zone', - onUpload: params.onUpload, - path: params.path - //uploadingTarget: var.uploadingTarget - //onError: - }); - } -*/ - delete swalParams.blocks; - delete swalParams.onUpload; - delete swalParams.upload; - - if (swalParams.confirm) delete swalParams.confirm; - if (swalParams.cancel) delete swalParams.cancel; - if (swalParams.timerProgressBar) { - swalParams.onBeforeOpen = function () { - //Swal.showLoading(); // rimuove i bottoni - alertInterval = setInterval(() => { - const content = Swal.getContent(); - if (content) { - const b = content.querySelector('b'); - if (b) { - b.textContent = self.getTime(Swal.getTimerLeft()); - } - } - }, 100); - }; - swalParams.onClose = function () { - clearInterval(alertInterval); - }; - } - - //self.log('swalParams'); - //self.log(swalParams); - Swal.fire(swalParams).then((result) => { - //self.log('alert result'); - //self.log(result); - // TO DO: if (!result) result = {} to avoid errors - var alertResult = result.value; - - if (alertObj.on) { - if (alertObj.on.value && result.value) { - //if (alertObj.id) alertObj.values[alertObj.id] = result.value; - if (alertObj.id) alertValues[alertObj.id] = result.value; - alertValues.value = result.value; - setTimeout(function () { - alertObj.on.value = self.replacePropertyWithPrefix(alertObj.on.value, 'alert', alertValues); - //alertObj.on.value = self.replaceProperty(alertObj.on.value, 'alert', result); - self.do(alertObj.on.value, undefined, result.value); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.value, result.value); // TO DO: remove result.value once removed all {result} - }, 500); - } - if (alertObj.on.isConfirmed && result.isConfirmed) { - if (alertObj.id) alertValues[alertObj.id] = result.isConfirmed; - alertObj.on.isConfirmed = self.replacePropertyWithPrefix(alertObj.on.isConfirmed, 'alert', alertValues); - alertObj.on.isConfirmed = self.replacePropertyWithPrefix(alertObj.on.isConfirmed, 'alert', result); - self.do(alertObj.on.isConfirmed, undefined, result.value); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.isConfirmed, result.value); // TO DO: remove result.value once removed all {result} - } - if (alertObj.on.isDenied && result.isDenied) { - alertObj.on.isDenied = self.replacePropertyWithPrefix(alertObj.on.isDenied, 'alert', result); - self.do(alertObj.on.isDenied, undefined, result.value); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.isDenied, result.value); // TO DO: remove result.value once removed all {result} - } - if (alertObj.on.isDismissed && result.isDismissed) { - alertObj.on.isDismissed = self.replacePropertyWithPrefix(alertObj.on.isDismissed, 'alert', result); - self.do(alertObj.on.isDismissed, undefined, result.dismiss); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.isDismissed, result.dismiss); // TO DO: remove result.value once removed all {result} - } - - console.log('alertValues'); - console.log(alertValues); - - - } else { - /* if (result.isConfirmed) { - self.do(alertObj.confirm, result.value); - } else if (result.isDenied) { - self.do(alertObj.deny, result.value); - } else if (result.dismiss === Swal.DismissReason.cancel) { - self.do(alertObj.cancel, result.value); - } else if (result.dismiss === Swal.DismissReason.timer) { - self.log('Alert closed by the timer'); - } */ - } - - /* - - Reason Description Related configuration - Swal.DismissReason.backdrop The user clicked the backdrop. allowOutsideClick - Swal.DismissReason.cancel The user clicked the cancel button. showCancelButton - Swal.DismissReason.close The user clicked the close button. showCloseButton - Swal.DismissReason.esc The user clicked the Esc key. allowEscapeKey - Swal.DismissReason.timer The timer ran out, and the alert closed automatically. timer - - */ - }); - - if (alertHtml) - self.do(alertHtml, { selector: '#swal2-html-container' }); - - //self.log('customIcon'); - //self.log(customIcon); - if (customIcon) { - /* self.icons({ - "class": "icon", - "svg": customIcon - }, {container: '.swal2-icon'}); */ - self.do(customIcon, { selector: '.swal2-icon' }); - //self.addTag(customIcon, {container: '.swal2-icon'}); // check - self.css({ - selector: '.swal2-icon', - style: { - 'border': '0px solid transparent' - } - }); - self.show({ - selector: '.swal2-icon' - }); - /* $('.swal2-icon').css({ - 'border': '0px solid transparent' - }); - $('.swal2-icon').show(); */ - } - - if (swalParams.on && swalParams.on.init) // to be repeated in each function - self.do(swalParams.on.init); - //self.do(swalParams.on.init); - } - } - }; - - /* var startUploadListeners = function (params) { // da FIXO - self.log('startUploadListeners'); - var.upload = params; - var obj = $(params.container); - self.log(params); - obj.on('dragenter', function (e) { - e.stopPropagation(); - e.preventDefault(); - $(this).css('border', '2px solid #0B85A1'); - }); - obj.on('dragover', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); - - $(document).on('dragenter', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); - $(document).on('dragover', function (e) { - e.stopPropagation(); - e.preventDefault(); - obj.css('border', '2px dotted #0B85A1'); - }); - $(document).on('drop', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); - // automatically submit the form on file select - - obj.on('drop', function (e) { - $(this).css('border', '2px dotted #0B85A1'); - e.preventDefault(); - var files = e.originalEvent.dataTransfer.files; - - //We need to send dropped files to firebase - handleFileUpload(files); - }); - $(params.container+'-file').on('change', function (e) { - var files = $(params.container+'-file')[0].files; - self.log(params.container+'-file'); - self.log(files) - handleFileUpload(files); - }); - - } */ - /* this.uploadFileNameAndType = function(params){ - self.log('uploadFileNameAndType'); - self.log(params); - - var fileArr = params.fileName.split('.'); - var.upload.fileName = params; - var.upload.fileType = fileArr[1].toLowerCase(); - if (!$('.swal2-act').length) $('.swal2-modal').append('
      '); - if (var.upload.fileType == 'ply') { - $('.swal2-act').css({'display':'none'}); - } else { - $('.swal2-act').css({'display':'block'}); - $('.swal2-act').append(''); - } - } */ - /* var handleFileUpload = function(files) { - self.log('handleFileUpload'); - self.log(files); - self.log('var.upload'); - self.log(var.upload); - //var auth0Id = fixo.getAuth0Id(); - // Swal.close(); // chiusura popup - for (var i = 0; i < files.length; i++) { - var fd = new FormData(); - fd.append('file', files[i]); - if (!files[i].name.endsWith('png')) var.upload.fileTimestamp = self.getTimestamp(); - - self.fireBaseUpload({ - 'file': files[i], //base64toBlob(files), - 'timestamp': var.upload.fileTimestamp, - 'path': var.user.uid+'/' || '' //auth0Id+'/files/images' //path_to_where_you_to_store_the_file - }, function (data) { - self.log('data'); - self.log(data); - if (!data.error) { - //if (data.progress && data.progress == 0) $('.swal2-actions').append(''); - if (data.progress >= 0 && data.progress <= 100) { - //progress update to view here - // self.log('Uploading file'); - // self.log(var.uploadingTarget); - $('#msgFooter').html(''+data.progress+'%') - } - if (data.progress == 100) { - //$(var.uploadingTarget).removeClass('pulseFade'); - // Swal.close(); - - if (data.fileExt !== 'png'){ - self.log('diverso da png'); - $('.drop-zone-file').attr('accept','.png'); - var.upload.data = data; - } - - if (var.upload.onUpload) self.do(var.upload.onUpload, data); - } - } else { - //$(var.uploadingTarget).removeClass('pulseFade'); - self.log(data.error + ' Firebase image upload error'); - } - }); - } - }; */ - /* var uploadDone = function (data) { - self.log('uploadDone'); - // download URL here "data.downloadURL" - var auth0Id = fixo.getAuth0Id(); - var storageRef = firebase.storage().ref(); - var imageRef = storageRef.child(auth0Id+'/files/images/'+data.fileName); - // Get the download URL - imageRef.getDownloadURL().then(function(url) { - self.do(var.onUpload, url); - // Insert url into an tag to "download" - }).catch(function(error) { - self.log(error.code); - // A full list of error codes is available at - // https://firebase.google.com/docs/storage/web/handle-errors - - switch (error.code) { - case 'storage/object_not_found': - // File doesn't exist - break; - - case 'storage/unauthorized': - // User doesn't have permission to access the object - break; - - case 'storage/canceled': - // User canceled the upload - break; - - case 'storage/unknown': - // Unknown error occurred, inspect the server response - break; - } - }); - } */ - this.findKey = function (obj, key) { - return obj.filter(function (item) { - return Boolean(item[key]); - }); - }; - - /* this.fireBaseUpload = function(parameters, callBackData) { - self.log('fireBaseUpload'); - self.log('parameters'); - self.log(parameters); - - // Get a reference to the storage service, which is used to create references in your storage bucket - var storageRef = firebase.storage().ref(); - - - var file = parameters.file; - var path = parameters.path; - var timestamp = parameters.timestamp; - //var path = var.user.uid; // non riesco a passare la path come parametro da olo.app.json così come l'errore funzione onUpload - - - self.log('file'); - self.log(file); - self.log('timestamp'); - self.log(timestamp); - self.log('path'); - self.log(path); - - //Riga originale pre-modifica nome file - // var fullPath = path + '/' + file.name; - - // expected parameters to start storage upload - var metaData = {'contentType': file.type}; - var fileSize = formatBytes(file.size); // get clean file size - var fileType = file.type; - var fileName = file.name; - var fileExt = fileName.split('.')[1]; - - self.log(metaData); - self.log(fileSize); - self.log(fileType); - self.log(fileName); - self.log(fileExt); - var modFileName = timestamp+'.'+fileExt; - - //var fullFilePath = storageRef.child(path+timestamp+'-'+fileName); - var fullFilePath = storageRef.child(path+modFileName); - self.log('fullFilePath'); - self.log(fullFilePath); - - var nm = fileName.split('.'); - var name = nm[0]; - - self.log('nm'); - self.log(nm); - self.log('name'); - self.log(name); - - - - // Modifica file name generato - // var name = generateRandomString(16); //(location function below) - // var n = name+'.'+file.type.replace('image/',''); - // var fullPath = path + '/' + n; - - - //Riga originale pre-modifica nome file - // var n = file.name; - - - // generate random string to identify each upload instance - //name = generateRandomString(12); //(location function below) - - // var uploadFile = storageRef.child(parameters.path).put(file, metaData); - var uploadFile = fullFilePath.put(file, metaData); - - // first instance identifier - //callBackData({id: name, fileSize: fileSize, fileType: fileType, fileName: n}); 20200724 - callBackData({id: timestamp.toString(), fileSize: fileSize, fileType: fileType, fileName: modFileName, fileExt: fileExt}); // fileName: fileName //id: name - - uploadFile.on('state_changed', function (snapshot) { - var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; - progress = Math.floor(progress); - self.log('progress'); - self.log(progress); - callBackData({ - progress: progress, - element: timestamp.toString(), - //element: name, - fileSize: fileSize, - fileType: fileType, - fileName: modFileName, - fileExt: fileExt}); - //fileName: fileName - }, function (error) { - callBackData({error: error}); - }, function () { - var downloadURL = uploadFile.snapshot.downloadURL; - callBackData({ - downloadURL: downloadURL, - element: timestamp.toString(), - //element: name, - fileSize: fileSize, - fileType: fileType, - fileName: modFileName, - fileExt: fileExt}); - //fileName: fileName - }); - } */ - var formatBytes = function (bytes, decimals) { - if (bytes == 0) return '0 Byte'; - var k = 1000; - var dm = decimals + 1 || 3; - var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - var i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; - }; - - this.userRole = function () { - switch (Boolean(self.user('uid'))) { - case true: - return 'user'; // user logged in - break; - case false: - return 'guest'; - break; - } - }; - - this.userIn = function () { - //var user = firebase.auth().currentUser; - //if (user.emailVerified) { - return Boolean(self.user('uid')); - }; - - this.userOut = function () { - return (!self.user('uid')); - }; - - this.user = function (param) { - /* self.log('user'); - self.log(auth); */ - if (auth && auth.currentUser) - if (param == 'firstName') - return self.firstName(auth.currentUser['displayName']); - else if (auth.currentUser[param]) - return auth.currentUser[param]; - else if (!param) - return auth.currentUser; - - else - return undefined; - - else - return undefined; - }; - - this.firstName = function (nameParam) { - var firstNameStr = (nameParam) ? nameParam.split(' ')[0] : ''; - return firstNameStr; - }; - - this.userUid = function () { - if (auth) return auth.currentUser.uid; - else return undefined; - }; - - this.userVerified = function () { - if (auth) return auth.currentUser.emailVerified; - else return undefined; - }; - - /* this.value = function (valueParams) { - if (valueParams.string) - return valueParams.string - else if (valueParams.function) - //return self.doFunctionByName(valueParams.function, window, ''); - } - */ - this.thunkableMessage = function (message, callback) { - if (callback) callback(message); - }; - - this.onMessage = { - alert: "test" - }; - - this.processMessage = function (message) { - self.alert('processMessage'); - self.do(self.onMessage, message); - //self.do(self.onMessage, undefined, message); - }; - - this.thunkable = function (params, args) { - if (params.postMessage) { - var message = self.replaceProperties(params.postMessage, args); - if (message) { - try { - ThunkableWebviewerExtension.postMessage(message); - } catch (error) { - } - } - else - self.log('in function "thunkable" "postMessage" parameter is wrong'); - } - if (params.receiveMessage) { - self.onMessage = params.receiveMessage; - try { - ThunkableWebviewerExtension.receiveMessage(self.processMessage); - } catch (error) { - } - } - - }; - - /* var ThunkableWebviewerExtension = (function () { - const postMessageToWebview = (message) => { - if (window.ReactNativeWebView) { - window.ReactNativeWebView.postMessage(message); - } else { - window.parent.postMessage(message, '*'); - } - }; - - const getReceiveMessageCallback = (fxn, hasReturnValue) => (event) => { - if (typeof fxn === 'function') { - if (event.data) { - let dataObject; - try { - dataObject = JSON.parse(event.data); - } catch (e) { - // message is not valid json - } - if (dataObject && dataObject.type === 'ThunkablePostMessage' && hasReturnValue) { - fxn(dataObject.message, (returnValue) => { - const returnMessageObject = { type: 'ThunkablePostMessageReturnValue', uuid: dataObject.uuid, returnValue }; - postMessageToWebview(JSON.stringify(returnMessageObject)); - }); - } else if (!hasReturnValue && (!dataObject || dataObject.type !== 'ThunkablePostMessage')) { - fxn(event.data); - } - } - } - }; - - return { - postMessage: postMessageToWebview, - receiveMessage: function (fxn) { - const callbackFunction = getReceiveMessageCallback(fxn, false); - document.addEventListener('message', callbackFunction, false); - window.addEventListener('message', callbackFunction, false); - }, - receiveMessageWithReturnValue: function (fxn) { - const callbackFunction = getReceiveMessageCallback(fxn, true); - document.addEventListener('message', callbackFunction, false); - window.addEventListener('message', callbackFunction, false); - }, - }; - })(); */ - this.extendFunctions = function (functions) { - // change it. don't call self.function - for (var name in functions) { - if (functions[name].js) { - try { - // create or override function - self.functions[name] = new Function(functions[name].js); - } catch (error) { - console.log('ERROR creating function %c' + name, 'color:orange;'); - self.log(functions[name].js); - self.log(error.message); - // error.column is wrong - /* let col = error.column -17; - console.log( - functions[name].js.substring(0,col) - + '%c' + functions[name].js.substring(col, col+1) - + '%c' + functions[name].js.substring(col+1), 'color:orange; font-weight:bold', 'color:#ddd') - console.log('%c' + error.message, 'color:orange;'); */ - // since the script is in one row, error.columns is the exact position of the error - } - } else { - self.log(name + ' function requires js property'); - } - } - }; - - - this.function = function (obj, args) { - /* console.log('function'); - console.log(params); - console.log('args'); - console.log(args); */ - // TO DO: add "name" parameter to make the js function permanently available in self.methods[name] - // https://stackoverflow.com/questions/49125059/how-to-pass-parameters-to-an-eval-based-function-injavascript - //app[func].apply( this, args ); // or app[func]( ...args ); // ES6 (2015) - // https://stackoverflow.com/questions/1316371/converting-an-array-to-a-function-arguments-list - //args = self.replaceProperties(args); // needed? - //try { - if (obj.name && obj.js) { - // create or replace function - self.functions[obj.name] = new Function(obj.js); - } else if (obj.name && !obj.js) { - if (self.functions[obj.name]) { - // execute function - if (!obj.arguments || !Array.isArray(obj.arguments)) obj.arguments = [obj.arguments]; - try { - return self.functions[obj.name](...obj.arguments); - //return self.functions[obj.name].apply(null, obj.arguments); - } catch (error) { - console.log('ERROR in function %c' + obj.name, 'color:orange;'); - console.log('obj'); - console.log(obj); - console.log('function'); - console.log(self.json.functions[obj.name]); - console.log(error.message); - } - } else { - console.log('ERROR function undefined %c' + obj.name, 'color:orange;'); - } - //return self.functions[obj.name](...obj.arguments); // also args? - } else if (obj.js) { - // execute js code as a function - if (obj.arguments && Array.isArray(obj.arguments)) { - return new Function(obj.js).call(null, obj.arguments); - //return new Function( obj.js ).apply(this, obj.arguments ); - } else { - return new Function(obj.js).call(null, obj.arguments); - } - } - /* } catch (error) { - self.log('function ERROR'); - self.log(error); - self.log(obj); - return false - } */ - }; - - - this.eval = this.js = function (code, args) { - /* self.log('js'); - self.log(code); - self.log(args); */ - /* if (Array.isArray(code)) { - let codeCombined = ''; - for (var codePart of code) codeCombined += self.replaceProperties(codePart, args); - try { - return eval(code); - } catch (error) { - self.log('JS error'); - self.log(error); - return code; - } */ - /* if (typeof code == 'object') { - - } else { */ - - code = self.replaceProperties(code, args); - /* self.log('args'); - self.log(args); */ - try { - //return new Function( code ).call(null, args); - return eval(code); - } catch (error) { - /* self.log('javascript catch on "'+ codeString + '"'); - self.log('error'); - self.log(error); - self.log('codeString'); - self.log(codeString); - self.log('args'); - self.log(args); - return false */ - return code; - } - //} - }; - - /* this.compile = function (obj, args) { - // functions e addTag potrebbero essere eseguiti da una stessa funzione - // in reatà addTag è la funzione che andrebbe lanciata quando la chiave - // dell'azione è tra i tag html - - if (obj !== undefined) { - var result; - if (typeof obj == 'object') - result = self.actionResult(obj, args); - result = self.replaceProperties(obj, args); - if (result == 'undefined') - return undefined; - else if (typeof result == 'object') // Array is also an object type - return self.do(result, args); - else if (typeof result == 'function') - return result(args); - else { - return result; - } - } else { - return undefined; - } - } */ - this.if = function (params, selectorParams, args) { - - // add array - if (typeof params == 'object') { - - var conditionString = 'if'; - var condition; - - if (params.is !== undefined) { - if (typeof params.is == 'string') { - let isReplaced = self.replaceProperties(params.is, args, true); - self.log(isReplaced, 'grey'); - try { - condition = Boolean(eval(isReplaced)); // remove undefined values - self.log(isReplaced + ' is ' + condition, 'grey'); - } catch (error) { - self.log(isReplaced, 'red'); - self.log('"if" condition wrong', 'red'); - self.log(error, 'red'); - } - conditionString += ' is ' + params.is; - } else if (Array.isArray(params.is)) { - let i = 0; - params.is[i]; - switch (params.is[i + 1]) { - case '=': condition = Boolean(eval(params.is[i] + '===' + params.is[i + 2])); break; - } - } - } else if (params.not !== undefined) { - condition = (!Boolean(eval(self.replaceProperties(params.not, args, true)))); // remove undefined values - if (typeof params.not == 'string') conditionString += ' not ' + params.not; - } else if (params.regexp) { - const regex = new RegExp(params.regexp); - condition = Boolean(regex.test(params.string)); - } else if (params.isArray) { - condition = self.isArray(params.isArray); - conditionString += 'isArray ' + params.isArray; - } else if (params.exist) { - let elementExist = self.element({ path: params.exist }); - condition = (elementExist); - self.log('"if" exist ' + params.exist, 'grey'); - } else if (params.value && params.in) { - //let arr = self.replaceProperties(params.in, args, true); - //condition = (arr.indexOf(self.replaceProperties(params.value)) >= 0); - condition = self.valueInJson(self.replaceProperties(params.in, args, true), self.replaceProperties(params.value)); - - self.log('"if" value ' + self.replaceProperties(params.value) + ' in array is ' + condition, 'grey'); - } else if (params.key && params.in) { - condition = self.keyInJson(self.replaceProperties(params.in, args, true), self.replaceProperties(params.key)); - self.log('"if" key ' + self.replaceProperties(params.key) + ' in object is ' + condition, 'grey'); - } else { - let selector = self.selector(params.selector || params.container, undefined) || self.selector(selectorParams, undefined); - //var selector = self.selector(params.selector || params.container, selectorParams); - if (selector) { - if (params.exist) { - //var element = self.query(params.exist); - //condition = Boolean(self.query(selector)); - condition = Boolean(self.exist(selector)); - conditionString += ' ' + selector + ' exist ' + params.exist; - } - if (params.hasClass) { // to be reviewed (self.hasClass need 1 parameter) - var element = self.query(selector); - condition = Boolean(self.hasClass(element, params.hasClass)); - conditionString += ' ' + selector + ' hasClass ' + params.hasClass; - } - if (params.isVisible) { - var element = self.query(selector); - condition = Boolean(self.isVisible(element, params.isVisible)); - conditionString += ' ' + selector + ' isVisible'; - } - if (params.isHidden) { - var element = self.query(selector); - condition = Boolean(self.isHidden(element, params.isHidden)); - conditionString += ' ' + selector + ' isHidden'; - } - if (params.inViewport) { - var element = self.query(selector); - condition = Boolean(self.inViewport(element, params.inViewport)); - conditionString += ' ' + selector + ' inViewport'; - } - if (params.outViewport) { - var element = self.query(selector); - condition = Boolean(self.outViewport(element, params.outViewport)); - conditionString += ' ' + selector + ' outViewport'; - } - if (params.isDisplay) { - var element = self.query(selector); - /* self.log('element'); - self.log(element); */ - condition = Boolean(self.isDisplay(element, params.isDisplay)); - conditionString += ' ' + selector + ' isDisplay ' + params.isDisplay; - } - } else { - self.log('the "if" function requires "is" or "not" parameter'); - } - } - - /* conditionString += ': ' + condition; - self.log(condition, 'grey'); */ - if (condition) - if (params.then) { - // self.console dovrebbe diventare così - if (typeof params.then == 'object') { - return self.do(params.then); - //return self.do(params.then); - } if (typeof params.then == 'string') { - return self.replaceProperties(params.then); - } else { - return params.then; - } - - } - else - self.log('the "if" function requires "then" parameter'); - else if (params.else) { - if (typeof params.else == 'object') { - return self.do(params.else); - //return self.do(params.else); - } if (typeof params.else == 'string') { - return self.replaceProperties(params.else); - } else { - return params.else; - } - } - } else { - //self.log(Boolean(params) && params !== 'false'); - return Boolean(self.js(params, args)); // 0.9.7 - - //return Boolean(eval(self.replaceProperties(params, args))) // need try - } - }; - - this.switch = function (params, args) { - //self.log('switch'); - //self.log(params); - var value; - var answer; - if (params.expression) - value = String(self.js(params.expression, args)); - - else - self.log('"switch" function requires "expression" parameter'); - //self.log(value); - if (params.cases) { - //self.log('params.cases[value]'); - //self.log(params.cases[value]); - if (value !== undefined && params.cases[value]) { - if (typeof params.cases[value] == 'object') - answer = self.do(params.cases[value], undefined, args); - - - //answer = self.do(params.cases[value], args); - else - answer = params.cases[value]; - - } else if (params.cases['default']) { - self.log('default'); - self.log(params.cases['default']); - if (typeof params.cases['default'] == 'object') - answer = self.do(params.cases['default'], undefined, args); - - - //answer = self.do(params.cases['default'], args); - else - answer = params.cases['default']; - } - } else { - self.log('"switch" function requires "cases" parameter'); - self.log('answer'); - self.log(answer); - } - return answer; - }; - - - /* - this.varAction = this.set = function (params, args) { - // {name, value, operator} - - var value; - var operator = params.operator; - - //self.log('operator'); - //self.log(operator); - - if (operator && args) operator = self.replaceProperties(operator, args); - - - //self.log('operator'); - //self.log(operator); - - if (params.value !== undefined) { // set - value = self.js(params.value, args); - if (params.var) { - self.docElement('self.json.var.'+params.var, value); - } else if (params.name) { - var actualValue = self.docElement('self.json.var.'+params.name); - if (actualValue == undefined && typeof value == 'string') actualValue = ''; - if (actualValue == undefined && typeof value == 'number') actualValue = 0; - if (actualValue == undefined && typeof value == 'object') actualValue = {}; - if (operator) { - - if (operator == '+=') actualValue += value; - if (operator == '-=') actualValue -= value; - if (operator == '/=') actualValue /= value; - if (operator == '*=') actualValue *= value; - value = actualValue; - } - self.docElement('self.json.var.'+params.name, value); - //self.log('self.json.var[params.name]'); - //self.log(self.json.var[params.name]); - } else { - self.log('set command requires "var" parameter'); - } - } else { // get - if (params.var) { - return self.docElement('self.json.var.'+params.var); - } else if (params.name) { - return self.docElement('self.json.var.'+params.name); - } else { - self.log('set command requires "value" parameter'); - } - } - //self.log('value'); - //self.log(value); - self.log('var ' + params.name + ' = ' + value); - - } */ - this.delay = function (params, selector, args) { - self.log('delay'); - self.log('selector'); - self.log(selector); - var duration = params.duration || 1000; - duration = Number(self.replaceProperties(duration, args)); - self.log(duration); - if (params.do) { - setTimeout(function () { - self.do(params.do, selector, args); - //self.do(params.do, args, container) - }, duration); - } - }; - - this.firebasePasswordReset = function (paramEmail, paramSuccess, paramError) { - //firebase.auth().languageCode = 'it'; - firebase.auth().useDeviceLanguage(); - auth.sendPasswordResetEmail(paramEmail).then(function () { - // Email sent. - if (paramSuccess) self.do(paramSuccess); - //if (paramSuccess) self.do(paramSuccess); - }).catch(function (error) { - // An error happened. - if (paramError) self.do(paramError, undefined, error.message); - //if (paramError) self.do(paramError, error.message); - }); - }; - - this.firebaseUpdateProfile = function (params, paramSuccess, paramError) { - self.log('firebaseUpdateProfile'); - self.log(params); - auth.currentUser.updateProfile(params).then(function () { - // Update successful. - self.log('User Profile Updated Successfully'); - if (paramSuccess) self.do(paramSuccess); - //if (paramSuccess) self.do(paramSuccess); - }).catch(function (error) { - // An error happened. - if (paramError) self.do(paramError, undefined, error.message); - //if (paramError) self.do(paramError, error.message); - }); - }; - - this.firebaseRegister = function (params, success, error) { - if (params.email && params.password) { - // log the user in - auth.createUserWithEmailAndPassword(params.email, params.password).then(cred => { - self.log(cred.user); - //var.auth.cred = cred; - var user = firebase.auth().currentUser; - /* if (user.emailVerified) { - } else { - self.sendEmailVerification(params); - } */ - //if (params.success) self.do(params.success); - if (params.success) self.do(params.success); - }).catch(error => { - // Handle Errors here. - //if (params.error) self.do(params.error, error.message); - if (params.error) self.do(params.error, undefined, error.message); - }); - } - }; - - this.firebaseLogin = function (params) { - self.log('firebaseLogin'); - self.log(params); - - if (auth) { - auth.signInWithEmailAndPassword(String(params.email), String(params.password)).then(cred => { - //var.auth.cred = cred; - var user = firebase.auth().currentUser; - //firebase.auth().languageCode = 'it'; - if (user.emailVerified) { - if (params.success) self.do(self.replaceResult(params, undefined, cred)); - //if (params.success) self.do(self.replaceResult(params, cred)); - } else { - self.sendEmailVerification(params); - } - }).catch(error => { - self.log('error.code'); - self.log(error.code); - if (params.error) self.do(self.replaceResult(params, undefined, error.message)); - //if (params.error) self.do(self.replaceResult(params, error.message)); - }); - } else { - // firebase auth non inizializzato - } - }; - - this.firebaseLogout = function (params) { - self.log('firebaseLogout'); - firebase.auth().signOut().then(function () { - self.log('firebaseLogout SUCCESS'); - self.log(params.success); - if (params.success) { - //app.stopMeeting(); - localStorage.clear(); - //self.do(params.success); - self.do(params.success); - } - }).catch(function (error) { - self.log('firebaseLogout ERROR'); - self.log(error); - //if (params.error) self.do(params.error); - if (params.error) self.do(params.error); - }); - }; - - // this.firebaseUserVerify = function (params) { - // self.log('firebaseUserVerify'); - // self.log(params); - // self.log(params.oobCode); - // if (params.oobCode) self.params.codeMail = params.oobCode - // self.log(self.params.codeMail); - // //self.do(data); - // // inviare mail di verifica - // } - this.sendEmailVerification = function (params) { - self.log('sendEmailVerification'); - var user = firebase.auth().currentUser; - firebase.auth().languageCode = 'it'; - var successAction = params.success || self.reload; - user.sendEmailVerification().then(function () { - firebase.auth().signOut(); - self.alert({ - //toast: true, - icon: "success", - title: "verifyingemail", // all\'indirizzo "+params.email+" - html: "msgverifyingemail", - //confirmButtonText: "Ok", - //showCancelButton: false, - showConfirmButton: false, - confirm: successAction - }); - - }); - }; - - /* //self.log('function'); - params = self.replaceProperties(params, args); // -> compile - - if (typeof params == 'object') { - // jsonic function - //return self.do(params, args); - return self.do(params, args); - } else if (typeof params == 'function') { - // javascript function - return params(args); - } else if (typeof params == 'string') { - if (json.actions[params]) { - var functionCompiled = self.replaceResult(json.actions[params], args); // replace {result} - //functionCompiled = self.replaceProperties(functionCompiled, args); - // jsonic predefined function - //return self.do(functionCompiled); - return self.do(functionCompiled); - //return self.actionResult(json.actions[params], args); - } else { - // javascript function name - var functionName = self.docElement(params); - if (functionName) - if (typeof functionName == 'function') { - // javascript function - return functionName(args) - } else { - // javascript object - return functionName; - } - else - self.log('function undefined: '+ params); - } - } */ - this.path = function (pathParams, args, separatorParam) { - var pathString = ''; - var separator = separatorParam || '/'; - - /* self.log('this.path'); - self.log(pathParams); - self.log(args); */ - if (typeof pathParams == 'string') { - pathString = self.replaceProperties(pathParams, args); - } else { - for (var index in pathParams) { - pathObj = pathParams[index]; - if (pathString !== '') pathString += separator; - if (pathObj.string) - pathString += String(pathObj.string); - else if (pathObj.number) - pathString += Number(pathObj.number); - else if (pathObj.function) - pathString += self.doFunctionByName(pathObj.function, window, ''); - } - } - return pathString; - }; - - - this.executeFunctionByName = function (functionName, context /*, arguments */) { - //self.log('executeFunctionByName'); - //self.log(functionName); - if (functionName) { - var args = [].slice.call(arguments).splice(2); - var namespaces = functionName.split("."); - var func = namespaces.pop(); - for (var i = 0; i < namespaces.length; i++) { - context = context[namespaces[i]]; - } - if (context[func] !== undefined) { - return context[func].apply(context, args); - } else { - //self.log('Error: executeFunctionByName'); - //if (functionName !== undefined) {self.log('functionName:'+functionName);} - } - } else { - self.log('executeFunctionByName'); - self.log('functionName undefined'); - } - - }; - - this.functions = {}; - - this.methods = { - // main methods - run: function (params, container, args) { self.run(params, container, args); }, - delay: function (params, container, args) { self.delay(params, container, args); }, - ajax: function (params, container, args) { self.ajax(params, container, args); }, - do: function (params, container, args) { self.do(params, container, args); }, - module: function (params, container, args) { self.module(params, args); }, - js: function (params, container, args) { self.js(params, args); }, - function: function (params, container, args) { self.function(params, args); }, - dispatchEvent: function (params, container, args) { self.dispatchEvent(params, args); }, - - // TO DO: check - lang: function (params, container, args) { self.lang(params, args); }, - find: function (params, container, args) { self.find(params, args); }, - page: function (params, container, args) { self.page(params, args); }, - - // DA VERIFICARE - //dayjs: function (params, args) {self.dayjs(params, args)}, - //moment: function (params, args) {self.moment(params, args)}, - //data: function (params, args) {self.data(params, args)}, - //var: function (params, args) {self.var(params, args)}, - //javascript: function (params, args) {self.javascript(params, args)}, - //color: function (params, args) {self.color(params, args)}, - //select: function (params, args) {self.select(params, args)}, - // LOGIC & DATA - for: function (params, container, args) { self.for(params, container, args); }, - if: function (params, container, args) { self.if(params, container, args); }, - switch: function (params, container, args) { self.switch(params, args); }, - set: function (params, container, args) { self.set(params, args); }, - - // TO DO: check is needs to be renamed to avoid confusion with self.json.data - data: { - set: function (params, args) { - for (var param in params) { - - var value = params[param]; - - if (value) value = self.replaceProperties(value, args); - if (value && args) value = self.replacePropertyWithPrefix(value, 'result', args); // backward compatibility TO DO: remove - - self.element({ path: param, value: value }); - } - }, - get: function (params) { - return self.element(params); - }, - delete: function (params, args) { - var path = self.replaceProperties(params, args); - alert(path); - self.objToDelete = self.element({ path: path }); - delete self.objToDelete; - }, - add: function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || ''; - obj += String(value); - self.element({ path: path, value: obj }); - } - } - }, - sum: function (params, args) { - console.log('%cdeprecated key "sum". Use set{x: "{x}+1"}', 'color:orange'); - console.log(params); - console.log(args); - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj += Number(value); - self.element({ path: path, value: obj }); - } - } - }, - sub: function (params, args) { - console.log('%cdeprecated key "sub". Use set{x: "{x}+1"}', 'color:orange'); - console.log(params); - console.log(args); - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj -= Number(value); - self.element({ path: path, value: obj }); - } - } - }, - push: function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.push(value); - self.element({ path: path, value: obj }); - } - } - } - }, - - // DOM - text: function (params, container, args) { self.text(params, container, args); }, // TO DO: -> html - html: function (params, container, args) { self.html(params, container, args); }, - attr: function (params, container, args) { self.attr(params, container, args); }, - empty: function (params, container, args) { self.empty(params, args); }, - delete: function (params, args) { - var path = self.replaceProperties(params, args); - - var obj = self.element({ path: path }); - self.log(JSON.stringify(obj)); - self.element({ path: path, delete: true }); - // NOTE: obj = self.element non prende l'oggetto effettivo. quindi element deve contenere tutte le funzioni - //self.element({path: path, delete: true}); - self.log(obj); - }, - add: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - /* self.log('value'); - self.log(value); */ - if (value) { - var obj = self.element({ path: path }) || ''; - obj += String(value); - self.element({ path: path, value: obj }); - } - } - }, - sum: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj += Number(value); - self.element({ path: path, value: obj }); - } - } - }, - sub: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj -= Number(value); - self.element({ path: path, value: obj }); - } - } - }, - push: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.push(value); - self.element({ path: path, value: obj }); - self.log('push obj'); - self.log(obj); - } - } - }, - - // should go in utils.json - calendar: function (params, container, args) { self.calendar(params, args); }, // to check - array: function (params, container, args) { self.array(params, args); }, - replace: function (params, container, args) { self.replace(params, args); }, - shuffle: function (array) { - let currentIndex = array.length, randomIndex; - // While there remain elements to shuffle. - while (currentIndex != 0) { - // Pick a remaining element. - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex--; - // And swap it with the current element. - [array[currentIndex], array[randomIndex]] = [ - array[randomIndex], array[currentIndex] - ]; - } - return array; - }, - - // should go in ui.json (or ux) module - alert: function (params, container, args) { self.alert(params, args); }, // change in swal2 - offcanvas: function (params, container, args) { self.offcanvas(params, args); }, // bootstrap / obsolete - - //in: function (params, container, args) {self.in(params, container, args)}, // bootstrap TO DO: replace in code with ui:in - out: function (params, container, args) { self.out(params, container, args); }, // bootstrap TO DO: replace in code with ui:out - qrcode: function (params, container, args) { self.qrcode(params, container, args); }, // obsolete TO DO: replace in code with ui:qrcode - hide: function (params, container, args) { self.hide(params, container, args); }, // TO DO: replace in code with ui:hide - show: function (params, container, args) { self.show(params, container, args); }, // TO DO: replace in code with ui:show - toggle: function (params, container, args) { self.toggle(params, container, args); }, // TO DO: replace in code with ui:toggle - sortablejs: function (params, container, args) { self.sortablejs(params, args); }, // TO DO: replace in code with ui:sortable - lottie: function (params, container, args) { self.lottie(params, container, args); }, // TO DO: replace in code with ui:lottie - chart: function (params, container, args) { - var selector = self.selector(container); - var element = self.query(selector); - element.innerHTML = ''; - const ctx = element.querySelector('canvas'); - const myChart = new Chart(ctx, self.replaceProperties(params)); - }, - - animate: function (params, container, args) { self.animate(params, container, args); }, - //editor: function (params, container, args) {self.editor(params, container, args)}, // quill - // window.dispatchEvent(new Event('resize')); // workaround known ACE bug - uiUpdate: function (params, container, args) { self.uiUpdate(params, args); }, - swiper: { - data: {}, - init: function (params, selector, args) { - //swiperConfig.on = {}; - setTimeout(function () { - // waits the plugin... TO DO: add this function to a promise - console.log('swiper inited'); - console.log(selector || params.selector); - console.log(params.options); - var swiperConfig = params.options; - self.methods.swiper.data[params.name] = new Swiper(self.selector(selector || params.selector), swiperConfig); - console.log(self.methods.swiper.data[params.name]); - }, 1000); - } - }, - - // should go in browser.json module - //export: function (params, container, args) {self.export(params, container, args)}, -> browser - //console: function (params, container, args) {self.console(params, args)}, // obsolete, changed in log - link: function (params, container, args) { self.link(params, args); }, - scroll: function (params, container, args) { self.scroll(params, args); }, - reload: function (params, container, args) { self.reload(params, args); }, - timer: function (params, container, args) { self.timer(params, args); }, - setInterval: function (params, container, args) { self.setInterval(params, args); }, - clearInterval: function (params, container, args) { self.clearInterval(params, args); }, - setTimeout: function (params, container, args) { self.setTimeout(params, args); }, - clearTimeout: function (params, container, args) { self.clearTimeout(params, args); }, - local: { - set: function (params) { - for (var param in params) { - var value = params[param]; - if (value) value = self.replaceProperties(value); - if (typeof value == 'object') value = JSON.stringify(value); - localStorage.setItem(param, value); - } - }, - get: function (key) { - var localValue = localStorage.getItem(key); - if (localValue && self.isJsonString(localValue)) - localValue = JSON.parse(localValue); - return localValue; - }, - remove: function (key) { - localStorage.removeItem(key); - }, - clear: function () { - localStorage.clear(); - } - }, - storage: { - _storage: new WeakMap(), - set: function (element, key, obj) { - if (!self.methods.storage._storage.has(element)) { - self.methods.storage._storage.set(element, new Map()); - } - self.methods.storage._storage.get(element).set(key, obj); - }, - get: function (element, key) { - return self.methods.storage._storage.get(element).get(key); - }, - has: function (element, key) { - return self.methods.storage._storage.has(element) && self.methods.storage._storage.get(element).has(key); - }, - remove: function (element, key) { - var ret = self.methods.storage._storage.get(element).delete(key); - if (!self.methods.storage._storage.get(element).size === 0) { - self.methods.storage._storage.delete(element); - } - return ret; - } - }, - - choose: function (params, container, args) { self.choose(params, container, args); }, - remove: function (params, container, args) { self.remove(params, container, args); }, - part: function (params, container, args) { self.part(params, container, args); }, - blocks: function (params, container, args) { self.part(params, container, args); }, // obsolete - block: function (params, container, args) { self.part(params, container, args); }, - ace: function (params, container, args) { self.ace(params, container, args); }, - code: function (params, container, args) { self.code(params, container, args); }, - - // should go in firebase.json module - database: function (params, container, args) { self.database(params, args); }, // obsolete (check) - firebase: function (params, container, args) { self.firebase(params, args); }, - - firebaseEvent: { - action: function (newObj) { - /* self.logdbRef('firebaseEvent.action'); - self.log('newObj'); - self.log(newObj); */ - /* var path = newObj.path; - delete newObj.path; - var pathString = 'self.json.var.db.' + self.replaceAll(path, '/', '.'); - self.log('pathString:'+pathString); - var dbObj = self.docElement(pathString); - dbObj = newObj; // update local db */ - var path = newObj.path; - delete newObj.path; - //alert(path); - document.querySelectorAll('[data-firebase="' + path + '"]').forEach(function (element, index) { - //$('[data-firebase="'+path+'"]').each(function (index) { - // var element = this; - var pathString = 'self.json.var.db.' + self.replaceAll(element.getAttribute('data-firebase'), '/', '.'); // data('firebase') - var dbObj = self.docElement(pathString); - - var firebaseValue = newObj[element.getAttribute('data-value')]; // TODO: not works for nested nodes - - //var template = element.getAttribute('data-template'); - var template = self.dataStorage.get(element, 'data-template'); - - //if ($(element).is('ul')) { - if (element.tagName == 'UL') { // se $(this) è un ul - - //var dbObj = self.docElement(pathString); - // se il percorso ha più nodi e il dato non è presente nel db locale, - // va creato un oggetto vuoto per ogni nodo - //var context = element.getAttribute('data-firebase'); - //self.var.db[context] = newObj; // update local db - var liTemplate = template.li || template.template; // template.li retro-compatibility - - - - - - - - /* self.log('liTemplate'); - self.log(liTemplate); - self.log('newObj'); - self.log(newObj); */ - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - - /* if (params.li.class == "deviceItem d-flex flex-wrap align-items-center list-group-item list-group-item-action d-flex align-items-center justify-content-between") { - alert(JSON.stringify(params.li)); - } */ - //if (dbPath == 'lessons') - //prompt(JSON.stringify(liTemplate)); - // TO DO: replace with replaceProperty - var dbParams = self.replaceItems(liTemplate, item, 'item') || ''; - - // var dbParams = self.replaceProperties(liTemplate, undefined, item) || ''; - // -> TO DO container = self.elementToSelector(element); - var container = element.getAttribute('data-selector'); - - self.li(dbParams, { selector: container }); - } - - //} else if ( $(element).is('span') || $(element).is('p')) { - } else if (element.tagName == 'SPAN' || element.tagName == 'P') { - - //$(element).text(firebaseValue); - element.textContent = firebaseValue; - - } else if (element.tagName == 'SVG') { - // TODO without JQUERY - //$(element).children('text').text(firebaseValue); - } else { // se $(this) non è un ul - - //var dbObj = self.docElement(pathString); - // se il percorso ha più nodi e il dato non è presente nel db locale, - // va creato un oggetto vuoto per ogni nodo - //var context = element.getAttribute('data-firebase'); - //self.var.db[context] = newObj; // update local db - if (template.blocks || template.html) { - var blocksTemplate = template.html || template.blocks; - - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - self.log('newObj'); - self.log(newObj); - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - var dbParams = self.replaceProperties(blocksTemplate, undefined, item) || ''; - /* self.log('container'); - self.log(container); - self.log('dbParams'); - self.log(dbParams); */ - self.html(dbParams, { selector: container }); - } - } - - if (template.init) self.do(template.init); //self.do(template.init); - - } - - - }); - } - }, - - auth: { - init: function (params, container, args) { - self.log("auth init"); - auth = firebase.auth(); - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - // No user logged in - self.log('authStateChanged: GUEST\n'); - // non bisognerebbe chiedere sempre di fare login - } else { - // User logged in - self.log('authStateChanged: USER\n'); - self.log('name: ' + self.user('displayName') + '\nemail: ' + user.email + '\nuid:' + user.uid); - //self.log('email verificata'); - //self.log(self.userVerified()); - } - /* self.log('params'); - self.log(params); */ - //self.do(params.onAuthStateChanged); - self.do(params.onAuthStateChanged); - - //if (!firebaseInitialized) { - // firebaseInitialized = true; - //self.do(data); - //} - }); - }, - - sendEmailVerification: function (params, container, args) { - self.sendEmailVerification(params); - }, - - login: function (params, container, args) { - self.log('params.auth'); - self.log(params.auth); // QUESTO E' {var:auth} MA SEMBRA NON RIMPIAZZARLO - self.log(args); // QUI MI RIPORTA LA PWD, ma perché ultimo args - var fba = self.replaceProperties(params.auth, args); - self.log('fba'); - self.log(fba); - var fbAuth = self.cloneObject(fba); - self.log('fbAuth'); - self.log(fbAuth); - if (params.success) fbAuth.success = params.success; - if (params.error) fbAuth.error = params.error; - self.firebaseLogin(fbAuth, params.success, params.error); - }, - - register: function (params, container, args) { - //var fbAuth = self.replaceTags({text: params.auth, args: args}); - //var fbAuth = self.replaceResult(params.auth, args); - var fbAuth = self.replaceProperties(params.auth, args); - fbAuth.success = params.success; - fbAuth.error = params.error; - //alert(JSON.stringify(fbAuth)) - self.firebaseRegister(fbAuth, params.success, params.error); - }, - - updateProfile: function (params, container, args) { - //params.profile = self.replaceTags({text: params.profile, args: args}); - //params.profile = self.replaceResult(params.profile, args); - params.profile = self.replaceProperties(params.profile, args); - self.firebaseUpdateProfile(params.profile, params.success, params.error); - }, - - passwordReset: function (params, container, args) { - //params.email = self.replaceTags({text: params.email, args: args}); - //params.email = self.replaceResult(params.email, args); - params.email = self.replaceProperties(params.email, args); - self.firebasePasswordReset(params.email, params.success, params.error); - }, - - logout: function (params, container, args) { - self.firebaseLogout(params); - } - }, - - // should go in mobile.json module - thunkable: function (params, container, args) { self.thunkable(params, args); }, - - // should go in 3d.json module - modelViewer: { - events: {}, - on: function (params) { - let container = self.selector(params.selector || params.container); - let element = self.query(container); - self.log('modelViewer on'); - self.log('container'); - self.log(container); - self.log('element'); - self.log(element); - if (element) { - self.methods.modelViewer.events[container] = {}; // use self.element - - - //let events = ['load', 'preload']; - //for (var event in events) { - var event = 'load'; - if (params[event]) { - //self.element({root: 'self.methods.modelViewer.events', path: container+'.'+event, value: params[event]}) - self.methods.modelViewer.events[container][event] = params[event]; - self.log('modelViewer element'); - self.log(element); - element.addEventListener(event, (e) => { - self.log('modelViewer event'); - self.log(e); - let container = e.path[0].getAttribute('data-selector'); - self.log(container); - //self.do(self.methods.modelViewer.events[container][e.type]); - self.do(self.methods.modelViewer.events[container][e.type]); - }); - } - } - }, - set: function (params) { - let element = self.query(self.selector(params.selector || params.container)); - if (element) { - if (params.color) { - let color = params.color.split(',').map(numberString => parseFloat(numberString)); - self.log('Changing color to: ', color); - const [material] = element.model.materials; - material.pbrMetallicRoughness.setBaseColorFactor(color); - } - if (params.exposure) element.exposure = params.exposure; - if (params.shadow) element.shadowIntensity = params.shadow; - if (params.orientation) element.orientation = params.orientation; - - } - } - } - }; - - - this.googleSignInPopup = function () { - self.log('googleSignInPopup'); - var provider = new firebase.auth.GoogleAuthProvider(); - - firebase.auth().useDeviceLanguage(); // lingua del dispositivo - - firebase.auth() - .signInWithPopup(provider) - .then((result) => { - // @type {firebase.auth.OAuthCredential} - var credential = result.credential; - // This gives you a Google Access Token. You can use it to access the Google API. - var token = credential.accessToken; - // The signed-in user info. - var user = result.user; - window.location.reload(); - // ... - }).catch((error) => { - // Handle Errors here. - var errorCode = error.code; - var errorMessage = error.message; - // The email of the user's account used. - var email = error.email; - // The firebase.auth.AuthCredential type that was used. - var credential = error.credential; - }); - }; - - - /* this.googleSignInPopup = function () { - // [START auth_google_signin_popup] - self.log('googleSignInPopup'); - var provider = new firebase.auth.GoogleAuthProvider(); - //provider.addScope('https://www.googleapis.com/auth/contacts.readonly'); //check security - //provider.addScope('https://www.googleapis.com/auth/calendar'); - //var languageApp = jsonic.var.language || 'en'; - //firebase.auth().languageCode = 'it';//languageApp; - //self.log(provider); - //return; - firebase.auth() - .signInWithPopup(provider) - .then((result) => { - // @type {firebase.auth.OAuthCredential} - var credential = result.credential; - // This gives you a Google Access Token. You can use it to access the Google API. - var token = credential.accessToken; - // The signed-in user info. - var user = result.user; - //######### result ########// - self.log("credential"); - self.log(credential); - self.log("token"); - self.log(token); - self.log("user"); - self.log(user); - window.location.reload(); - // ... - }).catch((error) => { - // Handle Errors here. - var errorCode = error.code; - self.log('errorCode'); - self.log(errorCode); - var errorMessage = error.message; - self.log('errorMessage'); - self.log(errorMessage); - // The email of the user's account used. - var email = error.email; - self.log('email'); - self.log(email); - // The firebase.auth.AuthCredential type that was used. - var credential = error.credential; - self.log('credential'); - self.log(credential); - // ... - }); - // [END auth_google_signin_popup] - } */ - /* this.auth = function (params, args) { - self.log('auth'); - self.log(params); - if (params.do == 'init') { - auth = firebase.auth(); - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - // No user logged in - self.log('authStateChanged: GUEST\n'); - // non bisognerebbe chiedere sempre di fare login - } else { - // User logged in - self.log('authStateChanged: USER\n'); - self.log('name: '+self.user('displayName') + '\nemail: '+user.email + '\nuid:'+ user.uid); - //self.log('email verificata'); - //self.log(self.userVerified()); - } - - //self.log('params.onAuthStateChanged'); - //self.log(params.onAuthStateChanged); - - self.do(params.onAuthStateChanged); - - //if (!firebaseInitialized) { - // firebaseInitialized = true; - //self.do(data); - //} - }); - } else if (params.do == 'sendEmailVerification') { - - self.sendEmailVerification(params); - - } else if (params.do == 'login') { - - self.log('params.auth'); - self.log(params.auth); - var fba = self.replaceProperties(params.auth, args); - self.log('fba'); - self.log(fba); - var fbAuth = self.cloneObject(fba); - self.log('fbAuth'); - self.log(fbAuth); - if (params.success) fbAuth.success = params.success; - if (params.error) fbAuth.error = params.error; - self.firebaseLogin(fbAuth, params.success, params.error); - - } else if (params.do == 'register') { - - //var fbAuth = self.replaceTags({text: params.auth, args: args}); - //var fbAuth = self.replaceResult(params.auth, args); - var fbAuth = self.replaceProperties(params.auth, args); - - fbAuth.success = params.success; - fbAuth.error = params.error; - //alert(JSON.stringify(fbAuth)) - self.firebaseRegister(fbAuth, params.success, params.error); - - } else if (params.do == 'updateProfile') { - - //params.profile = self.replaceTags({text: params.profile, args: args}); - //params.profile = self.replaceResult(params.profile, args); - params.profile = self.replaceProperties(params.profile, args); - self.firebaseUpdateProfile(params.profile, params.success, params.error); - - } else if (params.do == 'passwordReset') { - - //params.email = self.replaceTags({text: params.email, args: args}); - //params.email = self.replaceResult(params.email, args); - params.email = self.replaceProperties(params.email, args); - self.firebasePasswordReset(params.email, params.success, params.error); - - } else if (params.do == 'logout') { - - self.firebaseLogout(params); - } - // else - //self.database(params, args); - - } - */ - /* this.db = function (params, args) { - if (typeof params == 'string') - return self.db(params, args); - else - self.firebase(params, args); - } */ - this.console = function (params, args) { - - //value = self.replaceProperties(params); - //console.log('JSONIC: '+value, 'color:pink'); - if (typeof params.log == 'string' && params.color) { - var color = params.color || 'white'; - console.log('%c' + self.replaceProperties(params.log), 'color:' + color); - } else { - console.log(self.replaceProperties(params.log || params)); - } - }; - - this.module = function (params, args) { - if (typeof params == 'string') { - var nameReplaced = self.replaceProperties(params, args); - return self.element({ root: self.modules, path: nameReplaced }); - } else { - if (params.name) { - if (params.value) { - var name = self.replaceProperties(params.name, args); - //var value = self.actionResult(params.value, args); - var value = self.replaceProperties(value, args); - self.log('module'); - self.log(name); - self.log('value'); - self.log(value); - self.log(value.app.html.div.div[0].text.lang.en); - self.modules[name] = value; - } else if (params.url) { - self.addModule(params); // TO DO: return? - } - } - } - }; - - this.db = function (params, args) { - self.log('db'); - if (typeof params == 'string') { - var paramsReplaced = self.replaceProperties(params, args); - self.log('paramsReplaced'); - self.log(paramsReplaced); - self.log(self.var('db.' + paramsReplaced, args)); - //var varValue = self.docElement('self.json.var.db.'+name); - return self.var('db.' + paramsReplaced, args); // to do: change with self.element({path: 'db.'+paramsReplaced}}) - - - - - - - - - - /* - // questa versione non funzionava. vuol dire che this.var ha un errore nel caso di oggetto - return self.var({ - name: 'db.'+paramsReplaced - }, args); - - */ - } /* else { - return self.actionResult(params, args); - } */ - - - }; - - this.firebase = function (params, args) { - if (params.initializeApp) { - var firebaseConfig = self.replaceProperties(params.initializeApp); - firebase.initializeApp(firebaseConfig); - } else { - self.database(params, args); - } - }; - - this.database = function (params, args) { - //console.log('database'); - - if (params.do == 'init') { - database = firebase.database(); - self.log('database'); - self.log(database); - } else { - if (database) { - - if (typeof params == 'string') { - - return self.db(params, args); // local db - - } else { - - if (params) { - if (params.path) { - params.path = self.path(params.path, args); - } - /* console.log('params.path'); - console.log(params.path); */ - /* if (params.value) - params.value = params.value; */ //self.value({string: params.value}); - if (params.value) { - - /* self.log("params.value pre replace"); - self.log(params.value); */ - //params.value = self.replaceTags({text: params.value, args: args}); - //params.value = self.replaceResult(params.value, args); - //params.value = self.replaceProperties(params.value, args); - //params.value = self.actionResult(params.value, args); - params.value = self.replaceProperties(params.value, args); - - self.log("params.value post replace"); - self.log(params.value); - } - - - /* self.log('params to FIREBASE'); - self.log(params); */ - // params.value = "${var.newDevice}" - //var newDevice = `${params.value}`; - //var newDevice = `${var.newDevice}`; - if (params.do == 'init') { - } else if (params.do == 'increase') { - - self.firebaseIncrease(params); - - } else if (params.do == 'get') { - - self.firebaseGet(params.path, function (result) { - if (result.success) { - if (result.data) { - self.log('firebase get SUCCESS'); - self.log(params.success); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - } else { - self.log('firebase get no result.data ERROR'); - //if (params.on && params.on.error) self.do(params.on.error); - if (params.on && params.on.error) self.do(params.on.error); - } - } else { - self.log('firebase get ERROR'); - //if (params.on && params.on.error) self.do(params.on.error, result); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - // alert errore di connessione. alert riprova - } - }); - } else if (params.do == 'new' && params.value) { - var newKey = self.getKey(params.path); - self.firebaseSet(params.path + '/' + newKey, params.value, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } else if (params.do == 'remove' && params.path) { - self.firebaseRemove(params.path, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - //if (params.on && params.on.success) self.do(params.on.success, result); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - // alert errore di connessione. alert riprova - } - }); - } else if (params.do == 'addListener') { - self.firebaseAddListener(params); - } else if (params.do == 'removeListener') { - self.firebaseRemoveListener(params); - } else if (params.do == 'update') { - if (params.value) { // 'set' is the default action with 'value' param - self.firebaseUpdate(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase update SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - } else { - self.log('firebase update ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } else { - self.log('data update requires value param'); - } - } else if (params.do == 'push') { - if (params.value) { // 'set' is the default action with 'value' param - self.firebasePush(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase push SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success,result); - } else { - self.log('firebase push ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } else { - self.log('data push requires value param'); - } - } else { - if (params.value) { // 'set' is the default action with 'value' param - self.firebaseSet(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success,result); - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } - } - - - } - } - } else { - self.log('"database" function needs to be initialised'); - } - } - }; - - this.ajax = function (params, selectorParams, args) { - /* self.log('ajax'); - // TO DO: selectorParams - self.log('ajax'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - if (params.url) { - //var url = self.compile(params.url, args); - var url = self.replaceProperties(params.url, args); - var data; - if (params.data) - data = JSON.stringify(self.replaceProperties(params.data, args)); - //data = JSON.stringify(self.compile(params.data, args)); - /* self.log('data'); - self.log(data); */ - var type = params.type || 'POST'; - var request = new XMLHttpRequest(); - request.open(type, url, true); - //request.setRequestHeader("Accept", "application/json"); - //request.setRequestHeader('Content-Type', 'application/json'); - /* request.onreadystatechange = function () { - if (r.readyState != 4 || r.status != 200) return; - alert("Success: " + r.responseText); - } */ - request.onload = function () { - self.log('onload'); - self.log(this); - if (this.status >= 200 && this.status < 400) { - // Success! - var result = {}; - - //try { - var response = this.response; - response = response.replace(/(\\\")/g, '"'); - try { - response = decodeURI(response); - } catch (error) { - /* console.log('response'); - console.log(response); */ - console.log('decodeURI error'); - console.log(error); - } - result.response = self.parse(response); - result.status = this.status; - result.header = this.getAllResponseHeaders().split('\r\n').reduce((resultHeader, current) => { - let [name, value] = current.split(': '); - resultHeader[name] = value; - return resultHeader; - }, {}); - //} catch (e) { - //} - self.log('result'); - self.log(result); - if (params.success) - self.do(params.success, undefined, result); - //self.do(params.success, result); - //self.do(self.replaceProperty(params.success, 'result', result), result); - } else { - // We reached our target server, but it returned an error - if (params.error) - self.do(params.error, undefined, 'Server error'); - //self.do(params.error, 'Server error'); - } - }; - request.onerror = function (error) { - // There was a connection error of some sort - self.log('error'); - self.log(error); - self.log('this'); - self.log(this); - if (params.error) - self.do(params.error, undefined, 'Server unavailable'); - //self.do(params.error, 'Server unavailable'); - }; - //request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); - if (data) - request.send(data); - - else - request.send(); - } else { - self.log('ajax method requires url parameter'); - } - - - /* $.ajax({ - url: paramsReplaced.url, - type: params.type || 'post', - //dataType: 'json', // questo dovrebbe evitare JSON.parse - //dataType: 'text', // verificare se necessario - data: paramsReplaced.data || {}, - success: function (result) { - self.log('ajax'); - self.log('result'); - self.log(result); - self.do(params.success, result); - //self.do(data); // in .params dovrebbe andare il resto - }, - error: function (error) { - var errorText = error.responseText || error; - self.do(params.error, errorText); - //self.do(data); // in .params dovrebbe andare il resto - } - }); */ - }; - - /* View in fullscreen */ - this.openFullscreen = function (id) { - var element = document.getElementById(id); - - if (screenfull.isEnabled) { - screenfull.request(element); - } - - }; - - /* this.addListener = function(params) { - var selector = self.selector(params); - if (selector) - $(selector).on(params.event, self.do(params.action)); - //event.stopPropagation(); - } */ - /* Close fullscreen */ - this.closeFullscreen = function () { - - //document.exitFullscreen(); - screenfull.off('change'); // callback - }; - - /* this.list = function (params, selectorParams) { - - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - if (selector) { - - if (params.list) params.items = params.list; // retro-compatibilità - - if (params.listAction) $(selector).data('listAction', params.listAction); - if (params.listClass) $(selector).data('listClass', params.listClass); // ul - - if (params.items) { - - $(selector).empty(); - var index = 0; - - //params.items = self.replaceTags({text:params.items, args:selectorParams}); - //params.items = self.replaceResult(params.items, selectorParams); - params.items = self.replaceProperties(params.items, selectorParams); - - for (var itemKey in params.items) { - // da rimuovere id="item'+itemKey+'" href="" - //self.log('PARAMETRI'); - //self.log(itemKey); - //self.log(params.items); - - - $(selector).append('
    • '); - var item = params.items[itemKey]; - //var itemSelector = selector + ' li:eq(' + index + ')'; - var itemSelector = selector + ' li:eq(' + itemKey + ')'; - - // Item action - var itemAction; - if (item.action) - itemAction = item.action; - else if (params.action) - itemAction = params.action; - else if ($(selector).data('listAction')) - itemAction = $(selector).data('listAction'); - item.action = itemAction; - - if (item.action) { - $(itemSelector).addClass('list-group-item-action'); - $(itemSelector).css('cursor', 'pointer'); - } - if (item.color) $(itemSelector).css('color', item.color); - if (item.background) $(itemSelector).css('background', item.background); - - //$(itemSelector).append('
      '); - - var itemFields = params.items[itemKey].fields || params.items[itemKey]; // retro-compatibilità - //self.log('itemFields'); - //self.log(itemFields); - - for (var itemField in itemFields) { - var field = itemFields[itemField]; - //self.log(field); - if (itemField == 'icons') { - - self.icons(field, {container: itemSelector}); - - - } else if ((itemField != 'params') && (itemField != 'action')) { // retro-compatibilità - $(itemSelector).append(''+self.text(itemFields[itemField])+''); - } - } - - // action - if (item.action) { - $(itemSelector).data('onData', item); - $(itemSelector).on(self.touch, function (event) { - event.stopPropagation(); - self.onEvent(this, event); - }); - } - // events - if (item.on) self.on(item.on, {container: selector}); - - index++; - } - } else if (params.append) { - // aggiunge una riga alla fine (calcolare path) - } else if (params.prepend) { - // aggiunge una riga all'inizio (calcolare path) - // sballa tutti i dati presenti in var.functions - // sarebbe meglio mem in data value tutto il json - // azione - } - - // List classes - - //if (params.id) $(selector).attr('id', params.id); - var listClass = $(selector).data('listClass'); - - - if (listClass) { - var ulClass = listClass.ul || ''; - var liClass = listClass.li || ''; - - $(selector).addClass(ulClass); - $(selector + ' > li').addClass(liClass); - - var index = 0; - for (var field in listClass.fields) { - var fieldClass = listClass.fields[field] || ''; - $(selector + ' > li > span[data-field='+field+']').addClass(fieldClass); - index++; - } - } - } - } */ - this.scroll = function (params) { - // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView - // {id, class, value} - var selector = self.selector(params.selector || params.container); - var block = document.querySelector(selector); - //var offset = elem.dataset.offset ? parseInt(elem.dataset.offset) : 0; - if (block) { - var bodyOffset = document.body.getBoundingClientRect().top; - window.scrollTo({ - top: block.getBoundingClientRect().top - bodyOffset, // + offset, - behavior: 'smooth' - }); - } else { - self.log('scroll to unknown element: ' + selector); - } - }; - - /* this.scroll = function (params) { - // var selector = self.selector(params); - //var obj = $(selector).get(0); - - var selector = "g."+params.class+".myLabelStyle."+params.value; - - - //var parent = $(selector).parent().get(0); - - //document.querySelector(selector).scrollIntoView(); - //self.resizeEvent(); // bug workaround - //$(selector).parent().scrollTop($(selector).position().top); - $(selector).parent().animate({ - //scrollTop: $(selector).position().top - //scrollTop: $(selector).position().top, - transform: 'translate(0,-'+$(selector).position().top+'), scale(1)' - }); - } - */ - //------------------------ - /* this.do = function (data, args) { - if (data) { - if (typeof data == 'string' && self.json.actions[data]) { - self.do(self.json.actions[data], args); - } else { - if (!data.index) data.index = 0; - if (!data.tasks) { - if (Array.isArray(data)) { - - if (data.index < data.length) { - self.do(data[data.index]); - data.index = data.index +1; - self.do(data); - } else { - delete data.index; - } - } else { - self.do(data); - } - //} else if (data.tasks.length > 0) { - } else { - if (data.index < data.tasks.length) { - var currentTask = data.tasks[data.index]; - //var currentTask = data.tasks.shift(); - if (currentTask.params == undefined) {currentTask.params = {}} - if (data.params == undefined) {data.params = {}} - if (currentTask.if == undefined) {currentTask.if = true} - var taskParams = currentTask.params; // parametri specifici del task - taskParams.params = data.params; - taskParams.index = data.index+1; - //for (var param in data.params) {taskParams[param] = data.params[param]; } // merge - taskParams.tasks = data.tasks; - var taskIf = (typeof currentTask.if == "function") ? currentTask.if() : currentTask.if; - - if (taskIf) { - if (currentTask.delay !== undefined) { - setTimeout(function () { - self.do(currentTask.task, taskParams); - - }, currentTask.delay); - } else if (currentTask.interval !== undefined) { - self.createTaskInterval(currentTask); - } else { - self.do(currentTask.task,taskParams); - - } - } else { - self.do(taskParams); - } - } - } - } - } - } */ - /* this.playTaskInterval = function (taskFunction) { - self.log('playTaskInterval'); - var taskName = taskFunction.name; - if (tasksIntervals[taskName]) { - clearInterval(tasksIntervals[taskName].id); - tasksIntervals[taskName].id = setInterval(function () { - tasksIntervals[taskName].task(tasksIntervals[taskName].params); - }, tasksIntervals[taskName].interval); - } else { - self.log('taskName: '+taskName); - } - } - - this.stopTaskInterval = function (taskFunction) { - self.log('stopTaskInterval'); - var taskName = taskFunction.name; - if (tasksIntervals[taskFunction.name]) { - clearInterval(tasksIntervals[taskFunction.name].id); - } else { - self.log('taskName: '+taskName); - } - } - - this.createTaskInterval = function (myTask) { - tasksIntervals[myTask.task.name] = {}; - tasksIntervals[myTask.task.name].task = myTask.task; - tasksIntervals[myTask.task.name].params = myTask.params; - tasksIntervals[myTask.task.name].interval = myTask.interval; - self.playTaskInterval(myTask.task.name); - } - - this.addTimedTask = function (data) { - self.log('addTimedTask'); - if (data.frequence && data.task) { - if (!data.active) {data.active = true;} - if (!timedTasks[data.frequence]) {timedTasks[data.frequence] = {}} - timedTasks[data.frequence][data.task] = {active:data.active, params:{}}; - if (data.params) { - timedTasks[data.frequence][id].params = data.params; - } - } - } - - this.removeTimedTask = function (data) { - self.log('removeTimedTask'); - if (data.frequence && data.task) { - delete timedTasks[data.frequence][data.task]; - } - } - - this.doTimedTask = function (data) { - self.log('doTimedTask'); - self.log(data); - for (var task in timedTasks[data.frequence]) { - var taskObj = timedTasks[data.frequence][task]; - if (taskObj.active) { - self.do(task, taskObj.params); - } - } - } */ - //------------------------ - // CSS METHODS - //------------------------ - /* // SELETTORI - var previewPanel = '.appPanel[data-value="pnlPreview"]'; - var toolsPanel = '.appPanel[data-value="pnlTools"]'; - - var stagePanel = '.framePanel[data-value="pnlStage"]'; - var devicePanel = '.framePanel[data-value="pnlDevice"]'; - - this.closePanel = function(value) { - self.log(value); - - switch (value) { - case 'closePanelTools': - $(toolsPanel).fadeOut(); - $(previewPanel).fadeIn(); - case 'closePanelFrame': - $(devicePanel).fadeOut(); - $(stagePanel).fadeIn(); - } - } - */ - //------------------------ - // CSS METHODS - //------------------------ - /* this.cssProp = function (propPar) { - var cssObj = {transform: ''}; - if ((propPar.x) && (propPar.y)) {cssObj.transform += ' translate('+propPar.x+'px,'+propPar.y+'px)'; } - if (propPar.rotateY) {cssObj.transform += ' rotateY('+propPar.rotateY+'deg)'; } - if (propPar.rotateX) {cssObj.transform += ' rotateX('+propPar.rotateX+'deg)'; } - if (propPar.scale) {cssObj.transform += ' scale('+propPar.scale+','+propPar.scale+')'; } - if (propPar.deg) {cssObj.transform += ' rotate('+propPar.deg+'deg)'; } - if (propPar.opacity) {cssObj.opacity = propPar.opacity;} - return cssObj; - } */ - /* this.getCSS = function (data) { - var $inspector = $("
      ").css('display', 'none').addClass(data.class); - $("body").append($inspector); // add to DOM, in order to read the CSS property - try { - var props = []; - for (i=0; i { - /* self.log('animate'); - self.log('params'); - self.log(params); - - self.log('selectorParams'); - self.log(selectorParams); */ - - /* selectorParams.container = (params.container) ? params.container : selectorParams.container; - selectorParams.id = (params.id) ? params.id : selectorParams.id ; - selectorParams.class = (params.class) ? params.class : selectorParams.class; - selectorParams.value = (params.value) ? params.value : selectorParams.value; */ - const prefix = 'animate__'; - //var selector = self.selector(self.extend({}, params, selectorParams), undefined, true); // selectAll - let selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - //var selector = self.selector(params.selector || params.container, selectorParams, true); // selectAll - /* self.log('animate'); - self.log('selector'); - self.log(selector); */ - var transition = params.transition || params; - transition = self.replaceProperties(transition, args); - - const duration = params.duration || '0.5s'; - - const animationName = `${prefix}${transition}`; - - if (!selector) { - self.log('animate function without selector'); - self.log(params); - self.log(selectorParams); - } else { - - var elements = self.queryAll(selector); - /* console.log('elements'); - console.log(elements); */ - //var elements = document.querySelectorAll(selector); - if (elements) - elements.forEach(function (element, index) { - if (element) { - //element.classList.add(`${prefix}animated`, animationName); - //console.log(element.classList); - element.classList.add('animate__animated', animationName); - element.style.setProperty('--animate-duration', duration); - } else { - console.log('element'); - console.log(element); - } - }); - - - if (params.on && params.on.start) - self.do(params.on.start, { selector: selector }); - //self.do(params.on.start, undefined, {selector: selector}); - if (params.style) self.css(params, selectorParams); // TO DO: deprecated / to be removed - - - - - - //if (params.infinite) - // node.style.setProperty('--animate-infinite', 'infinite'); - // When the animation ends, we clean the classes and resolve the Promise - function handleAnimationEnd(event) { - if (params.on && params.on.end) { - self.do(params.on.end, { selector: selector }); - //self.do(params.on.end, undefined, {selector: selector}); - /* self.log('handleAnimationEnd'); - self.log('params.on.end'); - self.log(params.on.end); */ - } - - - event.stopPropagation(); - - if (elements) - elements.forEach(function (element, index) { - if (element) - element.classList.remove('animate__animated', animationName); - }); - resolve('Animation ended'); - } - - if (elements) - elements.forEach(function (element, index) { - if (element) - element.addEventListener('animationend', handleAnimationEnd, { once: true }); - }); - } - }); - }; - - /* - this.animation = function (data) { // deprecated - - if (data.animation != undefined) { - if (data.animation == 'show') { - $(data.object).css({'display':'block', opacity:1}); - } else if (data.animation == 'hide') { - $(data.object).css({'display':'none'}); - } else { - //if (data.autoDisplay == undefined) {data.autoDisplay = true}; - //var animationObject = self.cloneObject(animations[data.animation]); - var animationObject = jQuery.extend({}, animations[data.animation]); - //if (data.autoDisplay) - // if (data.animation == 'fadeIn') $(data.object).css({'display':'block'}); - if (data.reverse) {animationObject.name += 'Reverse'} - if (data.duration !== undefined) {animationObject.duration = data.duration} - - animationObject.complete = function () { - if (data.autoDisplay) { - if ((data.animation == 'fadeOut') || (data.animation == 'hide')) { - $('data.object').css({'display':'none'}); - } - } - if (data.onComplete !== undefined) { - self.do(data.onComplete); - } - } - self.log('animationObject.name'); - self.log(animationObject.name); - self.log('animationObject'); - self.log(animationObject); - - // playKeyframe va aggiornato con - // animate({from, to, ease, type, stiffness, dumping, mass, velocity, duration}) - // https://popmotion.io/#quick-start-animation-animate-keyframes-options - //var obj = popmotion.styler($(data.object)); - //popmotion.animate(animationObject).start(obj.set); // $(data.object).css - - $(data.object).playKeyframe(animationObject); - } - } else { - $(data.object).resetKeyframe(); - $(data.object).css({'opacity':1,'display':'block'}); - self.log('ANIMATION UNDEFINED'); - self.log(data); - } - } - - this.move = function (data) { // deprecated - var targetPos = {x:0,y:0}; - if (data.target != 'center') { targetPos = {x:384,y:384}; } - else if (data.target !== undefined) {targetPos = self.getTransform(data.target);} - else {self.log(data);} - if (data.move == 'toTarget') { - TweenMax.to(data.object, self.TweenMaxDuration(data.duration), { x: targetPos.x, y: targetPos.y}); - } else if (data.move == 'fromTarget') { - TweenMax.from(this, self.TweenMaxDuration(data.duration), { x: targetPos.x, y: targetPos.y}); - } - if (data.animation !== undefined) { - self.animation({object:data.object, animation:data.animation}); - } - } - - this.TweenMaxDuration = function (duration) { - if (duration != undefined) {return Number(duration)/1000} else {return 0.667;} - } - */ - // CSS CLASSES - this.addClassRule = function (ruleName, ruleParams) { - //self.log('addClassRule'); - var ruleProperties = '{'; - for (var property in ruleParams) { - if (typeof ruleParams[property] == 'object') { - self.addClassRule(ruleName + ' ' + property, ruleParams[property]); - } else { - ruleProperties += property + ':' + ruleParams[property] + ';'; - } - } - ruleProperties += '}'; - self.styleObj.sheet.insertRule(ruleName + ' ' + ruleProperties); - }; - - this.addApplyRule = function (ruleName, ruleParams) { - // Use @apply to inline any existing utility classes into your own custom CSS - // https://tailwindcss.com/docs/functions-and-directives#apply - self.styleObj.sheet.insertRule(ruleName + ' {@apply ' + ruleParams + '}'); - }; - - this.findPlugin = function (name) { - if (self.json.plugins) { - for (var plugin of self.json.plugins) { - if (plugin.name == name) return plugin; - } - } else { - return false; - } - }; - - this.defineCss = function (cssObj) { - self.log('defineCss'); - - self.styleObj = document.createElement("style"); - - document.head.appendChild(self.styleObj); - self.styleObj.appendChild(document.createTextNode("")); - - /* self.styleObj.sheet.insertRule('@tailwind base;'); - self.styleObj.sheet.insertRule('@tailwind components;'); - self.styleObj.sheet.insertRule('@tailwind utilities;'); */ - // shortcuts (must be improved / can't be extended) - /* if (self.json.shortcuts && self.json.shortcuts.class) - shortcuts = self.json.shortcuts.class; */ - if (cssObj) { - if (Array.isArray(cssObj)) { - for (var cssElement of cssObj) { - //console.log(cssElement); - for (var elementName in cssElement) { - //console.log(elementName); - let valueWithData = self.replaceProperties(cssElement[elementName]); - self.addClassRule(elementName, valueWithData); - } - } - } else { - for (var elementName in cssObj) { - let valueWithData = self.replaceProperties(cssObj[elementName]); - self.addClassRule(elementName, valueWithData); - } - } - } - - if (self.pluginsLoaded.tailwindcss) { - var plugin = self.findPlugin('tailwindcss'); - //var config = (plugin) ? plugin.config : {preflight: false}; - var config = (self.json.setup.config.tailwindcss) ? self.json.setup.config.tailwindcss : { preflight: false }; - //if (self.json.style.theme) setup.theme = self.json.style.theme; - //loadPlugin(undefined, 'tailwind-config', undefined, undefined, JSON.stringify(config)) // version 2.2.0 - if (tailwind) - tailwind.config = config; - - else - console.log('tailwind object is undefined'); - } - - /* // OBSOLETE - if (self.pluginsLoaded.twind && window.twind) { - var plugin = self.findPlugin('twind'); - var config = (plugin) ? plugin.config : {preflight: false, mode:'silent'}; - //if (self.json.setup.target) setup.target = self.query(self.json.setup.target); - //if (self.json.style.theme) setup.theme = self.json.style.theme; - - window.twind.setup(config); - - - } */ - /* if (self.pluginsLoaded.windicss && window.windicssRuntimeOptions) { - - var config = self.json.style.windi || { - // enabled preflight - preflight: false, - // scan the entire dom tree to infer the classnames on page loaded - extractInitial: false, - // generate mock classes for browser to do the auto-completeion - mockClasses: false, - // the windi config you are used to put in `windi.setup.js` - setup: {}, - theme: {extend: {}} - }; - if (self.json.style.theme) setup.theme.extend = self.json.style.theme; - window.windicssRuntimeOptions = config; - } */ - /* if (self.pluginsLoaded.unocss) { - - var config = self.json.style.unocss || { // -> self.json.plugins[].setup - rules: [ - // custom rules... - ], - presets: [ - // custom presets... - ], - // ... - }; - if (self.json.style.theme) setup.theme = self.json.style.theme; - if (self.json.shortcuts) setup.shortcuts = self.json.shortcuts; - - window.__unocss = config; - //alert(JSON.stringify(config)); - } */ - //self.do(data); - }; - - /* this.createLoader = function (data) { - // !--
      Loading...
      --> - - if (self.json.loader) $('.preloader img').attr('src', self.json.loader); - self.do(data); - } */ - /* this.preloadIcons = function (data) { - self.log('preloadIcons'); - // to do: check for duplicated ids - - if (self.json.icons) { - if (!data.icons && self.json.icons) data.icons = self.cloneObject(self.json.icons); - if (data.icons) { - var iconSet = Object.keys(data.icons)[0]; - var icons = data.icons[iconSet]; - delete data.icons[iconSet]; - if (icons.preload) { - - - var ajax = new XMLHttpRequest(); - ajax.open("GET", icons.src, true); - ajax.onload = function(e) { - - if (this.status >= 200 && this.status < 400) { - - self.log('Icon set loaded ' + iconSet); - - var result = this.response; // responseText - //self.log(result); - var div = document.createElement("div"); - //var iconsHtml = new XMLSerializer().serializeToString(result); - var iconsHtml = result; - iconsHtml = self.replaceAll(iconsHtml, 'id="', 'id="' + iconSet + '_'); - div.innerHTML = iconsHtml; - div.setAttribute("style", "display: none"); - //div.setAttribute("aria-hidden", "true"); - //document.getElementbyId('preloadIcons').appendChild(element); - document.body.insertBefore(div, null); - if (Object.keys(data.icons).length > 0) - self.preloadIcons(data); - else - self.do(data); - } - } - ajax.send(); - - } else { - if (Object.keys(data.icons).length > 0) - self.preloadIcons(data); - else - self.do(data); - } - } else - self.do(data); - } else { - self.do(data); - } - } */ - /* this.initApp = function (data) { - self.log('initApp'); - - self.defineCss(); - - window.addEventListener('resize', self.resizeEvent); - - if (self.json) { // can be self.json.init - //if (self.json.on.init) - if (self.json.on) - self.on(self.json.on); - - //else - // self.log('no on init functions'); - } - //self.do(data); - } - */ - /* this.createUI = function (data) { - jsonic.do({ - tasks:[ - {task: self.firebaseInit}, - { - task: self.firebaseVerifyUser, - params: { - code: self.params.oobCode - } - }, - {task: self.getDevices, if: jsonic.userIn}, - {task: self.defineCss}, - {task: self.defineAnimations}, // animazioni css predefinite - {task: self.createHeader}, - {task: self.createMenu, params: { - container: '#menu', - id: data.params.mode || 'guest' - }}, - {task: jsonic.createPages} - ] - }); - } */ - /* this.openPageFromUrl = function(data){ - jsonic.log('openPageFromUrl'); - jsonic.log('self.params'); - jsonic.log(self.params); - - var pageId = ''; - - //if (localStorage.getItem('scanning')) { - // self.hashopenTask({id:localStorage.getItem('scanningFile')}); - //} else { - - //self.disableFileIcons(); - - //var noDevices = (jsonic.userIn() && (!var.db.devices || Object.keys(var.db.devices).length == 0)); - //if (noDevices && !self.params.d && !self.params.m) { - // jsonic.gotoPage('devices'); - //} else { - - if (window.location.hash && window.location.hash !== '') { - //pageId = window.location.hash.substr(1); - self.hash(); - } else { - if (self.params.p) // retro-compatibilità - pageId = self.params.p; - else - pageId = self.homePage(); - self.gotoPage(pageId); - } - - //} - self.do(data); - } -*/ - /* - // Load a script from given `url` - var loadPlugin = function(url) { - return new Promise(function(resolve, reject) { - const script = document.createElement('script'); - script.src = url; - - script.addEventListener('load', function() { - // The script is loaded completely - resolve(true); - }); - - document.head.appendChild(script); - }); - }; - - // Perform all promises in the order - var waterfall = function(promises) { - return promises.reduce( - function(p, c) { - // Waiting for `p` completed - return p.then(function() { - // and then `c` - return c().then(function(result) { - return true; - }); - }); - }, - // The initial value passed to the reduce method - Promise.resolve([]) - ); - }; - - // Load an array of scripts in order - var loadScriptsInOrder = function(arrayOfJs) { - self.log('loadScriptsInOrder'); - self.log(arrayOfJs); - const promises = arrayOfJs.map(function(url) { - self.log(url); - return loadScript(url); - }); - return waterfall(promises); - }; - */ - this.hash = function (path, args) { - self.log('hash'); - var path = self.replaceProperties(path, args); - self.log(path); - window.location.hash = path; - }; - - this.page = function (path, args) { - self.log('page'); - var path = self.replaceProperties(path, args); - self.log(path); - if (path.startsWith('#')) - window.location.hash = path; - - else - window.location.href = path; - //window.location.hash = path; - }; - - this.hashChangeEvent = function () { - self.log('hashChangeEvent'); - self.log(window.location.hash); - - - /* if (window.location.hash && window.location.hash !== '') { - var hashParams = window.location.hash.substr(1).split('/'); - self.gotoPage(hashParams[0], hashParams[1]); - } else { - //pageId = self.homePage(); - if (self.json.setup && self.json.setup.wordpress && self.json.setup.wordpress.slug) - self.gotoPage(self.json.setup.wordpress.slug); - else - self.gotoPage(self.homePage()); - } - - if (json && json.app && json.app.on && json.app.on.page) { // page event - self.do(json.app.on.page); - } - - if (json && json.actions && json.actions.init) { // obsolete - self.do(json.actions.init); - } */ - }; - - /* this.addPageListeners = function (data) { - self.log('addPageListeners'); - - // Resize event - window.addEventListener('resize', self.resizeEvent); - - // Location hash (url) event - window.addEventListener('hashchange', self.hashChangeEvent); - //$(window).on('hashchange', self.hashChangeEvent); - - self.hashChangeEvent(); - - self.do(data); - - } */ - /* // testing - let findValues = function(obj, key, found) { - for (let localKey in obj) { - if (obj.hasOwnProperty(localKey)) { - let val = obj[localKey]; - //self.log(localKey) - if (localKey === key) { - found.add(val) - } else { - if (typeof val === 'object') { - findValues(val, key, found) - } - } - } - } - } - function uniqueValue(obj, key, value) { - let found = new Set() - findValues(object, key, found) - return found.size === 1 && found.has(value); - } */ - this.lookup = function (obj, k) { - for (var key in obj) { - var value = obj[key]; - - if (k == key) { - return [k, value]; - } - - if (typeof (value) === "object" && !Array.isArray(value)) { - var y = lookup(value, k); - if (y && y[0] == k) return y; - } - if (Array.isArray(value)) { - // for..in doesn't work the way you want on arrays in some browsers - // - for (var i = 0; i < value.length; ++i) { - var x = lookup(value[i], k); - if (x && x[0] == k) return x; - } - } - } - - return null; - }; - - this.findValues = function (obj, key) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - let matrix = [...JSON.stringify(obj).matchAll(new RegExp('\"?' + key + '\"?\:\s*\"([^,\"]+)', 'gi'))]; - var results = []; - for (var element of matrix) - results.push(element[1]); - return results; - //return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + key + '\"?\:\s+\"' + value + '\"'))) // JSON5 compatible - }; - - // testing - function findKey(obj, key) { - for ([k, v] of Object.entries(obj)) { - if (k == key) return v; - if (typeof v === 'object' && v !== null) { - let found = findKey(v, key); - if (found) return found; - } - } - } - - - // lookup in json - this.keyInJson = function (obj, string) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + string + '\"?\:'))); // JSON5 compatible - }; - - // lookup in json - this.valueInJson = function (obj, string) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + string + '\"?'))); // JSON5 compatible - }; - - /* this.keyInFiles = function (string) { - var found = self.keyInJson(self.options, string); // in main app options: jsonic = jsonicApp(options) - for (fileName in self.modules) { - if (fileName !== 'resources' && self.keyInJson(self.modules[fileName], string)) - found = true; - } - return found; - } */ - /* this.openPageFromUrl = function (data) { - self.log('openPageFromUrl'); - self.hashChangeEvent(); - self.do(data); - }; */ - /* this.addEventListeners = function (data) { - self.log('addEventListeners'); - - // Resize event - window.addEventListener('resize', self.resizeEvent); - - // Location hash (url) event - window.addEventListener('hashchange', self.hashChangeEvent); - $(window).on('hashchange', self.hashChangeEvent); - - self.hashChangeEvent(); // add here on.hashchange - - // Fullscreen event - if (screenfull && screenfull.isEnabled) { - screenfull.on('change', () => { - self.log('Am I fullscreen?', screenfull.isFullscreen ? 'Yes' : 'No'); - if (screenfull.isFullscreen) { - var.fullscreen = true; - if (var.onFullScreenOpen) self.do(var.onFullScreenOpen); - } else { - var.fullscreen = false; - if (var.onFullScreenClose) self.do(var.onFullScreenClose); - } - }); - } - - if (json && json.app && json.app.on) { - - if (json.app.on.thunkable && json.app.on.thunkable.receiveMessage) - window.receiveMessage(function (message) { - //document.querySelector('#message').value = message; - jsonic.functions(json.app.on.thunkable.receiveMessage, message, undefined); - }); - - var container = json.app.container || 'body'; - self.on(json.app.on, {container: container}); - self.do(data); - } else { - self.do(data); - } - } */ - /* this.loadIconset = function (data) { - self.log('loadIconset'); - - - if (self.json.iconset) { - if (!self.pluginsLoaded['iconify']) { - let plugin = self.json.resources.pluginsFunctions['iconify']; - self.pluginsLoader([plugin], self.loadIconset, [data]); - } else { - var iconset; - - if (!self.json.iconset[0]) - iconset = [self.json.iconset]; - else - iconset = self.json.iconset; - - for (var index in iconset) { - - if (Iconify.addCollection(iconset[index])) - self.log('added iconset '+ iconset[index].prefix); - else - self.log('can\t add iconset '+ iconset[index].prefix); - //alert(x); - } - self.do(data); - - } - - } else { - self.do(data); - } - - } */ - // Si potrebbe creare una nuova istanza di jsonicApp - this.start = function () { - - self.log('start'); - - //if (params.onFullScreenOpen) var.onFullScreenOpen = params.onFullScreenOpen; - //if (params.onFullScreenClose) var.onFullScreenClose = params.onFullScreenClose; - // PWA - /* if ('serviceWorker' in navigator) { - // Register a service worker hosted at the root of the - // site using the default scope. - navigator.serviceWorker.register('/app/assets/pwa/sw.js').then(function(registration) { - self.log('Service worker registration succeeded:', registration); - }, function(error) { - self.log('Service worker registration failed:', error); - }); - } else { - self.log('Service workers are not supported.'); - } */ - let deferredPrompt; - - window.addEventListener('beforeinstallprompt', (e) => { - // Prevent Chrome 67 and earlier from automatically showing the prompt - e.preventDefault(); - // Stash the event so it can be triggered later. - deferredPrompt = e; - }); - - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - self.json.setup.darkMode = e.matches ? "dark" : false; - }); - - // DEFINE ICONSET (iconify) - if (self.json.iconset) { - if (!self.pluginsLoaded['iconify']) { - let plugin = self.json.resources.pluginsFunctions['iconify']; - self.pluginsLoader([plugin], self.start); - return false; - } else { - var iconset; - - if (!self.json.iconset[0]) - iconset = [self.json.iconset]; - - else - iconset = self.json.iconset; - - for (var index in iconset) { - - if (Iconify.addCollection(iconset[index])) - self.log('added iconset ' + iconset[index].prefix); - - else - self.log('can\t add iconset ' + iconset[index].prefix); - //alert(x); - } - - } - - } - - // DEFINE CSS - //self.defineCss(); // TO DO: only additional css (do it on load module success) - // ADD RESIZE LISTENER (for dynamic styles) TO DO: check it - window.addEventListener('resize', self.resizeEvent); - - // PAGE - if (!self.json.setup.page) self.json.setup.page = {}; - self.json.setup.page.hash = window.location.hash.substr(1); - - // DO / ON - /* if (self.json) { - if (self.json.do) - self.do(self.json.do, undefined, self.json.container); - - if (self.json.on) - self.on(self.json.on, self.json.container); - } */ - var selector = self.json.selector || self.json.container; - - /* if (self.json.do) - self.do(self.json.do, undefined, selector); */ - // should go action/run - if (self.json.on) - self.on(self.json.on, selector); - - }; - - this.extendJson = function (jsonBase, jsonExtension) { - // TO DO: should be renamed in extendApp (or executeModule) because extend self.json and add CSS style - if (jsonExtension.css) self.defineCss(jsonExtension.css); - if (jsonExtension.functions) self.extendFunctions(jsonExtension.functions); - - for (var key in jsonExtension) { - // AGGIUNGERE ALL'ARRAY DELLE AZIONI ON.INIT... - if (key == 'on') { - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') { - //jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - if (!jsonBase[key][subKey]) jsonBase[key][subKey] = []; - jsonBase[key][subKey].push(jsonExtension[key][subKey]); - } else { - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } - } - } else if (key == 'parts' || key == 'shortcuts') { // combine subelements - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } - /* } else if (key == 'css') { - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } */ - /* } else if (key == 'app') { // to do: obsolete - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } */ - } else if (key == 'iconset' || key == 'plugins') { // combine arrays - if (!jsonBase[key]) jsonBase[key] = []; - jsonBase[key] = jsonBase[key].concat(jsonExtension[key]); - } else { - if (key == 'css') { - } else { - jsonBase[key] = self.extend({}, jsonBase[key], jsonExtension[key]); - } - } - } - return jsonBase; - }; - - this.loadModuleFromDb = function (data) { - self.log('loadModuleFromDb'); - self.firebaseGet('jsonic', function (result) { - if (result.success) { - self.log('firebase get SUCCESS'); - for (codeKey in result.data) - if (result.data[codeKey].code) - self.extendJson(json, result.data[codeKey].code); - //self.log('json'); - //self.log(json); - //if (params.success) self.do(params.success,result.data); - } else { - self.log('firebase get ERROR'); - //if (params.error) self.do(params.error, result.error); - // alert errore di connessione. alert riprova - } - self.do(data); - //self.do(data); - }); - }; - - this.modules = {}; - this.modulesLoading = {}; - - this.fileType = function (fileName) { - return /(?:\.([^.]+))?$/.exec(fileName)[1]; - }; - - this.jsoncToJson = function (jsoncText) { - return jsoncText.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1').replace(/\r/, "\n").replace(/\n[\n]+/, "\n"); - // https://stackoverflow.com/questions/244777/can-comments-be-used-in-json/24545329 - }; - //var json = jsoncToJson('https://fantacards.com/app/data.jsonc'); - //console.log(json); - this.loadModule = function (mod) { - /* self.log('loadModule'); - self.log(mod); */ - // params: {files, onComplete} - // self.cloneObject(params.json) to avoid to remove from initial params - //if (typeof setup.modules == 'string') setup.modules = [setup.modules]; - if (!self.modulesLoading[mod.name] && !self.modules[mod.name]) { - self.modulesLoading[mod.name] = true; - - return new Promise(function (resolve, reject) { - //mod = self.replaceProperties(mod); - //self.log(mod); - - const getAPIData = new XMLHttpRequest(); - getAPIData.open("GET", mod.url); - getAPIData.onload = function () { - self.modulesLoading[mod.name] = false; - //console.log(getAPIData); - let responseText = getAPIData.responseText; - if (self.fileType(getAPIData.responseURL) == 'jsonc') - responseText = self.jsoncToJson(responseText); - // try - const result = JSON.parse(responseText); - // error self.log('Wrong JSON in module '+ mod.name); - if (self.isJson(result)) { - self.modules[mod.name] = result; - self.extendJson(self.json, result); - self.log('Loaded module ' + mod.name, 'grey'); - } else { - self.log('Wrong JSON in module ' + mod.name, 'red'); - } - resolve(); - }; - getAPIData.onerror = function () { - self.modulesLoading[mod.name] = false; - }; - getAPIData.send(); - }); - - } else { - self.log('Module ' + mod.name + ' already loaded', 'orange'); - } - - - }; - - /* var loadPlugin = function (url) { - //self.log('loading ' + url); - - return new Promise(function(resolve, reject) { - var type = 'script'; - if (url.endsWith('.css')) type = 'link'; - - let obj = document.createElement(type); - - // obj.src = url; - obj.async = false; - obj.onload = function() { - resolve(url); - }; - obj.onerror = function() { - self.log('error loading: '+url); - reject(url); - }; - - if (type === 'script') { - if (url) obj.src = url; - //if (code) obj.text = code; - obj.location = document.body; - document.body.appendChild(obj); - } else { - obj.href = url; - obj.rel = 'stylesheet'; - obj.type = 'text/css'; - obj.location = document.head; - document.head.appendChild(obj); - } - - //self.log('obj'); - //self.log(obj); - }); - } */ - var loadPlugin = function (params) { - //self.log('loading ' + url); - - return new Promise(function (resolve, reject) { - var tag = 'script', type = 'text/javascript'; - if (params.type == 'script') { tag = 'script'; type = 'text/javascript'; } - else if (params.type == 'module') { tag = 'script'; type = 'module'; } - else if (params.type == 'tailwind-config') { tag = 'script'; type = 'tailwind-config'; } - else if (params.type == 'link') { tag = 'link'; type = 'text/css'; } - else if (params.type == 'font') { tag = 'link'; type = undefined; } - //if (!tag) - // tag = (url.endsWith('.js')) ? 'script' : 'link'; - let obj = document.createElement(tag); - if (params.content) - obj.appendChild(document.createTextNode(params.content)); - - obj.async = false; - obj.onload = function () { - self.pluginsLoaded[params.name] = { version: "1.0.0" }; - self.log('Loaded plugin ' + params.name, 'grey'); - resolve(params.url); - }; - obj.onerror = function () { - self.log('Error loading plugin ' + params.url, 'red'); - reject(params.url); - }; - - if (tag === 'script') { - if (params.url) obj.src = params.url; - //if (code) obj.text = code; - obj.location = document.body; - obj.type = type || 'text/javascript'; - /* if (type == 'tailwind-config') { - self.log('obj'); - self.log(obj); - } */ - document.body.appendChild(obj); - } else if (tag === 'link') { - obj.rel = params.rel || 'stylesheet'; - obj.location = document.head; - if (params.url) obj.href = params.url; - if (type) obj.type = type; - if (params.as) obj.as = params.as; - document.head.appendChild(obj); - } - }); - }; - - - /* var loadPlugin = function (url, tag, rel, as) { - //self.log('loading ' + url); - - //alert(url); - - return new Promise(function(resolve, reject) { - if (tag == 'js') tag = 'script'; - if (tag == 'css') tag = 'link'; - if (!tag) - tag = (url.endsWith('.js')) ? 'script' : 'link'; - - let obj = document.createElement(tag); - - obj.async = false; - obj.onload = function() { - self.log('loaded plugin: '+url); - resolve(url); - }; - obj.onerror = function() { - self.log('error loading: '+url); - reject(url); - }; - - if (tag === 'script') { - if (url) obj.src = url; - //if (code) obj.text = code; - obj.location = document.body; - document.body.appendChild(obj); - } else { - obj.href = url; - obj.rel = rel || 'stylesheet'; - if (obj.rel == 'stylesheet') - obj.type = 'text/css'; - if (as) - obj.as = as; - obj.location = document.head; - document.head.appendChild(obj); - } - }); - } - */ - this.uiLoaded = {}; - this.pluginsLoaded = {}; - - //The Firebase Realtime Database lets you store and query user data, and makes it available between users in realtime - this.findUrl = function (array, url) { - for (var item of array) { - if (item.url == url) - return true; - } - }; - - /* this.export = function (params) { - // {name, data} - if (params && params.name && params.data) { - let element = document.createElement('a'); - element.style.display = 'none'; - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(params.data))); - element.setAttribute('download', params.name); - document.body.appendChild(element); - element.click(); - document.body.removeChild(element); - } else { - self.log('"export" requires name and data attributes'); - } - } */ - /* this.exportData = function (path) { - // data - const fileName = self.replaceAll(path, ' ', '.') + '.json'; - const jsonData = self.element({path: path, root: params.root}); - self.export({name: fileName, data: jsonData}); - } - */ - this.loadPlugins = function () { - //self.log('loadPlugins'); - //var setup = json.setup; - // TEMPORAL API - // https://cdn.jsdelivr.net/npm/@cogitatio/tc39-temporal@0.0.12-alpha.2/index.js - // https://cdn.jsdelivr.net/npm/cogitatio-tc39-temporal@1.0.2/index.js - /* */ - var filesToLoad = []; - - // plugins - if (self.json.plugins) { - for (var index in self.json.plugins) { - - var plugin = self.json.plugins[index]; - - //self.log('loading ' + plugin.name + '...'); - var version = plugin.version || ''; - - if (!plugin.ondemand) { // V. >= 1.0.2 - - if (plugin.url) { // directly loaded - // plugin.name and version are needed? - if (!self.findUrl(filesToLoad, plugin.url)) { // not included yet - filesToLoad.push({ name: plugin.name, url: plugin.url, type: plugin.type }); - } - - } else { // from resources (TO DO: remove) - - var pluginsFiles = plugin.files || self.json.resources.pluginsFiles[plugin.name]; - - // moved in loadPlugin = ... onload - /* self.pluginsLoaded[plugin.name] = { - version: version - }; */ - if (!Array.isArray(pluginsFiles)) - pluginsFiles = [pluginsFiles]; - - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (plugin.params) url += '?' + plugin.params; - let pluginName = plugin.name || item.name; - if (!url || !self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({ name: pluginName, url: url, type: item.type, content: item.content }); - } - - } - } - } - } - - // ui - /* for (var index in config.ui) { - - var configUI = config.ui[index]; - - //self.log('loading ' + configUI.name + '...'); - - var version = configUI.version || ''; - var uiFiles = self.json.resources.uiFiles[configUI.name]; - - if (!Array.isArray(uiFiles)) - uiFiles = [uiFiles]; - - for (item of uiFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({url: url, type: item.type, content: item.content}); - } - } */ - // Auto load Google Fonts - // TO DO: comment - for (fontName of self.findValues(self.json, 'font-family')) { - if (self.json.resources.googleFonts.indexOf(fontName) >= 0) { - //alert(fontName); - fontName = self.replaceAll(fontName, ' ', '+'); - //filesToLoad.push({type: 'font', url:'https://fonts.googleapis.com/css2?family='+fontName+'&display=swap', rel:'preload', as:'font'}); - filesToLoad.push({ type: 'link', url: 'https://fonts.googleapis.com/css2?family=' + fontName }); - // +'&display=swap' // https://css-tricks.com/almanac/properties/f/font-display/ - } - } - - // Auto load plugins (firebase only) - /* if (config.plugins && config.plugins.autoload) { - self.log('plugins autoload'); - //for (var index in self.json.resources.pluginsFunctions) { - var pluginFunctions = self.json.resources.pluginsFirebase; // pluginFunctions - for (var index in self.json.resources.pluginsFirebase) { - //self.log(index + ':' + self.keyInFiles(index)); - if (self.keyInFiles(index)) { - if (pluginFunctions[index]) { - - var plugins = []; - if (Array.isArray(pluginFunctions[index])) - plugins = pluginFunctions[index]; - else - plugins = [pluginFunctions[index]]; - - for (plugin of plugins) { - - self.log('loading ' + plugin.name + '...'); - self.pluginsLoaded[plugin.name] = version; - - var version = plugin.version || ''; - var pluginsFiles = self.json.resources.pluginsFiles[plugin.name]; - - if (!Array.isArray(pluginsFiles)) - pluginsFiles = [pluginsFiles]; - - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({url: url, type: item.type, content: item.content}); - } - } - } - } - } - } */ - // load multiple scripts in sequence - // https://bit.ly/3nT5Ky1 - // one after another - // https://medium.com/@asimmittal/sequential-script-loading-in-javascript-a0b77ca9467c - // load multi js and css - // https://sphacks.io/load-multiple-js-scripts-dynamically-without-jquery/ - // save all Promises as array - let promises = []; - - //promises.push(loadPlugin("https://fonts.googleapis.com", 'link', 'preconnect')); - //promises.push(loadPlugin("https://fonts.gstatic.com", 'link', 'preconnect')); - filesToLoad.forEach(function (item) { - if (item.url) - promises.push(loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content })); - - else - loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content }); - //promises.push(loadPlugin(url)); - }); - - - //self.log(filesToLoad); - Promise.all(promises).then(function () { - - self.start(); - - }).catch(function (script) { - self.log('Failed to load'); - self.log(script); - }); - - }; - - this.modulesList = function (modulesObj) { - /* self.log('modulesList'); - self.log('modulesObj'); - self.log(modulesObj); - */ - var modulesList = []; - if (modulesObj) { - for (key in modulesObj) { - var mod = self.replaceProperties(modulesObj[key]); - modulesList = modulesList.concat(mod); - } - } - return self.replaceProperties(modulesObj); - }; - - this.loadModules = function () { - //self.log('loadModules'); - if (self.json.setup.modules) { - var modules = self.replaceProperties(self.json.setup.modules); // replace {page:id} - - - /* self.log('modules'); - self.log(modules); */ - var promises = []; - modules.forEach(function (item) { - if (!self.modulesLoading[item.name] && !self.modules[item.name]) { - promises.push(self.loadModule(item)); - } - }); - - Promise.all(promises).then(function () { - - self.loadPlugins(); - - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - }); - - } else { - self.loadPlugins(); - } - - }; - - this.moduleExecuted = {}; - - this.addModule = function (params) { - - if (!self.modules[params.name]) { - - var promises = []; - //var ideModule = {name: 'ide', url: 'https://jsonic.io/app/modules/ide.json'}; - promises.push(self.loadModule(params)); - - Promise.all(promises).then(function () { - - if (!self.moduleExecuted[params.name]) { - //self.log('all modules loaded'); - var module = self.modules[params.name]; - - if (module.html) { - self.moduleExecuted[params.name] = true; - self.html(module.html); - // TO DO: add also on, funcions ... - } - } - if (params.success) - self.do(params.success); - //self.do(params.success); - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - if (params.error) - self.do(params.error); - //self.do(params.error); - }); - } else { - if (params.success) - self.do(params.success); - //self.do(params.success); - } - }; - - this.loadModuleGlobal = function () { - self.log('loadModuleGlobal'); - - var promises = []; - - var modules = []; // we need it to keep the order of the modules given in the config - for (let key in self.json.setup.modules) { - var mod = self.replaceProperties(self.json.setup.modules[key]); - modules = modules.concat(self.cloneObject(mod)); - } - /* self.log('modules'); - self.log(modules); */ - for (let mod of modules) - promises.push(self.loadModule(mod)); - //var pageModule = {name: 'global', url: '/app/modules/global.json'}; - //var ideModule = {name: 'ide', url: '/app/modules/ide.json'}; - //promises.push(self.loadModule(ideModule)); // if admin - Promise.all(promises).then(function () { - //self.log('page module loaded'); - //if (self.json.modules) { - //self.json.setup.modules = self.cloneObject(self.json.modules); // required modules - //self.json.setup.modules.app.push(pageModule); // page module - //self.json.setup.modules.app.push(ideModule); // ide module if admin - self.loadModules(); - //} - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - }); - }; - - /* this.extendJsonFromModules = function () { - self.log('extendJsonFromModules'); - for (var mod in self.modules) { - //self.extendJsonFromElement(self.modules[mod.name]); - self.extendJson(json, self.modules[mod]); - } - } */ - /* DA SISTEMARE - TEMPORANEO */ - this.code = function (params, selectorParams) { - /* self.log("params"); - self.log(params); - self.log("selectorParams"); - self.log(selectorParams); */ - - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - //var container = self.selector(params) || self.selector(selectorParams); - self.log("this.code"); - self.log("container"); - self.log(container); - - var editorContainer = container.slice(1); - //if (editorContainer.startsWith('#')) {editorContainer.slice(1);} // remove # - var editor = ace.edit(editorContainer); - - var value = params.value; // else value = params; - if (!params.do || (params.do == 'set')) { - - //var langTools = ace.require('ace/ext/language_tools'); - if (params.theme) editor.setTheme(params.theme); // "ace/theme/monokai" - var editorMode = params.mode || "ace/mode/json"; - editor.getSession().setMode(editorMode); - - var editorStyle = self.extend({ - background: "rgba(255,255,255,0)" - }, params.style); - - //$(container).css(editorStyle); //editor.container.style - /* self.css({ - style: editorStyle - }, { - container: container - }); */ // Eventualmente - var codeOptions = self.extend({ - fontSize: "11pt", - selectionStyle: "line", - highlightActiveLine: false, - wrap: true, - showLineNumbers: false, - showGutter: false, - fixedWidthGutter: false, - readOnly: true, - //enableBasicAutocompletion: false, - //enableSnippets: false, - //enableLiveAutocompletion: false, - }, params.options); - - // https://github.com/ajaxorg/ace/wiki/Configuring-Ace - editor.setOptions(codeOptions); - - var codeString; - if (typeof value == 'string') - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(JSON.parse(value), null, '\t'); // json formatting - - else - codeString = value; - else { - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(value, null, '\t'); - else { - var functionObj = self.docElement(value.function); - var functionParams = value.params; - codeString = functionObj(functionParams); - } - } - - var codeRows = codeString.split(/\r\n|\r|\n/).length; - // $(container).css({ - // height: Number(21 * codeRows) + 'px' - // }); - /* self.css({ - style: { - height: Number(21*codeRows)+"px" - } - }, { - container: container - }); */ // Eventualmente - editor.setValue(codeString, -1); - } else if (params.do == 'get') { - return editor.getValue(); - } else { - self.log('"code" function requires value param'); - } - - }; - - this.init = function (appString, modulesString) { - console.log('init'); - // app(String: app url) (Object = json app) - // modules(String): modules "ui,daisyui,svg" - /* json = { // the jsonic app tree - blocks: {}, - parts: {}, - css: {}, - do: {}, - on: {}, - texts: {}, - data: {}, - var: {} - }; */ - //self.app = self.getParams(); // from url - if (typeof appString == 'string') { - - let modules = [{ "name": "app", "url": appString }]; - let modulesNames = (modulesString) ? modulesString.split(",") : []; - for (let modName of modulesNames) { - modules.push({ "name": modName, "url": "jsonic/modules/" + modName + ".json" }); - } - - self.json.setup = { "modules": modules }; - - } else { - - if (appString) self.extendJson(self.json, appString); - - /* // TO DO: remove the requirement of resources.json - if (!self.json.setup || !self.json.setup.modules) { - self.json.setup = { - "modules": [ - { - "name": "resources", - "url": "https://jsonic.io/app/modules/lib/resources.json" - } - ] - } - } */ - if (appString.css) self.defineCss(appString.css); // can be removed? - - } - - self.loadModuleGlobal(); - }; - - function toJsonNode(xml) { - let obj = {}; - if (xml.nodeType == 1) { - if (xml.attributes.length > 0) { - obj["attr"] = {}; - for (let j = 0; j < xml.attributes.length; j++) { - let attribute = xml.attributes.item(j); - obj["attr"][attribute.nodeName] = attribute.nodeValue; - } - } - } - if (xml.hasChildNodes()) { - for (let i = 0; i < xml.childNodes.length; i++) { - let item = xml.childNodes.item(i); - let nodeName = item.nodeName; - if (item.nodeType == 3 && nodeName == "#text") { - if (/^\s+$/.test(item.nodeValue)) { - } else obj.text = item.nodeValue; - } else { - if (typeof obj[nodeName] == "undefined") { - obj[nodeName] = toJsonNode(item); - } else { - if (!Array.isArray(obj[nodeName])) - obj[nodeName] = [obj[nodeName]]; - obj[nodeName].push(toJsonNode(item)); - } - } - } - } - return obj; - } - - this.htmlToJson = function (text) { - let xmlDoc = new DOMParser().parseFromString(text, "text/xml"); - return JSON.stringify(toJsonNode(xmlDoc), null, "\t"); - }; - - this.elementToJson = function (selector) { - let el = document.querySelector(selector); - return self.htmlToJson(el.getHTML()); - }; - - function clearSelection() { - if (window.getSelection) { window.getSelection().removeAllRanges(); } - else if (document.selection) { document.selection.empty(); } - } - - this.importHtml = function (htmlText) { - // use modal and monaco js - if (!htmlText) - htmlText = prompt("html/xml"); - if (htmlText) { - let jsonDoc = self.htmlToJson(htmlText); - let textarea = document.createElement("textarea"); - textarea.value = jsonDoc; - textarea.style = "position: absolute; z-index: 999999; background: white; width:100vw; height:100vh"; - //document.body.innerHTML = ''; - document.body.appendChild(textarea); - //document.execCommand("copy"); - textarea.addEventListener('click', function () { - textarea.remove(); - navigator.clipboard.writeText(textarea.value).then(() => console.log('copied!')); - }); - //console.log(JSON.parse(jsonDoc)); - } - }; - - // https://github.com/ktskts/html2json/blob/master/src/html2json.js - /* - var Util = { - div : null, - attrs: "id,name,style,class,value,src,href,width,height,title,type".split(","), - getJson: function(childNodes, attrs, length) { - var result = []; - for ( var i = 0, len = childNodes.length; i < len; i++) { - var item = childNodes[i]; - if (item.nodeType == 3) { // textual content in an element or attribute - result.push({ - text : item.nodeValue - }) - } else if (item.nodeType == 1) { // element - var obj = { - //tag : item.nodeName.toLowerCase(), - attr : {} - }; - var flag = false; - //for ie6 - if (attrs) { - for (var j = 0; j < length; j++){ - if (attrs[j] == 'style'){ - var sStyle = item.getAttribute('style').cssText; - if(sStyle){ - obj.attr["style"] = sStyle; - flag = true; - } - } else { - var attrNode = item.attributes[attrs[j]]; - if(attrNode && attrNode.nodeType === 2){ - var value = attrNode.value; - if(value && value != 'null'){ - obj.attr[attrs[j]] = value; - flag = true; - } - } - } - } - } else { - if (item.attributes.length) { - for ( var n = 0, l = item.attributes.length; n < l; n++) { - var value = item.attributes[n].value; - if(value){ - flag = true; - obj.attr[item.attributes[n].name] = value; - } - } - } - } - - let nodeOut = {}; - let nodeTag = item.nodeName.toLowerCase(); - let nodeChild = Util.getJson(item.childNodes, attrs, length); - nodeOut[nodeTag] = {}; - - - self.log( 'item.childNodes'); - self.log( item.childNodes); - self.log( 'nodeChild'); - self.log( nodeChild); - //self.log( item.textContent); - - - nodeOut[nodeTag].html = nodeChild; - if (flag) nodeOut[nodeTag].attr = obj.attr; - result.push(nodeOut); - - } else { - // do nothing - } - } - if (result.length == 1) return result[0] - else if (result.length > 1) return result; - } - } - - this.html2json = function(text) { - if (!Util.div) Util.div = document.createElement('div'); - Util.div.innerHTML = text; - return {html: Util.getJson(Util.div.childNodes)}; - }; - */ - /* var jsonicOptions = self.extend({ - }, options); */ - if (typeof options == 'object') { - } else if (options) - self.init(arguments[0], arguments[1]); - - -} // of jsonicObject - -//var jsonicApp = jsonApp; -var jsonApp = new jsonAppObj(); -var js = jsonApp; -var jsonic = jsonApp; - -//window.jsonic = new jsonicObject(); - -/* var receiveMessage = function (process) { - if (ThunkableWebviewerExtension) - ThunkableWebviewerExtension.receiveMessage(process); -} - -var postMessage = function (message) { - if (ThunkableWebviewerExtension) - ThunkableWebviewerExtension.postMessage(message); -} */ - -/* "on": { - "init": [ - { - "thunkable": { - "postMessage": "Hi Rick!" - } - }, - { - "thunkable": { - "receiveMessage": { - "alert": "message: {result}" - } - } - } - ] -} - */ diff --git a/jsonic/js/jsonic.1.0.13.js b/jsonic/js/jsonic.1.0.13.js deleted file mode 100644 index d321526..0000000 --- a/jsonic/js/jsonic.1.0.13.js +++ /dev/null @@ -1,16029 +0,0 @@ -/*----------------------------- - JSONIC V. 1.0.13 - jsonic.io --------------------------------*/ - -// CHANGELOG - -// 1.0.13 jsonApp removed; [replaceProperties: include event properties] -// 1.0.12 jsonApp; if is array option -// 1.0.11 block blocks -> parts -// 1.0.10 for: {name} work also with {value:name with path} (function replaceValue) -// 1.0.8 for: {name} replaced with {value:name} -// 1.0.5 set: if array of, the assignments follow the order -// 1.0.4 deprecated: to assign without set (too ambiguous now that the key can be function, window.function, etc) -// 1.0.3 "x": "2*3" if the value is a string, -> self.js(value) -// 1.0.2 plugins ondemand -// 1.0.1 jsonc support -// 1.0.0 FUNCTIONS -// 0.9.9 RESOURCES: Inside modules (resources will be deprecated) -// 0.9.3 DEBUG: Rimosso break in docElement -// 0.9.4 NOTE: In this.nested, commented and decommented nested.animate = partObj.animate; nested.if partObj.if, ... -// 0.9.5 CLASS: "div btn": "content" =
      content
      -// 0.9.6 DEBUG: in this.createElement newSelector (newSelector should be a dedicated function separated from selector) -// 0.9.7 REMOVE: method to remove an element from the DOM / Restored html {attr} to set the attributes of an element - -// https://minify-js.com Input: 624.1 kB; Output: 95.46 kB; Compression: 84.7%, saving: 528.64 kB; - -// README - -// PRIORITY - -// in attr -> addStyle / removeStyle -// instead of shortcuts the user can use {data shortcuts} -// {arguments:value|default} -> ({arguments:value}) ? {arguments:value} : default -// use (typeof id == "undefined") to understand if id is defined and is = 0 -// css should call defineCss in any part of code -// attr (addClass, removeClass, changeStyle direct methods?) can be changed (in element?) to avoid confusion with the use inside html -// add remove element from array -// debug of "set" key -// can be useful to define pointers (shortcode/path of the objects) -// https://dev.to/ternentdotdev/json-compression-in-the-browser-with-gzip-and-the-compression-streams-api-4135 -// a method to append an image to the DOM in base64 format methods? no -// check this.html notes -// anime can be a part/block/key function? called with "ui:anime" asking for the relative plugin? -// if the name of the block/part includes ":" it is more explicit -// blocks or parts or keys or nodes? -// parts -> blocks considering jsblocks.com? -// Dynamic modules loading? What if we ask for a node that is in the main modules? - -// remove console from methods and add log in browser functions - -// add log of the error if the app or json module is not in json format -// init, run, start -> do -// if selector is an array, repeat the action (do) -// think about html/do. Is it possible to avoid html object? Any unknown object is an html tag -// in parts, {setup:on.success} or {setup:config.color} doesn't work -// setup -> arguments -// part ui:icon: {selector:, config:} can be a js function () {var part = {}; self.run(config); } -// {arguments[0] arguments[1]. {1.setup} } -// improve shortcuts (in extendJsonFromElement and in attr) -// this.text -> this.content -// html attribute of html method -> content (should be an html but can be multilingual) -// property validation like the sintax (\w[\w+d+]) of the "name" in the "for" method ) -// default "html" al posto di "text": ogni contenuto testuale viene inserito con innerHTML anziché innerTEXT -// html [] tipo array e "" stringa (innerHTML) ok, html {} deprecato -// "p": "text" -> p.innerTHTML('text') -// "p": [] -> se item è oggetto -> htmlTag, se stringa dovrebbe fare append della stringa html sempre nello p. Ora invece crea più p.innerText -// ADD: append. empty true fixed on html -/* -1 page -> url (method and property) -2 dynamic class with ternary condition -3 swal button style -4 components copy bugs -5 installation guide -6 self.page -> not the variable but the real window path and window hash (can be jsonic.url) -7 page -> url -8 "roles" -> "only" -9 add localStorage actions -> ANY WINDOW method -10 add dataStorage -10 in parts {string} instead of {value} ? -11 on load image solution (should already work on: load -> animate -> fadein) - */ - -// BUGS - -// BUG from Tailwind 3.3.2 -// Sembra richiesto tailwind nel plugin Jsonic e non caricato dinamicamente come su eliokit.com -// Different rendering width or without spaces after commans "alert": " {js:(1 == 2) ? \"test\" : \"false condition\"} " - - - -// HOW IT WORKS -// loadModules -> loadPlugins -> Run - -// KNOWN BUGS - -// in museomira.it cerca "socialIcons", rimuovendo data-value l'icona finisce dentro contatti perché il newSelector è a:eq(5) -// è necesario creare una funzione selector destinata ai nuovi elementi - -// PARTS - -// 1. Responsive header menu -// 2. Alert -// 3. Slide -// 4. Form -// 5. Table - -// GOAL - -// Reduce custom js code in Jsonic and move the functions in modules -// Requires an extension of js method to make it more flexible -// js {function: String, params: Array} - -// TO DO - -// inline use: data-jsonic -> jsonic.run(data-jsonic, selector); (es. in body) -// init = run (or play) -// in parts {setup} should get subreferences link {setup:on.success} -// i plugins possono includere direttamente l'url -// la gestione dei plugin dovrebbe essere centralizzata (riferimento a jsonic e non all'oggetto) -// si potrebbe definire la distinsione tra oggetti specifici e oggetti globali (jsonic) -// verificare se oggetto function con {name: , params: []} è assegnabile a variabili -// addClass, removeClass etc with array -// change the behaviour of p: [] become a a list of content, not a list of p -// to do it, search and change "div": [ "p": [ "span": [ "li": [ "button": [ -// hypothesis (no, more complete with actions): class="ui:button{text:#333;bg:#fff}" -> bg-[white] text-[#333] hover:bg-[#fff] hover:text-[white] -// OPTIMIZATION: pluginsRequiredByTag only for self.json.resources.pluginsFunctions keys or better only for parts that requires plugins. alert -> ui:alert -// getJSON: load json (id: exampleApp, url: ...), success-> {getJSON:exampleApp} -// Ajax: load ajax (id: exampleApp, url: ...), success-> {ajax:exampleApp} -// DOM: queryAll(selector) -> value is string, el.before(value) and all the other methods of an element of the dom -// properties {dom:title} -// https://www.w3schools.com/jsref/dom_obj_all.asp -// DOCUMENT -// https://www.w3schools.com/jsref/dom_obj_document.asp -// {document: {title: 'test'}} -// properties {document:title} -// ON: https://www.w3schools.com/jsref/dom_obj_event.asp -// "selector" can be "query" / no selector recalls querySelector -// or APPEND/PREPEND -// https://registry.npmjs.com/-/v1/search?text=tailwindcss&size=1 -//https://api.npms.io/v2/package/tailwindcss -// https://api-docs.npms.io - -/* -TO DO - -1. ajax call with an id to identify the data in case of simultaneous requests -1. database path should be separated by spaces (or slashes) - -replaceProperties default: - -check if - -if p1 is a function, if p2 -> value = p1(p2), if p3 -> value = p1(p2(p3)) -if p1 is a value, and not p2, value = p1 - -self.methods[p1] or... -p1 is a function - - -{alert:string} -{window.f} -{window f1:window f2:window x} = window.f1(window.f2(window.x)) - -{querySelector:'.class':append} = window.f(jsonic.json.var.x) - -ESEMPI - -{new Date:'December 17, 1995 03:24:00'} -{new Date().getDay} -{console.log:'test'} -{window.innerHeight} invece di {window:innerHeight} (specifica) o {js:window.innerHeight} - -il vantaggio di questo schema è che si evita un livello di parentesi annidate -quando sono coinvolte variabili jsonic: -{querySelector:var obj x:append} -che puo diventare -{querySelector:var {item} x:append} -LIMITE -questo metodo preclude l'accesso ad eventuali oggetti javascript var o data -SOLUZIONE -in realtà, var e data devono essere elementi definiti nel json -altrimenti non sono trovati dall'interprete che può vagliare l'esistenza -di una funzione js - -{path to a data} is a reference to a value in the data node of the Jsonic app -if the action context (do) -{path to an action} is a reference to a method or a sub app in the "parts" node of the Jsonic app -if the html rendering context (html) - -{window.f:var x} = window.f(jsonic.json.var.x) -{window.f:num} if is number -{window.f:array} if isArray (more than one parameter) -{window.f:'string'} - -{jsonic.f:var x} - -do: [ - "functionName": [] // parameters -] - -check if functionName is a function -html tags can't have a space or points... - -Align with ELIO Language: -1. "if": {"is": ["a", "=", "b","and"...] (retrocompatibile: se is è un array...) -2. "set": ["a", "+=", "1","*", "3"...] (retrocompatibile: se set è un array...) -3. "div classes": ... - -CODE REDUCING - -1. string in "html" object that starts with a tag and continue with classes - -"html": [ - "span appsDeviceListName ms-2 me-2 text-[16px] text-left w-[80%] leading-tight|content" -] - -NOTES - -// datapicker and other input fiels now are native https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date - -COMPONENTS - -MONACO TAILWINDCSS AUTOCOMPLETE (check Tailwindcss VS Code extensions) -https://github.com/remcohaszing/monaco-tailwindcss - - -FIREBASE STRUCTURE DATA - -If you create your own keys, they must be UTF-8 encoded, can be a maximum of 768 bytes, and cannot contain ., $, #, [, ], /, or ASCII control characters 0-31 or 127. You cannot use ASCII control characters in the values themselves, either. - -24.4KB gzipped (85.24KB minified) -25.2KB minified + gzipped in 100ms - -65ms 3G 3 Mbps (375 KBs) -10ms 4G 20 Mbps (2,5 MBs) -<1ms 5G/Fiber 200 Mbps (25 MBs) - -TEST - -tailwindcss -104 KB 105 ms - -INTEGRATIONS: -https://b2bsaasleads.com - -NEW PLUGINS: - -http://jakim.me/Toasty.js/ -https://tingle.robinparisi.com - -GUIDE: - -COMPONENTS: reusable components / architectural philosophy -ENGINE, (no hidden code) all the parts of the app is exposed to the developer / can set the layout and the behaviour -JSON E' il modello di struttura ad albero usato da JSONIC per descrivere i dati, lo stile, e le azioni dell'applicazione -SHORTCUTS: combinations of utility names (classes) to reuse in "class" property (from WindiCSS) - // preloaded js/css plugins - -{ - "attr": { - "class": "py-2 text-center" - }, - "subTitle": { - "lang": { - "it": "L'albero JSON dell'app può contenere i seguenti rami principali:", - "en": "The JSON app tree may contain the following main branches:", - "es": "El árbol de la aplicación JSON puede contener los siguientes ramas principales:" - } - } -}, - - -PROPERTIES - -With {property}, a string delimited by braces you can refer to any sub-branch the app tree and special properties. - ------------------------ -HOME PARAGRAPHS ------------------------ - -AUTO-LOADED PLUGINS - -NESTED CSS - -HTML has a clear nested and visual hierarchy but CSS doesn't. JSONIC let you nest your CSS definitions in a way that follows the same visual hierarchy of your HTML. It's similar to the SAAS extension but without the need to compile the code. In modo simile al linguaggio SAAS, è necessario compilare il codice - - - // BP - Questo dimostra che c'è bisogno di semplificazione più di quanto non si possa pensare - -IDE - -Special char (or shortener or autocomplete) with { } etcetera) - - -PRIORITY: - -tags: - -button: "title" -or -button: { - text: title - color: color - on: ... -} - -buttonOutline: { - text: title - color: color - on: ... -} - ------------------------- -qualunque metodo: -[ - {"path": args}, - {"path": args} - {"path": args} -] ------------------------- - - -DEBUG -class must be a string otherwise log error -style in attr must work (now error) - - -CONFIG (now setup) -extend the main branch {b:config} - -ACTIONS (now parts) -extend the main branch {b:actions} - -DO -execute one or an array of functions -"do": "actionID" (string) execute the actions.actionID function - -CONTAINER (now selector) -change the context to the element {b:container} -Can be an object like {id, class, data-value} -or a string with a CSS selector like "body > div:nt-child(2)" -or a jquery-like selector like "body > div:eq(2)" - ------------------------- - -bootstrap menu -> tailwind - ------------------------- - - -IDEAS - -- share the modules in the object "jsonic" with the other jsonic objects in the page -- jsonic.registerJsMethod(name, function) register new js method to be inserted in jsonic.methods and called with "method": {params} -- choose can contain the methods "next":"1" / "previous":"1" or step "+1"/"-1" -- calendar can return the object {lang: {...}} -- self.js can be embedded in self.compile (if typeof params == 'string') -- Page doesn't exist / if admin / want to create it? -- if no jsonic file for the page, create it on save - -- AUTH (debug) + GITHUB - -- preload font flag -- IDE: Wordpress API new page -- window methods in (docs) -- for -> addTag (?) -- setup: form to set setup properties -- Method ARRAY - -"array": { -"push": "{var:num}" (pop, shift, unshift, length) - -DONE: - -remove JSONIC references: jsonic.firebaseEventAction / jsonic.resizeEvent -- HOME: docs / examples / integrations -- wordpress: access to media API -- iconify -- iconify remove SVG old -- colors -> setup (mmm) (like logo) -- styles -> css -> senza categorie, solo elements '#div' -> https://transform.tools/css-to-js DONE -} - -BUGS: -- version è necessario in pluginsFunctions -- shortcut as a node: attr / class values doesn't overwrite the shortcut - -WORDPRESS: - -(_embed to your URL will add the wp:featuremedia) -https://jsonic.io/wp-json/wp/v2/media?&context=embed&per_page=100 -https://jsonic.io/wp-json/wp/v2/media?&context=embed&after=2017-11-07T00:00:00 -https://jsonic.io/wp-json/wp/v2/media?include=1681,491 - -// https://github.com/schlosser/pig.js - -NOTE: - -- autoupdate only if the previous update is complete (we need a param in config complete:true/false) -- Play (create your app!) -- add a tag in menu buttons ? -- inViewport -> 'enter'/'exit' ? -- inViewport solo la prima volta? -- ('on': 'in'/out NO) confirm 'init'? -- IDE: backup timeline -- duplicato di this.selector dedicata a ottenere il selector di un nuovo elemento (su append e poco altro) -- col: [1,2,3] -> row with col1 col2 col3 ? or tailwind grid solution (ragionare su soluzione di tag. esempio: flex: []) -- in examples, test in posizione assoluta sul codice (utile su mobile) - -KEY BENEFITS - -- Integration (Jsonic code includes the logic, the layout and the style of the app on in one JSON object) -- Accelerator - -*/ - -// JQUERY to Vanilla: https://youmightnotneedjquery.com | http://vanilla-js.com -// Jquery plus: https://atypiccraft.com/insights/reasons-why-we-still-use-jquery -// https://cyrilletuzi.github.io/javascript-guides/jquery-to-javascript.html -// Tools to integrate: https://bestofjs.org/tags -// MINIFY: https://closure-compiler.appspot.com/home -// https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=cat - -// INTEGRATIONS - -// https://www.dropzone.dev/js/ -// uploadcare -// zaiper - -// a graph js tool - -// anime.js -// transition.style // analogo ad animate.style - -/* There were issues affecting this run of Lighthouse: - -There may be stored data affecting loading performance in this location: IndexedDB. Audit this page in an incognito window to prevent those resources from affecting your scores. - -// UI - -https://windicss.org/play.html -https://basscss.com -https://twind.dev -https://emotion.sh/docs/introduction -https://cssinjs.org/?v=v10.8.2 - -https://picturepan2.github.io/spectre/ -https://get.foundation -https://ant.design/ -https://purecss.io -https://onsen.io/ -https://shuffle.dev/ -*/ - -//{"type": "js", "url":"https://cdn.jsdelivr.net/npm/tailwindcss@{version}/lib/index.min.js"}, - - -//$.fn.jsonic = function(options) {return new jsonicObject(options);}; -//jsonicApp = function(options) {return new jsonicObject(options);}; - - -var jsonAppObj = function(options) { - - var self = this; - console.log(); - - //this.options = options; - /* var json = { // the jsonic app tree - setup: {}, - blocks: {}, // to be removed - parts: {}, - // plugins: {}, // TO DO: remove the error if included - // css: {}, - do: {}, - on: {}, - shortcuts: {}, - texts: {}, - data: {}, - var: {} - }; */ - //var var = json.var; - //this.setup = json.setup; - // for external access - this.json = { - setup: {}, - blocks: {}, // to be removed - parts: {}, - // plugins: {}, // TO DO: remove the error if included - // css: {}, - functions: {}, - do: {}, - on: {}, - shortcuts: {}, - texts: {}, - data: {}, - var: {} - }; - this.app = this.json; - - //var json = self.json; // TO DO: remove - var alertObj = {}; - var alertValues = {}; - this.params = {}; // maybe can be removed - - this.javascriptReservedWord = ['abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield', 'Array', 'Date', 'eval', 'function', 'hasOwnProperty', 'Infinity', 'isFinite', 'isNaN', 'isPrototypeOf', 'length', 'Math', 'NaN', 'name', 'Number', 'Object', 'prototype', 'String', 'toString', 'undefined', 'valueOf', 'getClass', 'java', 'JavaArray', 'javaClass', 'JavaObject', 'JavaPackage', 'alert', 'all', 'anchor', 'anchors', 'area', 'assign', 'blur', 'button', 'checkbox', 'clearInterval', 'clearTimeout', 'clientInformation', 'close', 'closed', 'confirm', 'constructor', 'crypto', 'decodeURI', 'decodeURIComponent', 'defaultStatus', 'document', 'element', 'elements', 'embed', 'embeds', 'encodeURI', 'encodeURIComponent', 'escape', 'event', 'fileUpload', 'focus', 'form', 'forms', 'frame', 'innerHeight', 'innerWidth', 'layer', 'layers', 'link', 'location', 'mimeTypes', 'navigate', 'navigator', 'frames', 'frameRate', 'hidden', 'history', 'image', 'images', 'offscreenBuffering', 'open', 'opener', 'option', 'outerHeight', 'outerWidth', 'packages', 'pageXOffset', 'pageYOffset', 'parent', 'parseFloat', 'parseInt', 'password', 'pkcs11', 'plugin', 'prompt', 'propertyIsEnum', 'radio', 'reset', 'screenX', 'screenY', 'scroll', 'secure', 'select', 'self', 'setInterval', 'setTimeout', 'status', 'submit', 'taint', 'text', 'textarea', 'top', 'unescape', 'untaint', 'window', 'onblur', 'onclick', 'onerror', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onmouseover', 'onload', 'onmouseup', 'onmousedown', 'onsubmit']; - // Source: https://www.w3schools.com/js/js_reserved.asp - var nodes = { - //parts: ['text', 'div', 'ul', 'p', 'a', 'button', 'input', 'span', 'img', 'video', 'audio', 'source', 'figure', 'figcaption', 'textarea', 'iframe', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'svg', 'path', 'g', 'd', 'polygon', 'circle', 'small', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'form', 'form-group', 'label', 'select', 'option', 'optgroup', 'nav', 'tab', 'header', 'main', 'footer', 'ide', 'model-viewer', 'i', 'icon', 'pre', 'code','animateMotion','animateTransform','circle','clipPath','defs','desc','discard','ellipse','feBlend','feColorMatrix','feComponentTransfer','feComposite','feConvolveMatrix','feDiffuseLighting','feDisplacementMap','feDistantLight','feDropShadow','feFlood','feFuncA','feFuncB','feFuncG','feFuncR','feGaussianBlur','feImage','feMerge','feMergeNode','feMorphology','feOffset','fePointLight','feSpecularLighting','feSpotLight','feTile','feTurbulence','filter','foreignObject','g','hatch','hatchpath','image','line','linearGradient','marker','mask','metadata','mpath','path','pattern','polygon','polyline','radialGradient','rect','script','set','stop','switch','symbol','text','textPath','title','tspan','use','view'], - //functions: ['do', 'function', 'for', 'run', 'module', 'page', 'html', 'text', 'empty', 'alert', 'blocks', 'attr', 'color', 'set', 'array', 'replace', 'var', 'js', 'javascript', 'if', 'switch', 'choose', 'delay', 'ajax', 'hide', 'show', 'toggle', 'in', 'out', 'link', 'scroll', 'lang', 'find', 'data', 'reload', 'calendar', 'moment', 'dayjs', 'log', 'setInterval', 'clearInterval', 'offcanvas', 'firebase', 'database', 'qrcode', 'editor', 'ace', 'code', 'thunkable', 'animate', 'sortablejs', 'uiUpdate'], // 'String', 'Number', 'Math', - //functionsWithContainer: ['for', 'editor', 'ace', 'code', 'qrcode', 'lottie', 'animate', 'html', 'hide', 'show', 'toggle', 'in', 'out', 'if', 'ajax', 'attr', 'run', 'delay'], - // not execute - extend: ['setup', 'blocks', 'parts', 'css', 'actions', 'texts', 'data', 'functions'], // also plugins? (TO DO: remove actions) - params: ['style', 'on', 'matchMedia', 'action', 'code', 'roles', 'plugins', 'css'], // 'if', 'attr', 'text'. 'html' - exclude: ['setup', 'container', 'selector', 'info', 'note', 'comment', 'lang', 'tag', 'plugins', 'template'] - }; - - /* - * Converts a JSON object to a JSON Schema - * @param {any} json - * @param {object} options - * @returns {object} a json schema - */ - // [{"name": "vito", "gallery": {"name":2, "date":"10-10-2012"}, "num":3, "bool":true, "color": "#ff0000"}] - const FORMAT_REGEX = { - email: /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/, - url: /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, - ip: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, - // J. Meijer / Stackoverflow / 15491894 - date: /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/, - // Joey / Stackoverflow / 1636350 - color: /^#(?:[0-9a-fA-F]{3}){1,2}$|#(?:[0-9a-fA-F]{3,4}){1,2}$/, - }; - - this.jsonToSchema = function (json, options = {}) { - // https://github.com/mohsen1/json-to-json-schema - if (typeof json === 'function') { - throw new TypeError('Can not convert a function'); - } - - if (json === undefined) { - return {}; - } - - // primitives - if (typeof json === 'string') { - - if (FORMAT_REGEX.url.test(json)) return { type: 'string', format: 'url' }; - else if (FORMAT_REGEX.email.test(json)) return { type: 'string', format: 'email' }; - else if (FORMAT_REGEX.ip.test(json)) return { type: 'string', format: 'ip' }; - else if (FORMAT_REGEX.date.test(json)) return { type: 'string', format: 'date' }; - else if (FORMAT_REGEX.color.test(json)) return { type: 'string', format: 'color' }; - else return { type: 'string' }; - } - - else if (typeof json === 'boolean') return { type: 'boolean' }; - - else if (typeof json === 'number') { - if (Number.isInteger(json)) { - return { type: 'integer' }; - } else { - return { type: 'number' }; - } - } - - else if (Array.isArray(json)) { - let schema = { type: 'array' }; - - if (!json.length) { - schema.items = {}; - return schema; - } - - let schemas = json.map(self.jsonToSchema); - - // if all schemas are the same use that schema for items - if (schemas.every(s => self.isEqual(s, schemas[0]))) { - schema.items = schemas[0]; - - // if there are multiple schemas use oneOf - } else { - schema.items = { oneOf: unique(schemas) }; - } - - return schema; - } - - if (json === null) { - return { type: 'null' }; - } - - let schema = { type: 'object' }; - - if (!Object.keys(json).length) { - return schema; - } - - schema.properties = Object.keys(json).reduce((properties, key) => { - properties[key] = self.jsonToSchema(json[key]); - return properties; - }, {}); - - return schema; - }; - - this.isEqual = function (a, b) { - return (JSON.stringify(a) == JSON.stringify(b)); - }; - - - //var canvasElement = document.getElementById("canvas"); - // * this is not important for PDFMake, it's here just to render the result * - // It's a Mozilla lib called PDFjs that handles pdf rendering directly on the browser - /* this.pdfjs = function (params, selectorParams) { - - var url = params.url; - var options = params.options || { scale: 1.4 }; - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - var canvasContainer = self.query(container); - - function renderPage(page) { - var viewport = page.getViewport(options.scale); - var wrapper = document.createElement("div"); - wrapper.className = "canvas-wrapper"; - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - var renderContext = { - canvasContext: ctx, - viewport: viewport - }; - - canvas.height = viewport.height; - canvas.width = viewport.width; - wrapper.appendChild(canvas) - canvasContainer.appendChild(wrapper); - - page.render(renderContext); - } - - function renderPages(pdfDoc) { - for(var num = 1; num <= pdfDoc.numPages; num++) - pdfDoc.getPage(num).then(renderPage); - } - - PDFJS.disableWorker = true; - PDFJS.getDocument(url).then(renderPages); - - } */ - //renderPDF('https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf', document.querySelector('#canvas')); - /* this.localStorage = function (params) { - // -> use self.method - if (params.getItem) return localStorage.getItem(params.get); - else if (params.setItem) return localStorage.setItem(params.setItem.name, params.setItem.value); - } */ - // UTILITY - /** A storage solution aimed at replacing jQuerys data function. - * Implementation Note: Elements are stored in a (WeakMap)[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap]. - * This makes sure the data is garbage collected when the node is removed. - */ - this.dataStorage = { - _storage: new WeakMap(), - set: function (element, key, obj) { - if (!this._storage.has(element)) { - this._storage.set(element, new Map()); - } - this._storage.get(element).set(key, obj); - }, - get: function (element, key) { - return this._storage.get(element).get(key); - }, - has: function (element, key) { - return this._storage.has(element) && this._storage.get(element).has(key); - }, - remove: function (element, key) { - var ret = this._storage.get(element).delete(key); - if (!this._storage.get(element).size === 0) { - this._storage.delete(element); - } - return ret; - } - }; - - // JQUERY cross-over - this.extend = function (out) { - - if (typeof arguments[0] == 'boolean' && arguments[0] == true) - return deepExtend(out); - else { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - if (!arguments[i]) - continue; - - for (var key in arguments[i]) { - if (arguments[i].hasOwnProperty(key)) - out[key] = arguments[i][key]; - } - } - return out; - } - }; - - var deepExtend = function (out) { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - var obj = arguments[i]; - - if (!obj) continue; - - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - if (typeof obj[key] === "object" && obj[key] !== null) { - if (obj[key] instanceof Array) out[key] = obj[key].slice(0); - else out[key] = deepExtend(out[key], obj[key]); - } else out[key] = obj[key]; - } - } - } - - return out; - }; - - /* this.actionResult = function(value, args) { // value -> params - - // Methods with a result - - if (value && typeof value == 'object') { - - // jsonic methods - if (value.js) { - return self.js(value.js, args); - } else if (value.array) { - return self.array(value.array, args); - } else if (value.calendar) { - return self.calendar(value.calendar, args); - } else if (value.data) { - return self.data(value.data, args); - } else if (value.var) { - return self.var(value.var, args); - } else if (value.module) { - return self.module(value.module, args); - } else if (value.color) { - return self.color(value.color, args); - } else if (value.css) { - return self.css(value.css, undefined, args); - } else if (value.if) { - return self.if(value.if, undefined, args); - } else if (value.switch) { - return self.switch(value.switch, args); - } else if (value.database) { - return self.database(value.database, args); - // js methods - } else if (value.Math) { - return self.Math(value.Math, args); - } else if (value.Number) { - return self.Number(value.Number, args); - } else if (value.String) { - return self.String(value.String, args); - // plugin methods - } else if (value.ace) { - return self.ace(value.ace, args); - // else if (value.code) { - // return self.code(value.code, args); - } else if (value.moment) { - return self.moment(value.moment, args); - } else if (value.dayjs) { - return self.dayjs(value.dayjs, args); - } else if (value.function) { // TO DO: remove (replaced by do) - return self.function(value.function, value.params); - } else { - return value; - } - } else { - return value - } - //} else if (typeof value == 'string') { - // return self.javascript(value, args); - - } */ - this.var = function (params, args) { - - - if (Array.isArray(params)) { - for (var index in params) - self.var(params[index], args); - } else { - - //self.log('var'); - var name; - var value; - var varValue; - - if (params.path && !params.name) - name = self.path(params.path, args, '.'); - - if (typeof params == 'string') { - // gives a variable value - name = self.replaceProperties(params, args); - /* self.log('name'); - self.log(name); */ - /* self.log('typeof params == string'); - self.log('params'); - self.log(params); - self.log('name'); - self.log(params); */ - varValue = self.docElement('self.json.var.' + name); - - /* self.log('varValue'); - self.log(varValue); */ - } else { - - /* self.log('var'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - //self.log('params'); - //self.log(params); - var paramsReplaced = self.replaceProperties(params, args); - //self.log('paramsReplaced'); - //self.log(paramsReplaced); - name = paramsReplaced.name; - value = paramsReplaced.value; - var operator = paramsReplaced.operator; - var type = paramsReplaced.type; - - /* self.log('extend'); - self.log(extend); */ - if (name) { - var pathString = 'self.json.var.' + name; - var pathLast = pathString.substr(pathString.lastIndexOf(".") + 1); - var pathBase = pathString.substr(0, pathString.lastIndexOf(".")); - var varObj = self.docElement(pathBase); - - /* self.log('name'); - self.log(name); - self.log('pathBase'); - self.log(pathBase); - self.log('pathLast'); - self.log(pathLast); - self.log('varObj'); - self.log(varObj); */ - if (value !== undefined) { - - //if (value == 'string') - // value = self.docElement('self.json.var.'+value); // todo - //else - value = self.actionResult(value, args); - - // typization - switch (type) { - case 'string': value = String(value); break; - case 'number': value = Number(value); break; - case 'boolean': value = Boolean(value); break; - case 'array': value = JSON.parse(value); break; - case 'object': value = JSON.parse(value); break; - } - - //self.log('value'); - //self.log(value); - /* - // reset - if (value == undefined && typeof value == 'string') value = ''; - if (value == undefined && typeof value == 'number') value = 0; - if (value == undefined && typeof value == 'object') value = {}; */ - /* self.log('operator'); - self.log(operator); - self.log('pathLast'); - self.log(pathLast); - self.log('varObj[pathLast]'); - self.log(varObj[pathLast]); */ - if (varObj && pathLast) { - switch (operator) { - case '+=': varObj[pathLast] += value; break; - case '-=': varObj[pathLast] -= value; break; - case '/=': varObj[pathLast] /= value; break; - case '*=': varObj[pathLast] *= value; break; - default: varObj[pathLast] = value; break; - } - - /* operators: [ - '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', - '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%', - '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=', - '%=', '<<=', '>>=', '>>>=' - ], */ - //self.log('varObj[pathLast]'); - varValue = varObj[pathLast]; - } else { - /* self.log('pathString'); - self.log(pathString); */ - //varValue = self.docElement(pathString, value); - //varValue = value; - self.docElement(pathString, value); - - /* self.log('name'); - self.log(name); - - self.log('var '+name); - self.log(self.var(name)); */ - } - - /* self.log('pathLast'); - self.log(pathLast); - self.log('varObj[pathLast]'); - self.log(varObj[pathLast]); */ - /* //alert(value); - //value = self.replaceProperties(value, args); - if (value == 'string') { - //self.json.var[name] = self.docElement('self.json.var.'+value); - varObj[pathLast] = self.docElement('self.json.var.'+value); - } else { - //self.json.var[name] = self.actionResult(value, args); - varObj[pathLast] = self.actionResult(value, args); - } */ - //self.log('varObj[pathLast]'); - //if (self.isJson(self.json.var[name])) - // self.json.var[name] = self.parse(self.json.var[name]); - } else if (paramsReplaced.push) { - if (varObj && pathLast && varObj[pathLast]) { - varObj[pathLast] = varObj[pathLast].push(paramsReplaced.push); - varValue = varObj[pathLast]; - } - } else if (paramsReplaced.extend) { - if (varObj && pathLast && varObj[pathLast]) { - varObj[pathLast] = self.extend({}, varObj[pathLast], paramsReplaced.extend); - varValue = varObj[pathLast]; - } - } else { - // no "value" property: return the value of the var "name" - varValue = varObj[pathLast]; - /* varValue = self.replaceProperties(varObj[pathLast], args); - alert(JSON.stringify(varValue)); */ - } - - //varValue = self.json.var[name] || {}; // to check - } else { - self.log('var name undefined'); - self.log(params); - varValue = undefined; - } - - if (params.do && params.do.length > 0) { - self.log('this.var params.do'); - self.log(params.do); - //alert(JSON.stringify(params.do)); - //self.do(params.do, args); - self.do(params.do, undefined, args); - } - - } - - return varValue; - - } - }; - - this.find = function (params, args) { - if (params.in) { - var list = self.replaceProperties(params.in, args); - return list.filter(function (item) { - if (params.value) { - if (typeof params.value == 'string') { - if (JSON.stringify(item).indexOf(params.value) >= 0) - return item; - } else { // if (typeof params.value == 'string') { - for (var key in params.value) { - if (params.value[key] == item[key]) - return item; - } - } - } - }); - } - }; - - /* this.data = function (params, args) { - if (typeof params == 'string') - return self.db(params, args); - else - self.firebase(params, args); - } */ - this.array = function (params, args) { - /* self.log("---- this.array ----"); - self.log('params'); - self.log(params); */ - if (args) - params = self.replacePropertyWithPrefix(params, 'result', args); - - for (var par in params) { - var paramReplaced = self.replaceProperties(params[par], args); - //value[par](params[par]) // ipotesi di eseguire in automatico qualunque funzione js su stringhe - /* self.log("par"); - self.log(par); - self.log("params[par]"); - self.log(params[par]); - self.log("paramReplaced"); - self.log(paramReplaced); */ - params[par] = paramReplaced; - } - - //self.log("params"); - //self.log(params); - var value = self.element({ path: params.name }) || []; - /* self.log("value"); - self.log(...value); */ - if (params.push) { - if (Array.isArray(params.push)) - value.push(...params.push); - - else - value.push(params.push); - - } - if (params.unshift) value.unshift(...params.unshift); - if (params.pop) return value.pop(params.pop); - if (params.shift) return value.shift(params.shift); - - self.element({ path: params.name, value: value }); - - }; - - this.replace = function (params, args) { - // self.log("---- this.replace ----"); - params = self.replacePropertyWithPrefix(params, 'result', args); - /* self.log("params"); - self.log(params); */ - var value = self.element({ path: params.path }) || []; - var to = params.to || ''; - - var type = typeof value; - /* self.log("type"); - self.log(type); */ - if (type !== "string") value = JSON.stringify(value); - /* self.log("value 1"); - self.log(value); */ - if (params.from) value = self.replaceAll(value, params.from, to); - /* self.log("value2 "); - self.log(value); */ - switch (type) { - case "number": - value = Number(value); - break; - case "boolean": - value = Boolean(value); - break; - case "object": - value = JSON.parse(value); - break; - } - /* self.log("value 3"); - self.log(value); */ - //return value; - return self.element({ path: params.path, value: value }); - - }; - - - this.unshift = function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.unshift(value); - self.element({ path: path, value: obj }); - } - } - }; - - this.set = function (params, args) { - - if (Array.isArray(params)) { // 1.0.5 - for (var obj of params) - self.set(obj, args); - } else { - for (var param in params) { - - var value = params[param]; - - if (value) value = self.replaceProperties(value, args, false); // TO DO: check - if (value && args) value = self.replacePropertyWithPrefix(value, 'result', args); // backward compatibility TO DO: remove - - self.element({ path: param, value: value }); - } - } - - //return true - }; - - - this.get = function (element) { - //self.log('self.get'); - if (element.startsWith('\'')) - return String(element.match(/\'([^\']*)\'/)[1]); // stringa racchiusa tra apici (serve?) - else if (element.startsWith('Boolean')) - return Boolean(element.match(/Boolean\(([^\)]*)\)/)[0]); // Boolean(x) - else if (element.startsWith('Number')) - return Number(element.match(/Number\(([^\)]*)\)/)[0]); // Number(x) - else if (element.startsWith('String')) - return String(element.match(/String\(([^\)]*)\)/)[0]); // String(x) - - else - return (self.docElement(element)); // ora le tipizzazioni sono già in docElement grazie a eval - }; - - this.getJSON = function (url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'json'; - xhr.onload = function () { - var status = xhr.status; - if (status === 200) { - callback(null, xhr.response); - } else { - callback(status, xhr.response); - } - }; - xhr.send(); - }; - - /*--------------------- - var - ---------------------*/ - var database, auth, storage; - this.listeners = {}; - this.resizeActions = {}; - - /* var iconsFile; - - this.device = false; // touch device - this.touch = 'mousedown'; if (this.device) {this.touch = 'touchstart';} - - var animations = {}; - var tweenLoading; - - var tasksIntervals = {}; - var timedTasks = {'yearly':{},'monthly':{},'daily':{},'hourly':{}, '10mins':{}, '5mins':{}, '30mins':{}, '1min':{}, '30sec': {}, '10sec': {}, '1sec': {}}; */ - /* this.dateSelection; // = {day:0, month:0, year:0}; - this.timeSelection = {hour:0, min:0, sec:0, ampm:'AM', allday:true}; - this.timeSelectionCallback = null; */ - /*-------------------- - FIREBASE - --------------------*/ - //var firebaseInitialized = false; - this.firebaseVerifyUser = function (data) { - self.log('firebaseVerifyUser'); - //self.log(data); - //self.log(data.code); - if (self.params.oobCode) { - var oobCode = self.params.oobCode; - - auth.applyActionCode(oobCode).then(function (resp) { - // self.log('resp'); - // self.log(resp); - self.alert({ - //toast: true, - icon: "success", - title: "titVerifyEmail", - html: "msgVerifyEmail", - confirmButtonText: "btnOk", - //showCancelButton: false, - confirm: function () { - //self.reload(); - // self.do(data); - window.location.href = "/app/index.html"; - } - }); - }).catch(function (error) { - self.log('error'); - self.alert({ - icon: "error", - title: "titWarning", - html: error.code + " - " + error.message, - confirmButtonText: "btnOk", - //showCancelButton: false, - confirm: function () { - // self.reload(); - // self.do(data); - window.location.href = "/app/index.html"; - } - }); - }); - // verifica su auth - } - //data.code / data.params.code - //self.do(data); - self.do(data); - }; - - /* this.firebaseInit = function (data) { - self.log("firebaseInit"); - - if (json.setup && json.setup.firebase) { - //var.databaseURL = json.setup.firebase.databaseURL; - - firebase.initializeApp(json.setup.firebase); - database = firebase.database(); - auth = firebase.auth(); - // if (self.json.plugins['firebase-storage'].active) OR find in self.json.plugins name: 'firebase-storage' - //storage = firebase.storage(); - - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - // No user logged in - self.log('onAuthStateChanged:GUEST\n'); - // non bisognerebbe chiedere sempre di fare login - } else { - // User logged in - self.log('onAuthStateChanged:USER\n'); - self.log('name: '+self.user('displayName') + '\nemail: '+user.email + '\nuid: '+ user.uid); - } - //self.log('firebaseInitialized'); - //self.log(firebaseInitialized); - if (!firebaseInitialized) { - firebaseInitialized = true; - self.do(data); - } - }); - } else { - self.do(data); - } - } */ - this.sendMail = function (data) { - self.log('sendMail'); - - var emailParams = { - Host: "smtp.mailgun.com", - Username: "vito@nuvolaria.com", - Password: "bee02191be84c784a665fa98c61e03ce-915161b7-d32cb9d0", - From: data.from, - To: data.to, - Subject: data.subject, - Body: data.html - }; - - Email.send(emailParams).then( - message => self.alert({ - icon: 'success', - title: 'titEmailSuccess', - confirmButtonText: 'btnClose' - }) - ); - - /* - "from": "gianfrancoguglielmi@gmail.com", - "to": "vito.minchilli@gmail.com", - "subject": "Prova oggetto", - "html": "Prova testo", - "text": "Prova testo" -*/ - /* - var SERVER_NODEJS_BASEURL='https://app.fixo.io:4002'; - - var params = { - rom: data.from, - to: data.to, - subject: data.subject, - html: data.html, - text: data.text - }; - - $.ajax({ - type: "POST", - 'beforeSend': function(xhr) { - xhr.setRequestHeader('Accept', 'application/json'); - xhr.setRequestHeader('Content-Type', 'application/json'); - }, - data: JSON.stringify(params), - url: SERVER_NODEJS_BASEURL + '/sendMail', - success: function(data) { - self.log('sendMail SUCCESS'); - self.log(data); - self.do(data); - }, - error: function(error) { - self.log('sendMail ERROR'); - self.log(error); - self.do(data); - } - }); - */ - }; - - //var multipleFiles = []; - /* this.fileDownload = function (url) { - self.log('fileDownload'); - self.log(url); - - var fileArr = url.split('?'); - self.log(fileArr); - //var file = fileArr[0]; - var urlArr = fileArr[0].split('/'); - self.log(urlArr); - var name = urlArr[urlArr.length-1]; - self.log(name); - var token = self.getParameterByName('token', url); - self.log(token); - - window.location.href = '/app/php/proxy.php?name='+ name + '&url='+ url; - - } */ - /* this.fileUrl = function (params) { - // da nome file a l'url Firebase Storage inclusiva del token - self.log('fileUrl'); - self.log(params); - // self.log('storage'); - // self.log(storage); - if (storage) { - var storageRef = storage.ref(); - var pathReference = storageRef.child(params.user+'/'+params.name); - - pathReference.getDownloadURL().then(function(url) { - if (params.callback) params.callback(url); - }).catch(function(error) { - if (error && error.code && params.error) { - self.log(self.firebaseStorageError(error.code)); - params.error(error.code); - } - // A full list of error codes is available at - // https://firebase.google.com/docs/storage/web/handle-errors - }); - } else { - self.log('storage undefined'); - } - } */ - /* this.firebaseStorageError = function (errorCode) { - switch (errorCode) { - case 'storage/object-not-found': - // File doesn\'t exist - return 'File doesn\'t exist'; - case 'storage/unauthorized': - // User doesn\'t have permission to access the object - return 'User doesn\'t have permission to access the object'; - case 'storage/canceled': - // User canceled the upload - return 'User canceled the upload'; - case 'storage/unknown': - // Unknown error occurred, inspect the server response - return 'Unknown error occurred, inspect the server response'; - default: - return 'No error' - } - } */ - var x = [{ if: 3 }, function () { }, 3, []]; - - this.firebaseAddListener = function (params) { - /* self.log('firebaseAddListener'); - self.log(params); */ - // {path, orderByChild, equalTo} - //self.log(params.path); - if (database) { - // Aggiunge listener in ascolto su params.path che esegue params.action - if (params.action) { - if (!self.listeners[params.path]) self.listeners[params.path] = []; - /* alert('params.action:'+params.action); - alert('type params.action:' + typeof params.action); - alert(params.path+':'+JSON.stringify({ - action: params.action - })); */ - //if (Array.isArray(params.action)) - // self.listeners[params.path].concat(params.action); - //else - self.listeners[params.path].push(params.action); - } - /* if (params.success !== undefined) { - alert('params.success:'+params.success); - alert('type params.success:' + typeof params.success); - alert(params.path+':'+JSON.stringify({ - success: params.success - })); - self.listeners[params.path].push(params.success); - } */ - //self.log('params.path: '+ params.path); - //self.listeners[params.path] = params.action; - //alert(self.listeners[params.path]); - /* - - limitToFirst() Sets the maximum number of items to return from the beginning of the ordered list of results. - limitToLast() Sets the maximum number of items to return from the end of the ordered list of results. - - startAt() Return items greater than or equal to the specified key or value, depending on the order-by method chosen. - startAfter() Return items greater than the specified key or value depending on the order-by method chosen. - endAt() Return items less than or equal to the specified key or value, depending on the order-by method chosen. - endBefore() endBefore() Return items less than the specified key or value depending on the order-by method chosen. - equalTo() Return items equal to the specified key or value, depending on the order-by method chosen. - - orderByChild() Order results by the value of a specified child key or nested child path. - orderByKey() Order results by child keys. - orderByValue() Order results by child values. - orderByPriority() Order results by priority - - https://firebase.google.com/docs/reference/js/v8/firebase.database.Query - - */ - //Firestore.collection(collectionName).orderBy(field).where(field, ">=", keyword.toUpperCase()).where(field, "<=", keyword.toUpperCase() + "\uf8ff").get() - // https://medium.com/feedflood/filter-by-search-keyword-in-cloud-firestore-query-638377bf0123 - // https://firebase.google.com/docs/database/rest/retrieve-data?hl=it#range-queries - // startAt , endAt , limitToFirst , limitToLast o equalTo - //databaseReference.orderByChild('_searchLastName').startAt(queryText).endAt(queryText+"\uf8ff") - // where ("string, "in"/"not-in", array) - // https://firebase.google.com/docs/firestore/query-data/queries?hl=it#in_and_array-contains-any - var dbRef = database.ref(params.path); - dbRef.off(); - if (params.orderByChild) dbRef = dbRef.orderByChild(params.orderByChild); - if (params.orderByKey) dbRef = dbRef.orderByKey(params.orderByKey); - if (params.orderByValue) dbRef = dbRef.orderByValue(params.orderByValue); - if (params.equalTo) dbRef = dbRef.equalTo(params.equalTo); - if (params.startAt) dbRef = dbRef.startAt(params.startAt); - if (params.startAfter) dbRef = dbRef.startAfter(params.startAfter); - if (params.endAt) dbRef = dbRef.endAt(params.endAt); - if (params.endBefore) dbRef = dbRef.endBefore(params.endBefore); - if (params.limitToFirst) dbRef = dbRef.limitToFirst(params.limitToFirst); - if (params.limitToLast) dbRef = dbRef.limitToLast(params.limitToLast); - if (params.where) dbRef = dbRef.where(params.where[0], params.where[1], params.where[2]); // maybe params.where in enough - - var feedback = dbRef.on('value', firebaseEvent); - //console.log(feedback); - /* console.log('dbRef'); - console.log(dbRef); - */ - /* if (params.orderByChild && params.equalTo) - dbRef.orderByChild(params.orderByChild).equalTo(params.equalTo).on('value', firebaseEvent); - else - dbRef.on('value', firebaseEvent); */ - } else { - self.log('database undefined'); - // Restart the db - } - }; - - var firebaseEvent = function (snapshot) { - console.log(snapshot.val()); - var ref = snapshot.ref; - if (snapshot.val() !== undefined) { - var dbVal = snapshot.val(); - var path = snapshot.ref.toString(); - //if (!dbVal) dbVal = {}; - var pathArr = path.split(/\.\w+\//); - var dbPath = pathArr[1]; - self.log('firebaseEvent: ' + dbPath); - //if (var.databaseURL) dbPath = path.substr(var.databaseURL.length+1); - //else dbPath = path; - /* self.log('path: '+ path); - //self.log('var.databaseURL: '+ var.databaseURL); - self.log('dbPath: '+ dbPath); */ - if (dbVal) - self.localDbUpdate(dbVal, dbPath); - else { - var dbObj = self.element({ path: 'self.json.var.db.' + self.replaceAll(dbPath, '/', '.') }); - if (dbObj) - dbObj = null; - //delete dbObj; - } - - - //self.do(self.listeners[dbPath], dbVal); - } - }; - - this.localDbUpdate = function (newObj, dbPath) { - /* self.log('localDbUpdate'); - self.log(newObj); - self.log(dbPath); */ - //var path = newObj.path; - //delete newObj.path; - /* self.do( - { - var: { - name: "db."+self.replaceAll(dbPath, '/', '.'), - value: newObj, - //success: function () { - // self.do(self.listeners[dbPath], newObj); - //} - } - } - ); */ - //alert('db.'+self.replaceAll(dbPath, '/', '.')); - /* var dbUpdateAction = { - var: { - name: 'db.'+self.replaceAll(dbPath, '/', '.'), - value: newObj - //do: (self.listeners[dbPath] && self.listeners[dbPath].length > 0) ? self.listeners[dbPath] : undefined - } - }; - if (self.listeners[dbPath] !== undefined && self.listeners[dbPath] !== null && self.listeners[dbPath].length > 0) - dbUpdateAction.var.do = self.listeners[dbPath]; - - newObj.path = dbPath; - - self.do(dbUpdateAction, newObj); */ - // TO DO: decide l'utente dove salvare i dati - newObj = Object.fromEntries(Object.entries(newObj).reverse()); - - //newObj = Object.keys(newObj).reverse(); - self.element({ path: 'self.json.var.db.' + self.replaceAll(dbPath, '/', '.'), value: newObj }); - if (self.listeners[dbPath] !== undefined && self.listeners[dbPath] !== null && self.listeners[dbPath].length > 0) { - newObj.path = dbPath; - if (self.listeners[dbPath]) { - self.methods.firebaseEvent.action(newObj); - //self.do(self.listeners[dbPath], newObj); - self.do(self.listeners[dbPath], undefined, newObj); - } - } - - - }; - - - - this.firebaseRemoveListener = function (params) { - // Rimuove listener in ascolto su data.path - self.log('firebaseRemoveListener'); - if (self.listeners[params.path]) { - delete self.listeners[params.path]; - var dbRef = database.ref(params.path); - dbRef.off(); - } - }; - - // Rimuove un elemento del database - this.firebaseRemove = function (path, callback) { - self.log('firebaseRemove'); - self.log(path); - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.remove(function (error) { - //Dati impostati con successo - if (error == null) { - self.log('set SUCCESS'); - result = { success: true }; - } else { - self.log('set ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - // Write or replace data to a defined path - this.firebaseSet = function (path, value, callback) { - /* - set Write or replace data to a defined path, like messages/users/ - update Update some of the keys for a defined path without replacing all of the data - push Add to a list of data in the database. Every time you push a new node onto a list, your database generates a unique key, like messages/users// - transaction Use transactions when working with complex data that could be corrupted by concurrent updates - */ - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.set(value, function (error) { - //Dati impostati con successo - if (error == null) { - self.log('set SUCCESS'); - result = { success: true }; - } else { - self.log('set ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - // Update some of the keys for a defined path without replacing all of the data - this.firebaseUpdate = function (path, value, callback) { - self.log('firebaseUpdate'); - self.log('path'); - self.log(path); - self.log('value'); - self.log(value); - - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.update(value, function (error) { - //Dati impostati con successo - if (error == null) { - self.log('update SUCCESS'); - result = { success: true }; - } else { - self.log('update ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - // Add to a list of data in the database. Every time you push a new node onto a list, your database generates a unique key, like messages/users// - this.firebasePush = function (path, value, callback) { - self.log('firebasePush'); - self.log(path); - - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.push(value, function (error) { - //Dati impostati con successo - if (error == null) { - self.log('push SUCCESS'); - result = { success: true }; - } else { - self.log('push ERROR'); - //Errore inserimento dati - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - - - // https://firebase.google.com/docs/database/security/rules-conditions - // tutte le get / o listeners / potrebbero essere basate su orderByChild("owner") - /* - rooms": { - // this rule applies to any child of /rooms/, the key for each room id - // is stored inside $room_id variable for reference - "$room_id": { - "topic": { - // the room's topic can be changed if the room id has "public" in it - ".write": "$room_id.contains('public')" - } - } - } - */ - /* this.firebaseQuery = function(params) { - self.log('firebaseQuery'); - self.log(params); - // path = 'users/'+self.user('email') - // value = 'guest' - var dbRef = database.ref(params.path); - - if (!params.result) params.result = {}; - if (params.value && !Array.isArray(params.value)) { - var buffer = params.value; - params.value = []; - params.value[0] = buffer; - } - //self.log('params.value'); - //self.log(params.value); - if (params.value && params.value.length > 0) { - var value = params.value.shift(); - //self.log('value'); - //self.log(value); - //self.log('params.key'); - //self.log(params.key); - dbRef.orderByChild(params.key).equalTo(value).once('value', (object) => { - self.log('object'); - self.log(object); - if(object) { - params.result = self.extend(params.result, object.val()); - if (params.value.length > 0) - self.firebaseQuery(params); - else - params.callback({ - success: true, - error: null, - data: params.result - }); - } else { - //self.log('firebaseQuery ERROR'); - //result = {success:false, error:8}; - params.callback({ - success:true, - error:null, - data: params.result - }); - } - }); - } else { - params.callback({success:false, error:null}); - } - } */ - this.firebaseGetPart = function (params) { - self.log('firebaseGetPart'); - let remotePath = self.replaceAll(params.localPath, '.', '/'); - - self.log('localPath:' + params.localPath); - //self.log('remotePath:'+remotePath); - if (self.partContainers[params.localPath]) { - self.partContainers[params.localPath].push(params); - } else { - self.partContainers[params.localPath] = []; - self.partContainers[params.localPath].push(params); - - dbRef = database.ref().child(remotePath); - - return dbRef.once('value').then(function (object) { - //Dati recuperati con successo - if (object) { - self.log('firebaseGetPart SUCCESS'); - self.log(object); - // local db update - if (object.val() !== undefined) { - window.dbVal = object.val(); - var dbVal = object.val(); - self.log('dbVal'); - self.log(dbVal); - if (dbVal !== null) { - let fullPath = object.ref.toString(); - let pathArr = fullPath.split(/\.\w+\//); // split on the domain extension - let dbPath = pathArr[1]; // path after the domain extension - let localPath = self.replaceAll(dbPath, '/', '.'); - //var dbPath = path.substr(var.databaseURL.length+1); - self.log('dbPath: ' + dbPath); - self.log('localPath: ' + localPath); - //self.log('self.partContainers[localPath]'); - //self.log(self.partContainers[localPath]); - self.element({ path: localPath, value: dbVal }); - for (partObj of self.partContainers[localPath]) { - /* self.log('partObj'); - self.log(partObj); */ - let part = self.replacePropertyWithPrefix(dbVal, 'setup', partObj.setup); - part = self.replacePropertyWithPrefix(part, 'arg', partObj.arg); - self.extendJsonFromElement(part); // or selectorParams - - - /* self.log('part'); - self.log(part); */ - self.html(part, partObj.container); - //self.run(part, partObj.container); - //self.run(dbVal, container); - } - } - } - } else { - self.log('firebaseGetPart ERROR'); - result = { success: false, error: 8 }; - } - //self.log(result); - //callback(result); - }); - } - }; - - - /* { - "database": { - "do": "get", - "path": "apps/dev/{setup:key}", - "on": { - "success": [ - { */ - this.firebaseIncrease = function (params) { - console.log('firebaseIncrease'); - self.firebaseGet(params.path, function (result) { - console.log(result); - if (result.success) { - if (result.data === null || result.data === undefined || typeof result.data == 'number') { - var counter = Number(result.data) + 1; - console.log('counter:' + counter); - self.firebaseSet(params.path, counter, function (result) { - if (result.success) { - self.log('firebaseIncrease SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - }); - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - }); - }; - - this.firebaseGet = function (path, callback) { - self.log('firebaseGet:' + path); - var result = { success: false, error: 7 }; - if (path) { - // try, if path is wrong "Uncaught TypeError: Cannot read properties of undefined (reading 'ref')" - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - - /* if (false) { //path == 'files') { - //alert(self.user('email')); - return dbRef.orderByChild('users/'+self.user('email')).equalTo('guest').on('value', (object) => { - //return dbRef.orderByChild('prefs/authorId').equalTo(self.user('uuid')).on('value', (object) => { - //return dbRef.orderByChild('users').equalTo(self.user('email')).on('value', (object) => { - //self.log(object); - //var user = object.val(); - //Dati recuperati con successo - if(object) { - result = {success:true, error:null, data: object.val()}; - } else { - self.log('get ERROR'); - //Errore recupero dati - result = {success:false, error:8}; - } - //self.log(result); - callback(result); - }); - } else { */ - // ATTENZIONE: va intercettato e loggato l'errore di accesso negato dalle regole - return dbRef.once('value').then(function (object) { - //Dati recuperati con successo - if (object) { - self.log('get SUCCESS'); - result = { success: true, error: null, data: object.val() }; - - // local db update - if (object.val() !== undefined) { - var dbVal = object.val(); - var path = object.ref.toString(); - if (!dbVal) dbVal = {}; - var pathArr = path.split(/\.\w+\//); // split on the domain extension - var dbPath = pathArr[1]; // path after the domain extension - - //var dbPath = path.substr(var.databaseURL.length+1); - self.log('dbPath: ' + dbPath); - self.localDbUpdate(dbVal, dbPath); - } - } else { - self.log('get ERROR'); - //Errore recupero dati - result = { success: false, error: 8 }; - } - //self.log(result); - callback(result); - }); - - //} - }; - - this.stringToKey = function (str) { - return str.replace(/\./g, '%2E'); - }; - - this.keyToString = function (key) { - return key.replace(/%2E/g, '.'); - }; - - this.firebaseKey = this.getKey = function (path) { - var dbRef = database.ref(path); - return dbRef.child(path).push().getKey(); - }; - - // -------------- - // SELECTOR - // -------------- - this.exist = function (selector) { - console.log('selector'); - console.log(selector); - console.log(Boolean(self.query(selector))); - return Boolean(self.query(selector)); - }; - - this.count = function (selector) { - //self.log('count:'+selector+ '='+ self.queryAll(selector).length); - return self.queryAll(selector).length; - - /* if (selector) { - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - var route = routes[index]; - - //onsole.log('route'); - //self.log(route); - - var routeParts = route.match(/(.*):eq\((\d*)\)/); - - //self.log('routeParts'); - //self.log(routeParts); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - element = element.querySelectorAll(routeElement)[routeIndex]; - - - } else { - element = element.querySelectorAll(route)[0]; - } - } */ - /* var elements = self.query(selector); - if (elements) - return elements.querySelectorAll().length; - else - return 0 */ - /* if (self.exist(selector)) - return document.querySelectorAll(selector).length; - else - return 0 */ - }; - - var log = function (id, value) { - self.log(id); - self.log(value); - }; - - this.classSelector = function (selClass) { - if (selClass.indexOf('.') == 0) { selClass = String(selClass).substr(1); } // backward compatibility - let classes = selClass.split(' '); - selClass = classes[0]; - /* self.log('selClass'); - self.log(selClass); */ - // avoid dynamic classes as selector - var regex = new RegExp('[\-][\[]'); - if (selClass && selClass.match(regex)) selClass = classes[1]; - if (selClass && selClass.match(regex)) selClass = classes[2]; - return selClass; - }; - - this.selector = function (params, containerParams, selectAll) { - // {container, class, value, id} - var selector; - - if (params) { - - if (typeof params == 'string') { - /* self.log('this.selector'); - self.log(params); */ - return params; - } else if (Array.isArray(params)) { - return params; - } else { - var selContainer; - - if (params.selector || params.container) - selContainer = params.selector || params.container; - - else if (containerParams) - selContainer = containerParams.selector || containerParams.container; - - //var selContainer = container; //data.container; - var attr = (params.attr) ? params.attr : {}; - var selId = (attr.id) ? attr.id : params.id; - var selClass = (attr.class) ? attr.class : params.class; - var selValue = (attr.value) ? attr.value : params.value; - var selDataValue = (attr['data-value']) ? attr['data-value'] : params['data-value']; - selValue = selDataValue || selValue; - if (selId) selId = self.replaceProperties(selId); - if (selValue) selValue = self.replaceProperties(selValue); - if (selClass) selClass = self.replaceProperties(selClass); - /* if (selId) selId = self.compile(selId); - if (selValue) selValue = self.compile(selValue); - if (selClass) selClass = self.compile(selClass); */ - // use the first class as selector - if (selClass) - selClass = self.classSelector(selClass); - - //if (!selectAll) selClass = undefined; - if (selId) { - selector = '#' + selId; - } else if (selValue && selClass) { - selector = '.' + selClass + '[data-value="' + selValue + '"]'; - } else if (selValue && params.tag) { - selector = params.tag + '[data-value="' + selValue + '"]'; - } else if (selClass && selectAll) { - selector = '.' + selClass; - - //if (!selectAll) - // selector += ':eq(' + self.count(selector) + ')'; - // qui c'è / c'era un baco: - // quando proviamo a eseguire un'azione su un elemento esistente - // usando solo la classe come selector, $(selector).length = 1 - // quindi prova a selezionare il secondo elemento eq(1), non il primo eq(0) - } else if (params.tag) { - //if (selContainer) selector = selContainer; - selector = params.tag; - if (selContainer) { - selector = selContainer + ' > ' + params.tag; - if (!selectAll) { - - //if (count !== $(selector).length) self.log('>> '+ selector + ' count:'+ self.count(selector) + ' !== ' + $(selector).length ); - selector += ':eq(' + self.count(selector) + ')'; - //selector += '[' + self.count(selector) + ']'; - //selector += ':eq(' + $(selector).length + ')'; - } - } else { - if (!selectAll) { - selector += ':eq(' + self.count(selector) + ')'; - //selector += '[' + self.count(selector) + ']'; - } - } - } else { - selector = selContainer; - }; - - } - return selector; - } - }; - - // -------------- - // TEXTS - // -------------- - this.stringify = function (obj) { - if (typeof obj == 'object') - try { - return JSON.stringify(obj); - } catch (error) { - return obj; - } - - else - return obj; - - }; - - this.parse = function (str) { - if (typeof str == 'string') - try { - return JSON.parse(str); // json - } catch (error) { - return str; // non json - } - - else - return str; - }; - - /* this.removeEventProperties = function (params) { - var paramsObj = self.cloneObject(params); - if (paramsObj && paramsObj.on) { - paramOn = self.cloneObject(paramsObj.on); - delete paramsObj.on; - } - if (paramsObj && paramsObj.success) { - paramSuccess = self.cloneObject(paramsObj.success); - delete paramsObj.success; - } - return paramsObj; - }; */ - - - self.setupId = 0; - - this.replacePropertyWithPrefix = function (params, prefix, args) { - - var paramsString; - - if (typeof params == 'object') - paramsString = self.stringify(params); - - else - paramsString = String(params); - - /* let argsWithProperties = (args) ? JSON.stringify(args) : ''; - paramsString = self.replaceAll(paramsString, '"{'+prefix+'}"', argsWithProperties); // obsolete */ - //if (typeof args == undefined) - // self.log('replacePropertyWithPrefix args is undefined', 'yellow'); - if (paramsString && paramsString.indexOf('{' + prefix) >= 0) { - paramsString = paramsString.replace(new RegExp('"{' + prefix + '[:\\s]?([\\w\\d\\s\\.\\|]*)}"', 'g'), function (match, path) { - if (path) { - let value = self.replaceUndefined({ match: match, path: path, root: args, removeUndefined: true }); - //let value = self.element({path:path, root: args}); - /* if (typeof value == undefined) { - self.log(match + ' not found', 'orange'); - value = ''; - } else */ - if (value === undefined) { - return '""'; - } else if (typeof value == 'object') - return JSON.stringify(value); - else if (typeof value == 'string') - return '"' + value + '"'; - - else - return value; - } else { - if (typeof args == 'object') - return JSON.stringify(args); - else if (typeof args == 'string') - return '"' + args + '"'; - - else - return args; - } - }); - - /* if (paramsString && paramsString.indexOf('Contacts')>= 0) { - self.log(paramsString, 'green'); - } */ - paramsString = paramsString.replace(new RegExp('{' + prefix + '[:\\s]?([\\w\\d\\s\\.]*)}', 'g'), function (match, path) { - if (path) { - let value = self.replaceUndefined({ match: match, path: path, root: args, removeUndefined: true }); - //let value = self.element({path:path, root: args}); - /* if (typeof value == undefined) { - self.log(match + ' not found', 'orange'); - value = ''; - } else */ - if (value === undefined) - return ''; - else if (typeof value == 'object') // when object inside a string? - return JSON.stringify(value); - - else - return value; - } else { - if (typeof args == 'object') - return JSON.stringify(args); - - else - return args; - } - }); - - if (self.isJsonString(paramsString)) { - var paramsObj = self.parse(paramsString); - return paramsObj; - } else { - return paramsString; - } - } else { - return params; - } - - }; - - /* this.replaceProperty = function (params, name, args) { // TO DO: change name in replaceArguments - //console.log('replaceProperty:'+name); - //var actions = {}; - - if (typeof params == 'object') { - - params = self.stringify(params); - } - - if (typeof args !== 'string') { - - let argsWithProperties = (args) ? JSON.stringify(args) : ''; - params = self.replaceAll(params, '"{'+name+'}"', argsWithProperties); // obsolete - - // TO DO: get self.element({path:key, root: args}); - - for (let key in args) { - if (typeof args[key] !== undefined) { - if (typeof args[key] == 'object') - params = self.replaceAll(params, '"{'+name+' '+key+'}"', JSON.stringify(args[key])); - else - params = self.replaceAll(params, '{'+name+' '+key+'}', args[key]); - } else { - params = self.replaceAll(params, '{'+name+' '+key+'}', ''); - self.log('{'+name+' '+key+'}' + ' not found', 'yellow'); - } - } - - for (let key in args) { - if (args[key]) { - if (typeof args[key] == 'object') - params = self.replaceAll(params, '"{'+name+':'+key+'}"', JSON.stringify(args[key])); - else - params = self.replaceAll(params, '{'+name+':'+key+'}', args[key]); - } else { - params = self.replaceAll(params, '{'+name+':'+key+'}', ''); - } - } - - } else { - //console.log('args STRINGA'); - - params = self.replaceAll(params, '{'+name+'}', args); - - } - - if (self.isJson(params)) {// (typeof params == 'object') - var paramsObj = self.parse(params); - return paramsObj; - } else { - //alert(paramsString); - return params; - } - - } - */ - this.replaceResult = function (params, args) { - - var paramOn, paramSuccess, paramError; - - if (typeof params == 'object') { - var paramsObj = self.cloneObject(params); - if (paramsObj && paramsObj.on) { - paramOn = self.cloneObject(paramsObj.on); - delete paramsObj.on; - } - if (paramsObj && paramsObj.success) { - paramSuccess = self.cloneObject(paramsObj.success); - delete paramsObj.success; - } - - params = self.stringify(params); - } - - if (typeof args !== 'string') { - params = self.replaceAll(params, '"{result}"', JSON.stringify(args)); - } else { - params = self.replaceAll(params, '{result}', args); - } - - /* self.log('replaceResult'); - self.log('params'); - self.log(params); */ - if (self.isJson(params)) { // (typeof params == 'object') - var paramsObj = self.parse(params); - if (paramOn) paramsObj.on = paramOn; - if (paramSuccess) paramsObj.success = paramSuccess; - if (paramError) paramsObj.error = paramError; - return paramsObj; - } else { - //alert(paramsString); - return params; - } - - }; - - /* - this.replaceTags = function (params, selectorParams) { - self.log('replaceTags'); - var undef = false; - - if (params.text && (typeof params.text == 'string' || typeof params.text == 'object')) { - //alert(params.text); - - params.text = self.stringify(params.text); - - // i tag speciali sono contenuti tra i caratteri { e } - if (params.text.indexOf('{') >= 0) { - // alert(params.text.indexOf('{')); - - // <{visible:element}> - params.text = params.text.replace(/\<\{visible\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = ($(p1).is(':visible')); - return value; - }); - - // <{var:var.object}> - params.text = params.text.replace(/\<\{this\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.json[p1]; - if (!value) undef = true; - return self.stringify(value); - }); - - // <{data:value}> - params.text = params.text.replace(/\<\{data\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.json.var[p1]; - if (!value) undef = true; - return self.stringify(value); - }); - - params.text = params.text.replace(/\<\{var\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.get(p1); - if (!value) undef = true; - return self.stringify(value); - }); - - params.text = params.text.replace(/\<\{param\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.params[p2]; - if (!value) undef = true; - return value; - }); - - // <{value:[id]}> - params.text = params.text.replace(/\<\{value\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = $('#'+p1).val(); - // https://www.geeksforgeeks.org/html-value-attribute/ - if (!value) undef = true; - return value; - }); - - // <{user:[fieldName]}> - params.text = params.text.replace(/\<\{user\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - var value = self.user(p1); - if (!value) undef = true; - return self.stringify(value); - }); - - // <{time:timestamp}> - params.text = params.text.replace(/\<\{time\:timestamp\}\>/g, self.getTimestamp()); - - // <{result}> - if (params.args) { - params.args = self.stringify(params.args); - params.text = params.text.replace(/\<\{result\}\>/g, params.args); - } - - // <{function:app.mac}> - params.text = params.text.replace(/\?/g, function(match, p1, offset, string) { - var functionName = self.docElement(p1); - return functionName(selectorParams); - }); - - // <{random}> - params.text = params.text.replace(/\<\{random\:([^\-]+)\-([^\}]+)\}\>/g, function(match, p1, p2, offset, string) { - return Number(p1)+Math.round((p2-p1)*Math.random()); - }); - - // <{firebaseKey:path}> - params.text = params.text.replace(/\<\{firebaseKey\:([^\}]*)\}\>/g, function(match, p1, offset, string) { - return self.firebaseKey(p1); - }); - - } - if (undef) return undefined - else return self.parse(params.text); - - } else { - //self.log('params.text undefined or number or boolean'); - return params.text; - } - } */ - this.langText = function (textId) { - // find text in language and follow the capitalization of textId - // we could need text in langId language - - if (textId) { - var textValue = textId; - if (typeof textId == 'string') { - if (self.json.texts[textId]) { - textValue = self.json.texts[textId]; - if (typeof textValue == 'object') - textValue = textValue[self.json.setup.language] || textValue['en'] || textValue[Object.keys[0]]; - } - else - textValue = textId; - } else if (typeof textId == 'object') { - textValue = textId[self.json.setup.language] || textId['en'] || textId[Object.keys[0]]; - //textValue = textObj[langId] || textObj[self.json.setup.language] || textObj['en']; - } - return textValue; - } else { - return textId; - } - - /* if (self.json.texts[textId]) - textObj = self.json.texts[textId]; - else if (self.json.texts[textId.toLowerCase()]) - textObj = self.json.texts[textId.toLowerCase()]; - //else if (self.json.texts[textId.toUpperCase()]) - // textObj = self.json.texts[textId.toUpperCase()]; - if (textObj) { - var textValue = textObj[self.json.setup.language] || textObj['en'] || textId; - if (textId.charAt(0) == textId.charAt(0).toUpperCase()) // first char uppercase - if (textId.charAt(1) == textId.charAt(1).toUpperCase()) - return textValue.toUpperCase(); - else - return textValue.replace(/\b\w/, l => l.toUpperCase()); // capitalize - // textValue = textValue.charAt(0).toUpperCase() + name.slice(1) - // style: text-transform: capitalize; - else - return textValue.toLowerCase(); - } else { - return textId; - } */ - /* } else { - self.log('textId undefined in langText'); - } */ - }; - - this.lang = function (params, args) { - if (args) { - var value = self.replaceProperties(params, args); - self.json.setup.language = value; - //alert(value); - self.log('lang'); - self.log(value); - - document.querySelectorAll('[data-text]').forEach(function (element, index) { - //$('*[data-text]').each(function( index ) { - var dataParams = self.dataStorage.get(element, 'params'); - var selector = self.dataStorage.get(element, 'selector'); - /* self.log('index'); - self.log(index); - self.log('dataParams'); - self.log(dataParams); - */ - //alert(JSON.stringify(dataParams)); - self.html(dataParams, { selector: selector }); - //self.text($(this).data('params'), {container: this}); - }); - - /* - var elements = document.querySelectorAll('[data-text]'); - self.log('elements'); - self.log(elements); - //var elements = document.querySelectorAll(selector); - if (elements) - elements.forEach(function (element, index) { - self.log(index); - //var dataParams = self.dataStorage.get(element, 'params'); - var dataSelector = self.attribute(element, 'data-selector'); - //self.text(dataParams, {container: dataSelector}); - self.text($(dataSelector).data('params'), {container: dataSelector}); - - }); - */ - } else { - return self.json.setup.language; - } - }; - // Determine whether is possible to write an image/text to the clipboard. - var isClipboardWritingAllowed = function () { - return new Promise(function (resolve, reject) { - try { - navigator.permissions.query({ name: "clipboard-write" }).then(function (status) { - // PermissionStatus object - // { - // onchange: null, - // state: "granted" (it could be as well `denied` or `prompt`) - // } - self.log(status); - - resolve((status.state == "granted")); - }); - } catch (error) { - // This could be caused because of a Browser incompatibility or security error - // Remember that this feature works only through HTTPS - reject(error); - } - }); - }; - - this.codeSearch = function (params) { - let selector = params.selector || params.container; - // {container, word} - if (selector && params.word) { - var element = self.query(selector); - var editor = ace.edit(element); - - var range = editor.find(params.word, { - wrap: true, - caseSensitive: true, - wholeWord: true, - regExp: false, - preventScroll: false // do not change selection - }); - editor.session.selection.clearSelection(); - editor.setOption("highlightActiveLine", true); - - - /* range.start.column = 0; - range.end.column = Number.MAX_VALUE; - //editor.session.replace(range, "x" + editor.session.getLine(range.start.row) + "x"); - editor.selection.setRange(range); */ - } - }; - - - this.ace = function (params, selectorParams) { - // https://codepen.io/zymawy/pen/XwbxoJ - //self.log('code'); - //self.log(params); - var selector = params.selector || params.container; - var container = selector || self.selector(selectorParams); - - //paramsReplaced = self.cloneObject(params); - //paramsReplaced.value = self.actionResult(paramsReplaced.value); - var value = params.value; - - // item from library - if (params.blocks && self.json.blocks) - if (self.json.blocks[params.blocks]) - value = self.json.blocks[params.blocks]; - - else - self.log('"code" method can\'t find in "blocks" the element ' + params.blocks); - // json file - if (params.module) { - let moduleName = self.replaceProperties(params.module); - if (moduleName && self.modules[moduleName] !== undefined) { - value = self.modules[moduleName]; - - /* self.log('value'); - self.log(value); - self.log(value); */ - } - else - self.log('"code" method can\'t find the file ' + params.file); - } - if (params.var) - if (self.json.var) - value = self.var(params.var); - - else - self.log('"code" method can\'t find the variable ' + params.blocks); - - var element = self.query(container); - //var containerId = $(container).attr('id'); - //self.log('containerId'); - //self.log(containerId); - //var containerId = $(container).attr('id'); - if (element) { - - //var containerId = self.attribute(element, 'id'); // or assign a random unique id - var editor = ace.edit(element); - - /* var keywordMapper = this.createKeywordMapper({ - "tag" : 'div|ul|p|a|button|input|span|img|video|audio|source|figure|figcaption|textarea|iframe|table|thead|tbody|tfoot|tr|th|td|svg|small|h1|h2|h3|h4|h5|h6|form|form-group|label|select|option|optgroup|nav|lottie-player|qrcode|tab|model-viewer' - }, "identifier"); */ - /* var staticWordCompleter = { - getCompletions: function(editor, session, pos, prefix, callback) { - var wordList = ['div', 'ul', 'p', 'a', 'button', 'input', 'span', 'img', 'video', 'audio', 'source', 'figure', 'figcaption', 'textarea', 'iframe', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'svg', 'small', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'form', 'form-group', 'label', 'select', 'option', 'optgroup', 'nav', 'lottie-player', 'qrcode', 'tab', 'model-viewer']; - callback(null, wordList.map(function(word) { - return { - caption: word, - value: word, - meta: "static" - }; - })); - - } - } - - //langTools.setCompleters([staticWordCompleter]) - // or - editor.completers = [staticWordCompleter] */ - /* if (editor) - AceColorPicker.load(ace, editor); */ - //var value = paramsReplaced.value; // else value = params; - if (!params.do || (params.do == 'set')) { - - //var langTools = ace.require('ace/ext/language_tools'); - if (params.theme) - editor.setTheme(params.theme); // "ace/theme/monokai" - var editorMode = params.mode || "ace/mode/json"; - editor.getSession().setMode(editorMode); - - if (params.options) - editor.setOptions(params.options); - //AceColorPicker.load(ace, editor, {hideDelay: 1000}); - //import AceColorPicker from 'ace-colorpicker'; - /* editor.getSession().setMode(editorMode, () => { - AceColorPicker.load(ace); // , {hideDelay: 1000} - }); */ - var editorStyle = self.extend({ - //background: "rgba(255,255,255,0)" - }, params.style); - //$(container).css(editorStyle); //editor.container.style - self.css({ - style: editorStyle - }, { - selector: container - }); - - //var aceOptions = params.options; - /* var aceOptions = self.extend({ - fontSize: "12pt", - selectionStyle: "line", - //showGutter: false, - highlightGutterLine: false, - fixedWidthGutter: false, - //vScrollBarAlwaysVisible: true, - tabSize: 3, - //readOnly: true, - //enableBasicAutocompletion: false, - //enableSnippets: false, - //enableLiveAutocompletion: false, - }, params.options); */ - // https://github.com/ajaxorg/ace/wiki/Configuring-Ace - var codeString; - if (typeof value == 'string') - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(JSON.parse(value), null, '\t'); // json formatting - - else - codeString = value; - else { - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(value, null, '\t'); - else { - var functionObj = self.docElement(value.function); //? - var functionParams = value.params; - codeString = functionObj(functionParams); - } - } - - // should be {lines:dividcode} - if (codeString) { - var codeRows = codeString.split(/\r\n|\r|\n/).length; - /* $(container).css({ - height: Number(21 * (codeRows)) + 'px' - }); */ - /* self.log('element'); - self.log(element); - self.log('container'); - self.log(container); - self.log('codeRows'); - self.log(codeRows); */ - element.style.height = Number(21 * codeRows) + 'px'; - - - //element.querySelector('.ace_scroller').querySelector('.ace_content').height = Number(21 * codeRows) + 'px'; - /* self.css({ - style: { - height: Number(21 * codeRows) + 'px' - } - }, { - container: container - }); */ - editor.setValue(codeString, -1); // -1 unselect the code - - - - //editor.renderer.updateFull(true); - //AceColorPicker.load(ace, ace.edit(containerId)); - self.uiUpdate(); // resize event trigger - - - // workaround known ACE bug (.ace_content element doesn't follow the height until window resize) - } - - if (params.on) { - - var containerId = self.attribute(element, 'id'); // or assign a random unique id - self.codeChangeFunctions[containerId] = params.on; - //self.editorChangeFunctions[editor.id] = params.on; - if (params.on.change) { - editor.on('change', function (event, obj) { - /* self.log('event'); - self.log(event); - self.log('obj'); - self.log(obj); */ - if (self.isJson(obj.getValue())) { - var code = JSON.parse(obj.getValue()); - var action = self.codeChangeFunctions[obj.container.id].change; - //var methods = self.replaceResult(action, code); - var methods = self.replaceResult(action, code); - - //var methods = self.replaceProperties(action, code); - // check on jsonic.io/play (methods is string instead of object) - /* self.log('code'); - self.log(code); - self.log('method'); - self.log(method); - self.log('-------------'); */ - //self.do(methods); - self.do(methods); - //self.do(code, self.editorChangeFunctions[obj.id]); - //var container = self.editorChangeFunctions[obj.id].change.container; - } else { - // syntax error - } - //self.do(self.editorChangeFunctions[obj.id].change, JSON.parse(obj.getValue())); - //self.log(obj); - //self.blocks(JSON.parse(obj.getValue()), {container: }); - }); - } - - // save key - // https://michilehr.de/overwrite-cmds-and-ctrls-in-javascript - } - - - } else if (params.do == 'get') { - return JSON.parse(editor.getValue()); - - } else if (params.do == 'update') { - - self.uiUpdate(); // resize event trigger - - - // workaround known ACE bug (.ace_content element doesn't follow the height until window resize) - } else if (params.do == 'search') { - if (params.word) { - var range = editor.find(params.word, { - wrap: true, - caseSensitive: true, - wholeWord: true, - regExp: false, - preventScroll: false // do not change selection - }); - editor.session.selection.clearSelection(); - editor.setOption("highlightActiveLine", true); - /* range.start.column = 0; - range.end.column = Number.MAX_VALUE; - //editor.session.replace(range, "x" + editor.session.getLine(range.start.row) + "x"); - editor.selection.setRange(range); */ - } - } else if (params.do == 'find') { - // toggle - editor.execCommand('find'); - //editor.searchBox.show(); - } else if (params.do == 'copy') { - // Select the whole content of the editor - editor.selectAll(); - // Store text that will be copied to clipboard - let copyText = editor.getCopyText(); - // Verify if clipboard writing is allowed - isClipboardWritingAllowed().then(function (allowed) { - // Write to clipboard if allowed - if (allowed) { - navigator.clipboard.writeText(copyText).then(function () { - editor.getSession().selection.clearSelection(); - //self.log("Code copied!"); - }); - } - }).catch(function (err) { - self.log("Cannot copy to clipboard", err); - }); - } else { - self.log('"code" function requires value param'); - } - } else { - self.log('"code" method can\'t select the container'); - self.log('container'); - self.log(container); - self.log('element'); - self.log(element); - } - - }; - - // TO DO: should be in the app var and reset on a new execution - this.codeChangeFunctions = {}; - this.editorChangeFunctions = {}; - this.quillElements = {}; - - this.text = function (params, selectorParams, args) { - /* - { - "text": / "string": / textId -> textId "{text:textId}" - "case": [up, down, capitalize] - } - */ - - - /* if (Array.isArray(params)) { - for (var obj of params) - self.text(obj, selectorParams, args); - } else { */ - var textKey; - var textCase; - var textArgs; - var textLang; - var langId; - var selector, element; - //var textAction; - if (typeof params == 'object') { - - if (selectorParams && selectorParams.isConnected) { // Check if an element is attached to DOM - element = selectorParams; - //selector = self.dataStorage.get(element, 'selector'); - //selector = element.getAttribute('data-selector'); - selector = self.elementToSelector(element); // 1.0.12 - } else { - selector = self.selector(self.extend({}, params, selectorParams)); - element = self.query(selector); - } - - // todo: REMOVE (check the menu) - //textAction = self.actionResult(params, textArgs); - //textAction = params; - //textKey = params.string; // || params.text || params.title; // params.key to be removed? - textCase = params.case; // use text-transform uppercase lowercase capitalize - textArgs = params.args; // deve diventare args (secondo parametro) al posto di caseFunction - - - //langId = params.langId; - if (typeof params == 'object') { - - textKey = params.key || params.string || params; // || params.text || params.title; // params.key to be removed? - - - - - - - //textCase = params.case; // use text-transform uppercase lowercase capitalize - //textArgs = params.args; // deve diventare args (secondo parametro) al posto di caseFunction - //langId = params.langId; - } else { - textKey = params; - } - - /* self.log('textKey'); - self.log(textKey); */ - } else if (typeof params == 'string') { - textKey = params; - - /* self.log('textKey'); - self.log(textKey); */ - //textCase = caseFunction; - if (selectorParams) { - if (selectorParams.isConnected) { // Check if an element is attached to DOM - element = selectorParams; - selector = self.dataStorage.get(element, 'selector'); - } else { - selector = self.selector(selectorParams); - element = self.query(selector); - } - } else { - // here when windowTitle += ' ' + self.text(page.title); // window title - } - } - - if (typeof textKey == 'string') { - - /* // TO DO: remove - if (textKey.startsWith('js:')) textKey = self.js(textKey.substr(3)); - else if (textKey.startsWith('db:')) textKey = self.element({path: 'var.db.'+textKey.substr(3)}); - else if (textKey.startsWith('var:')) textKey = self.element({path: 'var.'+textKey.substr(4)}); - else if (textKey.startsWith('data:')) textKey = self.element({path: 'data.'+textKey.substr(5)}); - else - // ----- */ - /* console.log('textKey'); - console.log(textKey); */ - textKey = self.replaceProperties(textKey, textArgs); - /* console.log('textKey'); - console.log(textKey); */ - } - - //self.log('selector'); - //self.log(selector); - //self.log(selector.isConnected); - /* self.log('HOTSPOT'); - self.log(params); - self.log(self.json.setup.language); */ - if (params && params.lang) { // multi-language text - - //self.log('params.lang definito'); - textLang = self.langText(params.lang); // , langId - - //textLang = params.lang[self.json.setup.language] || params.lang['en'] || params.lang[Object.keys[0]]; - textLang = self.replaceProperties(textLang, textArgs); - - /* self.log('textLang'); - self.log(textLang); - self.log('element'); - self.log(element); */ - if (textCase) textLang = self.textCase(textLang, textCase); - - //self.log('textLang'); - //self.log(textLang); - if (element) { - element.textContent = textLang; - self.attribute(element, 'data-text', true); // textKey instead of lang? - self.dataStorage.set(element, 'params', params); - //$(selector).data('params', params); - } - - } else { - //self.log('params.lang non definito'); - //if (!textKey) textKey = params; - if (textKey) { - //textKey = self.compile(textKey, textArgs); // TO DO: verify - /* self.log('textKey'); - self.log(textKey); */ - //if (!textKey) alert(JSON.stringify(params)); - //if (typeof textKey == 'object') { - // textLang = JSON.stringify(textKey, null, '\t'); - //} else { - //textLang = params.lang[self.json.setup.language] || params.lang['en'] || params.lang[Object.keys[0]]; - if (textKey.lang) // multi-language text - textLang = self.langText(textKey.lang); // , langId - - else - textLang = textKey; - - /* self.log('textLang1'); - self.log(textLang); */ - textLang = self.replaceProperties(textLang, textArgs); // move after textLang = self.langText(textKey.lang); - if (textCase) textLang = self.textCase(textLang, textCase); - - //} - /* self.log('textLang2'); - self.log(textLang); */ - //if (selector) { // set - if (element) { // set - - if (self.json.texts[textKey]) { - // save data-text for lang change - //$(selector).data('params', params); - //$(selector).attr('data-text', textKey); - self.attribute(element, 'data-text', true); - self.dataStorage.set(element, 'params', params); - } - - // obsolete - /* if (params.background) $(selector).css({'background': params.background}); - if (params.color) $(selector).css({'color': params.color}); - if (params.size) $(selector).css({'font-size': params.size}); */ - if (params.style) - self.css({ - style: params.style - }, { - selector: selector - }); - //$(selector).css(params.style); - element.textContent = textLang; // put text in element - - - //$(selector).text(textLang); - } else { // get - return textLang; - } - - } else { - /* self.log('"string" parameter required in text object'); - self.log(params); */ - return params; - } - - } - - }; - - var caseUp = function (string) { - return string.toUpperCase(); - }; - - var caseDown = function (string) { - return string.toLowerCase(); - }; - - var capitalize = function (string) { - return self.capitalize(string); - }; - - this.textCase = function (textParam, caseParam) { - if (textParam) { - var text = textParam; - switch (caseParam) { - case 'up': - text = text.toUpperCase(); - break; - - case 'down': - text = text.toLowerCase(); - break; - - case 'capitalize': - text = self.capitalize(text); - break; - } - return text; - } else { - self.log('textParam undefined in textCase'); - } - }; - - /* this.textFit = function (selector,params) { - if (params.alignHoriz == undefined) { - params.alignHoriz = true; - } - if (params.alignVert == undefined) { - params.alignVert = true; - } - if (params.minFontSize) { - params.minFontSize = parseInt(params.minFontSize, 10); // remove px - } - if (params.maxFontSize) { - params.maxFontSize = parseInt(params.maxFontSize, 10); // remove px - } - - // textFit va in errore se l'oggetto diventa invisibile - // mentre sta elaborando la dimensione del testo - if (!$(selector).children('span').hasClass('textFitted')) { - $(selector).each(function(i, obj) { - if ($(obj).is(":visible") - && ($(obj).css("display") !== 'none') - && ($(obj).css('width')) - && ($(obj).css('height'))) { - textFit($(obj), params); - } - }); - } - } */ - /* this.data = function (path, value) { - if (!value) return self.json.var; - } - - this.setvar = function (data) { - var = self.data(); - self.data(data); - } */ - // -------------- - // PAGES - // -------------- - /* this.lastInteraction = function () { - // uso: self.lastInteraction().asMinutes() - var lastInteraction = 0; - if (var.touchTime) lastInteraction = moment(var.touchTime); - var thisMoment = moment(); - var duration = moment.duration(thisMoment.diff(lastInteraction)); - return duration - } */ - // -------------- - // icons e - // -------------- - /* this.icons = this.icon = function (params, selectorParams, args) { - // { [container, class, value, id] - // [html, text, append, prepend] } - - if (Array.isArray(params)) { - for (var index in params) - {self.icons(params[index], selectorParams);} - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.icons(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - - //if (selectorParams) params = self.extend(params, selectorParams); - - var paramsReplaced = self.replaceProperties(params, args); - - self.log('icons'); - self.log('paramsReplaced'); - self.log(paramsReplaced); - - if (paramsReplaced) { - if (paramsReplaced.disabled == true) - self.disableIcon(paramsReplaced, selectorParams); - else if (paramsReplaced.disabled == false) - self.enableIcon(paramsReplaced, selectorParams); - else if (paramsReplaced.change) - self.changeItem(paramsReplaced, selectorParams); - else - self.addItem(paramsReplaced, selectorParams); - } - - if (paramsReplaced.firebase) self.addFirebaseTag(paramsReplaced); - - var selector = self.selector(self.extend(paramsReplaced, selectorParams)); - - if (paramsReplaced.span) // text near icon - self.addTag(paramsReplaced, {container: selector}); - - } - } - } */ - /* this.buttons = this.tab = function (params, selectorParams) { - - // { [container, class, value, id] - // [html, text, append, prepend] } - if (Array.isArray(params)) { - for (var index in params) - self.tab(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.tab(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - - // se necessario, replaceProperties dovrebbe escludere il contenuto di events/action - // in quanto verrà ripetuto sulle azioni in tempo reale solo dove necessario - //params = self.replaceProperties(params); - - if (!params.class) params.class = ''; - var classes = params.class.split(' '); - - if (params.change) { - if (classes.includes('icon')) - self.changeItem(params, selectorParams); - else // if (classes.includes('tabs')) - self.changeTab(params, selectorParams); - } else { - if (classes.includes('icon')) - self.addItem(params, selectorParams); - else // if (classes.includes('tabs')) - self.addTab(params, selectorParams); - } - - if (params.firebase) self.addFirebaseTag(params); - - } - } - } - */ - /* - this.replacePropertyNew = function (params, name, args) { - console.log('replacePropertyNew'); - // like replaceProperties but only for {name:...} property - var paramsString; - - if (typeof paramsString !== 'string') {paramsString = JSON.stringify(self.cloneObject(params));} - - // remove string quotes for object property - if (args && paramsString && paramsString.indexOf('{')>= 0) { - //if (args && paramsString && /{\w/.test(paramsString)) { - paramsString = paramsString.replace(/\"\{(\w+\:)?([\w\s\.\:]+)\}\"/g, function(match, p1, p2, offset, string) { - var value; - if (p1 && p1.endsWith(':')) {p1 = p1.slice(0, -1);} - console.log('match:'+match); - console.log('p1:'+p1); - console.log('p2:'+p2); - if (p1 == name || (!p1 && p2 == name)) { - let nameFound = p1 || p2; - let pathFound = (p1) ? p2 : undefined; - console.log(nameFound+':'+pathFound); - if (typeof args !== 'string') { - //return self.replaceAll(self.stringify(args), '\"', '\''); - return self.stringify(args); - } else { - return '"' + args + '"'; - } - } else - return match; - }); - //console.log('paramsString without quotes'); - //console.log(paramsString); - paramsString = paramsString.replace(/\{(\w+\:)?([\w\s\.\:]+)\}/g, function(match, p1, p2, offset, string) { - var value; - if (p1 && p1.endsWith(':')) {p1 = p1.slice(0, -1);} - if (p1 == name || (!p1 && p2 == name)) { - let nameFound = p1 || p2; - let pathFound = (p1) ? p2 : undefined; - console.log(nameFound+':'+pathFound); - self.partSetup = args; - if (pathFound) { - value = self.docElement('self.partSetup.'+pathFound); - } else { - value = args; - } - console.log('value:'+value); - delete self.partSetup; - } else { - value = match - } - if (typeof value !== 'string') value = self.stringify(value); - return value; - }); - if (self.isJsonString(paramsString)) {// (typeof params == 'object') - console.log('isJsonString'); - var paramsObj = self.parse(paramsString); - return paramsObj; - } else { - console.log('NOT isJsonString'); - console.log(paramsString); - // TO DO: log of wrong json string - return paramsString; - } - } else { - return params - } - } - */ - this.replaceUndefined = function (params) { - let value, defaultValue; - //if (params.path == 'badge') alert(); - if (typeof params.path !== undefined) { - if (params.path.indexOf('|') > 0) - [params.path, defaultValue] = params.path.split('|'); - value = self.element({ path: params.path, root: params.root }); - } - if (value == undefined || value == null) { // empty string is false - if (typeof defaultValue !== undefined) - value = defaultValue; - else { - if (params.removeUndefined) { //p1 == 'args' || p1 == 'selector') { - value = ''; // remove undefined values - } else { - value = params.match; - self.log(value + ' not found', 'yellow'); - } - } - } else { - //console.log('match:'+params.match); - //if (params.removeUndefined) value = ''; - } - return value; - }; - //value = self.replaceUndefined({match: '{'+match+'}', id:p1, removeUndefined: removeUndefined}); - this.replaceProperties = function (params, args, removeUndefined) { - // TO DO: remove fieldsObj. can't find replaceProperties with 3 args - // the third parameter can be removeUndefined - // test with a firebase app like elio - - var paramsString; - var paramOn, paramDo, paramSuccess, paramError, paramEvents, paramConfirm; - if (typeof params == 'string') { - paramsString = params; - } else { - //paramsString = JSON.stringify(params); - var paramsObj = self.cloneObject(params); - if (paramsObj) { - if (paramsObj.on) { paramOn = paramsObj.on; delete paramsObj.on; } - if (paramsObj.success) { paramSuccess = paramsObj.success; delete paramsObj.success; } - if (paramsObj.error) { paramError = paramsObj.error; delete paramsObj.error; } - if (paramsObj.events) { paramEvents = paramsObj.events; delete paramsObj.events; } // TO DO: remove - if (paramsObj.confirm) { paramConfirm = paramsObj.confirm; delete paramsObj.confirm; } // TO DO: check it - if (paramsObj.do) { paramDo = paramsObj.do; delete paramsObj.do; } - } - paramsString = JSON.stringify(paramsObj); - } - /* self.log("paramsString"); - self.log(paramsString); */ - if (paramsString && paramsString.indexOf('{') >= 0) { - - paramsString = paramsString.replace(/\"\{([\w\s\.]+)\}\"/g, function (match, p1, offset, string) { - var value; - if (p1) { - //self.log('p1:' + p1); - //value = self.element({path: p1}); // || match; - value = self.replaceUndefined({ match: '{' + match + '}', path: p1, removeUndefined: removeUndefined }); - if (value) { - if (value.isConnected) return self.elementToSelector(value); // DOM element to CSS selector - if (typeof value !== 'string') - return self.stringify(value); // object or array to string (TO DO: check numbers) - else { - //console.warn('we are here'); - return '"' + value + '"'; - } - } - else - return '""'; - } else { - return '""'; - } - }); - - paramsString = paramsString.replace(/\{(\w+\:)?([\w\s\->|\/=\.:#&;,\[\]\']+)\}/g, function (match, p1, p2, offset, string) { - /* - Firebase references may contain any unicode characters except: - . (period) - $ (dollar sign) - [ (left square bracket) - ] (right square bracket) - # (hash or pound sign) - / (forward slash) - */ - - /* self.log("paramstring"); - self.log(match, p1, p2); */ - // self.log(match, p1, p2); - var value; - if (p1) { - if (p1.endsWith(':')) { - p1 = p1.slice(0, -1); // remove the final ":" - - - // check if is a function name (in this.json.functions) - if (self.functions[p1]) { - //value = self.functions[p1](JSON.parse(p2)); - let funcArgs = p2.split('|'); - /* console.warn('p2'); - console.warn(p2); - console.warn('funcArgs'); - console.warn(funcArgs); */ - // if Number(funcArgs[i]) == funcArgs[i] -> funcArgs[i] = Number(funcArgs[i]); - value = self.function({ name: p1, arguments: [funcArgs] }); - } else { - switch (p1) { - - /* case 'hasClass': - var element = document.querySelector(p2); - if (p3) - value = self.hasClass(el,p3); - else - value = false; el:selector.class (esiste l'elemento selector.class o l'elemento selector ha la classe class) - break; */ - // 'isVisible', 'isHidden', 'isDisplay', 'inViewport', 'outViewport', 'notClass', 'hasClass' - // hasClass da aggiungere come funzione css - // html markups - // 'b:string' 'i:string' 'u:string' 'a:STRING|URL' - /* case 'i': case 'b': case 'u': case 'strong': case 'em': case 'mark': case 'del': case 'ins': case 'sub': case 'sup': - value = '<'+p1+'>'+p2+''; - break; - - case 'a': - // example: "{a:text|href:....|target:_blank}" - let props = p2.split('|'); // or indexOf(':') prima occorrenza - let string = props.shift(); - var propsString = ''; - for (var prop of props) { - //let propArr = prop.split(':'), propName = propArr[0], propValue = propArr[1]; - propsString += ' ' + prop; - } - if (propsString == '') propsString = ' href="'+string+'"'; - value = ''+string+''; - - // https://stackoverflow.com/questions/1547899/which-characters-make-a-url-invalid - // https://www.w3schools.com/tags/tag_a.asp - break; - */ - // DOM properties - case 'visible': - var element = document.querySelector(p2); // self.query(p2); - value = (element && self.isVisible(element)); - //value = ($(p2).is(':visible')); - break; - - case 'number': - value = Number(p2); - break; - - case 'string': - value = String(p2); - break; - - case 'js': // deprecated (too much special characters like {}) - try { - value = eval(p2); - } catch (error) { - value = ''; - self.log('javascript error on ' + p2); - self.log(error); - } - break; - - /* case 'item': - if (fieldsObj) { - //self.log('fieldsObj['+p2+']:'+fieldsObj[p2]); - value = fieldsObj[p2] || ''; //|| p2+'=NULL'; - } else { - //self.log('p2:'+p2); - //self.log('fieldsObj == undefined'); - value = '{'+p1+':'+p2+'}'; - } - break; */ - /* case 'item': - case 'items': - value = self.docElement('self.json.items.'+p2); - break; */ - /* case 'frame': - var element = self.query(p2); - element.contentWindow - break; */ - /* case 'field': - if (fieldsObj) { - //self.log('fieldsObj['+p2+']:'+fieldsObj[p2]); - value = fieldsObj[p2] || ''; // || p2+'=NULL'; - } else { - //self.log('p2:'+p2); - //self.log('fieldsObj == undefined'); - value = ''; - } - break; */ - /* case 'setup': - value = self.docElement('self.json.setup.'+p2) || match; - break; */ - /* - case 'setup': - if (args) { - self.partSetup = args; - value = self.docElement('self.partSetup.'+p2); - delete self)Setup; - } else { - value = ''; - } - break; */ - case 'wp': - case 'wordpress': - // TO DO: should get/set data with jsonic.get/setWordpressData - // setWordpressData can be done automatically in the init - value = self.docElement('self.json.setup.wordpress.' + p2) ?? match; - //alert(value); - //if (value.indexOf('"') >= 0) - // value = self.replaceAll(value, '"', '\\"'); - // the first should replace only " and not \" but it doesn't works - //value = value.replaceAll(/([^\\\"])\"/g, '$1\\"'); - break; - - case 'plugins': - value = self.json.resources.pluginsFunctions[p2]; - if (value && !Array.isArray(value)) value = [value]; - else value = []; - /* self.log('plugins'); - self.log('value'); - self.log(value); */ - /* value = plugins; - for (plugin of plugins) { - value = self.json.resources.pluginsFunctions[p2].name || 'unknown plugin required'; - } */ - break; - - case 'database': - case 'db': - value = self.docElement('self.json.var.db.' + self.replaceProperties(p2, args)); - break; - - // shorteners (useful?) - case 'media': // or m or src - if (self.json.setup && self.json.data.media) - value = self.docElement('self.json.data.media.' + p2) || match; - - else - value = match; - break; - - case 'color': // or col - if (self.json.data && self.json.data.colors) - value = self.docElement('self.json.data.colors.' + p2) || match; - - else - value = match; - break; - - case 'class': // or cla - if (self.json.data && self.json.data.class) - value = self.docElement('self.json.data.class.' + p2) || match; - - else - value = match; - break; - - case 'text': - value = self.langText(p2); - break; - - case 'param': - value = self.params[p2] || ''; // || p2+'=NULL'; - break; - - case 'height': - /* self.log('{height:p2}'); - self.log('p2'); - self.log(p2); */ - var element = document.querySelector(p2); // self.query(p2); - if (element) // && self.isVisible(element) - //value = getComputedStyle(element, null).height; - value = element.offsetHeight + 'px'; - - - - //if ($(p2).is(':visible')) - //value = $(p2).height() + 'px' - else - value = '0px'; - break; - - case 'offsetWidth': - var element = document.querySelector(p2); // self.query(p2); - if (element) // && self.isVisible(element) - //value = getComputedStyle(element, null).height; - value = element.offsetWidth; - - - - //if ($(p2).is(':visible')) - //value = $(p2).height() + 'px' - else - value = '0'; - break; - - case 'width': - var element = document.querySelector(p2); // self.query(p2); - if (element) // && self.isVisible(element) - //value = getComputedStyle(element, null).height; - value = element.offsetWidth + 'px'; - - - - //if ($(p2).is(':visible')) - //value = $(p2).height() + 'px' - else - value = '0px'; - break; - - case 'local': - value = self.methods.local.get(p2); - //self.log('{localStorage:cart}'); - //self.log(value); - break; - - case 'ace': - var element = document.querySelector(p2); - if (element) { - var editor = ace.edit(element); - value = JSON.parse(editor.getValue()); - } - //self.log('{localStorage:cart}'); - //self.log(value); - break; - - /* case 'innerText': - var element = document.querySelector(p2); - value = (element) ? element.innerText : undefined; - self.log('p1:'+p1); - self.log('p2:'+p2); - self.log('value:'+value); - //.trisBox[data-value="0"] - break; - - case 'innerHtml': - var element = document.querySelector(p2); - value = (element) ? element.innerHTML : undefined; - break; */ - case 'shuffle': - value = self.element({ path: p2 }); - value = self.methods.shuffle(value); - break; - - case 'select': - case 'input': - case 'value': // deprecated - - var element = document.querySelector(p2); // self.query(p2); - value = (element) ? String(element.value || '') : ''; - - //value = $('#'+p2).val() || ''; //|| p2+'=NULL'; - // input field value - // https://www.geeksforgeeks.org/html-value-attribute/ - break; - - case 'user': - if (p2 == 'in') { - value = self.userIn(); - } else if (p2 == 'out') - value = self.userOut(); - - else - value = self.user(p2) || match; //|| p2+'=NULL'; - break; - - // can go in objects - case 'length': - var varObj = self.element({ path: p2 }); // to get also js objects length - - //var varObj = self.docElement('self.json.'+p2); - if (varObj) - if (typeof varObj == 'object') - value = Object.keys(varObj).length; - - else - value = varObj.length; - - else - self.log('' + p2 + ' is undefined'); - break; - - case 'Date': - case 'time': - if (p2 == 'timeZone') value = new Intl.DateTimeFormat().resolvedOptions().timeZone; - else if (p2 == 'weekday') value = self.weekday(); - else if (p2 == 'stamp') value = self.getTimestamp(); - else if (p2 == 'timestamp') value = self.getTimestamp(); - else if (p2 == 'getTimestamp') value = self.getTimestamp(); - else if (p2 == 'getDay') value = new Date().getDay(); - else if (p2 == 'getDate') value = new Date().getDate(); - else if (p2 == 'getMonth') value = new Date().getMonth(); - else if (p2 == 'getFullYear') value = new Date().getFullYear(); - else if (p2 == 'getTime') value = new Date().getTime(); // timestamp - else if (p2 == 'getSeconds') value = new Date().getSeconds(); - else if (p2 == 'getMinutes') value = new Date().getMinutes(); - else if (p2 == 'getHours') value = new Date().getHours(); - - // second, minute, hour, weekday, day, month, year - else value = p2 + '=NULL'; - break; - - case 'now': - // ... - break; - - case 'month': - var month = (p2 == 'today' || p2 == undefined) ? new Date().getMonth() : Number(p2); - value = self.month(month); - break; - - case 'weekday': // format: long, short, narrow - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'long' }); - break; - - case 'weekdayNarrow': // format: long, short, narrow - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'narrow' }); - break; - - case 'weekdayShort': // format: long, short, narrow - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'short' }); - break; - - case 'moment': - var timeFormat = (p2) ? p2 : ''; - value = moment().format(timeFormat); - break; - - case 'dayjs': // TO DO: check - var timeFormat = (p2) ? p2 : ''; - value = dayjs().format(timeFormat); - break; - - case 'Math': - value = self.Math(p2); - break; - - - case 'action': - case 'do': - self.log('do'); - self.log('p2'); - self.log(p2); - //value = self.do(p2); // || match; // TO DO: log error - value = self.do(p2); // || match; // TO DO: log error - - - - - //var functionName = self.docElement(p2); - //value = (functionName) ? functionName(functionName) : p2+'=NULL' - break; - - /* WITH ARGS */ - case 'method': - var method = self.element({ path: p2, root: self.methods }); - if (method) { - value = method(args); // how to pass args? needs p3 - } else { - value = match; - } - break; - - case 'function': // TO DO: remove - var func = self.element({ path: p2, root: self.functions }); - if (func) { - value = func(args); // how to pass args? needs p3 - } else { - value = match; - } - break; - - case 'on': - /* self.log('args'); - self.log(args); */ - if (args) { - self.onResult = args; - value = self.docElement('self.onResult.' + p2); - //alert(JSON.stringify(value)); - delete self.onResult; - } else { - //alert(JSON.stringify(value)); - value = match; - } - //value = ($(p2).is(':visible')); - break; - - case 'ajax': - if (args) { - self.ajaxResult = args; // -> self.json.var.ajaxData[self.json.var.ajaxId] = args.response - - //alert(JSON.stringify(args)); - value = self.docElement('self.ajaxResult.' + p2); - - delete self.ajaxResult; - } else { - //alert(JSON.stringify(value)); - value = match; - } - //value = ($(p2).is(':visible')); - break; - - /* case 'function': // TO DO: remove - //self.log('function'); - //self.log('p2'); - //self.log(p2); // app.mac - value = self.function(p2) || match; // TO DO: log error - - //var functionName = self.docElement(p2); - //value = (functionName) ? functionName(functionName) : p2+'=NULL' - - break; */ - case 'if': // TO DO: remove (can't manage spacial characters !<>'' etc) - p2 = self.replaceProperties(p2); - var ifArr = p2.split('|'); - if (self.js(ifArr[0])) value = true; - if (ifArr.length > 1 && value) value = ifArr[1]; - if (ifArr.length > 2 && !value) value = ifArr[2]; - break; - case 'random': - /* var random = p2.replace(/([^\-]+)\-([^\}]+)/g, function(match, n1, n2, offset, string) { - return Number(n1)+Math.round((n2-n1)*Math.random()); - }); */ - value = String(Math.floor(Number(p2) * Math.random())); - //self.log('random value: '+value); - //value = random; //p2+' format is wrong' - // CHANGE TO {math.random:max} - break; - - case 'getKey': - case 'firebaseKey': - value = self.firebaseKey(p2); - // https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot - // CHANGE TO {data.exists:path/to/record} - //"alert.close" functions(alert, do:close) - break; - - case 'window': - /* try { - value = eval('window.'.p2); - } catch (error) { - self.log('javascript error on '+ p2); - value = match; - } */ - //value = self.js('window.'.p2) || match; - value = self.docElement(p2) || match; - break; - - - /* case 'args': - // often replaceProperties is called without args - value = match; - break; */ - default: - // ci finiamo dentro con {setup:value} - /* var element = document.querySelector(p2); - value = (element) ? element[p1] : ''; - self.log('p1 ' + p1); - self.log('p2 ' + p2); - self.log('value ' + value); - if (!element) - self.log('can\'t match ' + match, 'color:red'); */ - break; - - - /* default: - - var node = self.docElement('self.json.'+p1); - self.log('node'); - self.log(node); - if (node) value = node[p2] // example: p1 = styles.colors p2 = colorName - else value = '<{'+p1+':'+p2+'}>'; - break; - */ - } - } // not self.functions[p1] - } - } else if (p2) { - - // can be a FUNCTION: from modules - let keyPrefix = p2.split(' ')[0]; // /\s\./ - if (self.functions[keyPrefix]) { - value = self.function({ name: keyPrefix }); - value = self.element({ path: p2, root: value }); // example: {pathFromHash 0} - console.log(keyPrefix); - console.log(value); - } - else - value = self.replaceUndefined({ match: match, path: p2, removeUndefined: removeUndefined }); - //value = self.element({path: p2}); - } - - // value is a DOM element - if (value && value.isConnected) value = self.elementToSelector(value); // DOM element to CSS selector - - if (!value) { - // TO DO: should be (typeof value == undefined) - // t's a critical change. It changes the result of "is": "'{data id}' !== ''" - if (removeUndefined) - value = ''; - else { - if (typeof value == undefined) - self.log(match + ' is undefined', 'yellow'); - } - } - if (typeof value !== 'string') value = self.stringify(value); // object or array to string (TO DO: check numbers) - - return value; - }); - - - // js property TO DO: check it - if (paramsString.startsWith('{js:') && paramsString.endsWith('}')) - paramsString = self.js(paramsString.substr(4, paramsString.length - 1 - 4)); - - //if (self.isJson(paramsString)) {// (typeof params == 'object') - if (self.isJsonString(paramsString)) { // (typeof params == 'object') - var paramsObj = self.parse(paramsString); - - // restore event nodes - if (paramOn) paramsObj.on = paramOn; - if (paramDo) paramsObj.do = paramDo; - if (paramConfirm) paramsObj.confirm = paramConfirm; - if (paramSuccess) paramsObj.success = paramSuccess; - if (paramError) paramsObj.success = paramError; - if (paramEvents) paramsObj.events = paramEvents; // obsolete - return paramsObj; - } else { - // TO DO: log of wrong json string - //alert(paramsString); - /* if (Array.isArray(self.parse(paramsString))) - return self.parse(paramsString) - else */ - return paramsString; - } - } else { - // restore event nodes - if (paramOn) params.on = paramOn; - if (paramDo) params.do = paramDo; - if (paramConfirm) params.confirm = paramConfirm; - if (paramSuccess) params.success = paramSuccess; - if (paramError) params.error = paramError; - if (paramEvents) params.events = paramEvents; // obsolete - return params; - } - - }; - - /* if (!value) undef = true; - if (undef) return undefined - else return params; - */ - this.isJsonString = function (str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; - }; - - this.isJson = function (item) { - item = typeof item !== "string" ? JSON.stringify(item) : item; - try { - item = JSON.parse(item); - } catch (e) { - return false; - } - - if (typeof item === "object" && item !== null) { - return true; - } - - return false; - }; - - this.replaceStringInObject = function (obj, stringToReplace, value) { - var paramsString, valueString; - if (typeof obj == 'string') paramsString = obj; else paramsString = JSON.stringify(obj); - if (typeof value == 'string') valueString = value; else valueString = JSON.stringify(value); - paramsString = self.replaceAll(paramsString, stringToReplace, valueString); - if (self.isJson(paramsString)) - return self.parse(paramsString); - - else - return paramsString; - }; - - /* this.replaceResult = function (params, args) { - - paramsString = paramsString.replace(/(\"\s*)\{[result]\:(\w+)\}(\s*\")/g, function(match, p1, p2, p3, offset, string) { - }); - } - */ - this.replaceItems = function (params, item, name) { - // check this: http://mir.aculo.us/2011/03/09/little-helpers-a-tweet-sized-javascript-templating-engine/ - // params:
    • <{item:name}>
    • , item: Vito or item: {name: Vito} - //var paramString = self.replaceProperties(params, undefined, item); - var paramsString; - var specialPattern; - var itemName = name || 'item'; - /* if (name) { - self.log('replaceItems'); - self.log('params'); - self.log(params); - self.log('item'); - self.log(item); - self.log('name'); - self.log(name); - } */ - if (typeof params == 'string') paramsString = params; else paramsString = JSON.stringify(params); - - /* paramsString = paramsString.replace(/\{item\}/g, function(match, p1, offset, string) { - - var value; - - if (item) { - value = item; - } else { - value = ''; - } - - if (typeof value == 'object') value = self.stringify(value); - return value; - }); */ - if (typeof item == 'object' || Array.isArray(item)) { // || Array.isArray(item) not needed - paramsString = self.replaceAll(paramsString, '"{' + itemName + '}"', JSON.stringify(item)); - for (let key in item) { - if (typeof item[key] == 'object') - paramsString = self.replaceAll(paramsString, '"{' + itemName + ':' + key + '}"', JSON.stringify(item[key])); - - else - paramsString = self.replaceAll(paramsString, '{' + itemName + ':' + key + '}', item[key]); - } - } else { - paramsString = self.replaceAll(paramsString, '{' + itemName + '}', String(item)); - } - //if (itemName == 'hour') alert(paramsString); - /* if (itemName !== 'item') { // TO DO: remove - var propertyPattern = new RegExp('\{'+itemName+'\:([^\}]+)\}', 'g'); - paramsString = paramsString.replace(propertyPattern, function(match, p1, p2, p3, offset, string) { - - - var value = self.docElement(p1, undefined, item); - if (value) - return value - else - return match; - - }); - } */ - //specialPattern = new RegExp(/\"\{(\w+)\}\"/, "g"); - // item: inside double quotes (to manage objects inside double string) - //specialPattern = new RegExp(`(\")\{${itemName}\:(\w+)\}(\")`, 'g'); - //paramsString = paramsString.replace(specialPattern, function(match, p1, p2, p3, offset, string) { - //specialPattern = new RegExp('(\"\s*)\{'+itemName+'\:(\w+)\}(\s*\")', 'g'); - paramsString = paramsString.replace(/(\"\s*)\{item\:(\w+)\}(\s*\")/g, function (match, p1, p2, p3, offset, string) { - - var value; - - if (item) - value = item[p2] || ''; - - else - value = ''; - - if (typeof value == 'object') - value = self.stringify(value); - else if (Array.isArray(value)) - value = value; - - else - value = p1 + value + p3; // p1 and p3 are the " matched by (\"\s*) and (\s*\") - - return value; - }); - - /* - specialPattern = new RegExp('\{'+itemName+'\:([^\}]*)\}', 'g'); - paramsString = paramsString.replace(specialPattern, function(match, p2, offset, string) { - //paramsString = paramsString.replace(/\{item\:([^\}]*)\}/g, function(match, p2, offset, string) { - - var value; - - if (item) - value = item[p2] || ''; - else - value = ''; - - if (typeof value == 'object') - value = self.stringify(value); - - return value; - }); */ - if (self.isJson(paramsString)) - return self.parse(paramsString); - - else - return paramsString; - //if (typeof params == 'object') return self.parse(paramsString); else return paramsString; - }; - - /* this.replaceItems = function (objWithNames, name) { - //self.log('replaceItems'); - var paramString = self.stringify(objWithNames); - //self.log(paramString); - if (!name) name = ''; - paramString = self.replaceAll(paramString, '{item}', name); - //self.log(paramString); - //paramString = self.replaceTags({text:paramString}); - //self.log(paramString); - //paramString = self.replaceProperties(paramString); - //self.log(paramString); - if (typeof objWithNames == 'object') return self.parse(paramString); else return paramString; - } */ - this.color = function (params, args) { - var paramsReplaced = self.replaceProperties(params, args); - //if (self.json.styles.colors) - // return self.json.styles.colors[paramsReplaced]; - if (self.json.data && self.json.data.colors) - return self.json.data.colors[paramsReplaced]; - }; - - // ---------------------------- - // ELEMENT METHODS - // ---------------------------- - this.empty = function (params) { - /* self.log('empty'); - self.log(params); */ - var el = self.query(params); - if (el) { - while (el.firstChild) - el.removeChild(el.firstChild); - } else { - self.log('"empty" is unable to select element'); - self.log(params); - } - }; - - this.isArray = function (value) { - return Array.isArray(self.js(value)); - }; - - this.isVisible = function (el) { - return (el.style.display !== 'none' && !self.hasClass(el, 'd-none')); - }; - - this.isHidden = function (el) { - return (el.offsetParent === null); - }; - - this.isDisplay = function (el, displayValue) { - //var style = window.getComputedStyle(el); - /* self.log('isDisplay'); - self.log('el.style'); - self.log(el.style); - self.log('displayValue'); - self.log(displayValue); */ - return (el.style.display === displayValue); - }; - - this.inViewport = function (el) { - const rect = el.getBoundingClientRect(); - return ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - rect.right <= (window.innerWidth || document.documentElement.clientWidth) - - ); - }; - - this.outViewport = function (el) { - return !self.outViewport(el); - }; - - this.notClass = function (el, className) { - return !self.hasClass(el, className); - }; - - this.hasClass = function (el, className) { - if (el.classList) - return el.classList.contains(className); - - else - return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')); - }; - - this.addClass = function (el, className) { - if (el.classList) - el.classList.add(className); - else if (!self.hasClass(el, className)) el.className += " " + className; - }; - - this.removeClass = function (el, className) { - if (el.classList) - el.classList.remove(className); - else if (self.hasClass(el, className)) { - var reg = new RegExp('(\\s|^)' + className + '(\\s|$)'); - el.className = el.className.replace(reg, ' '); - } - }; - - this.toggleClass = function (el, className) { - if (self.hasClass(el, className)) - self.removeClass(el, className); - - else - self.addClass(el, className); - }; - - this.choose = this.select = function (params, selectorParams, args) { - // "choose OR options / "select" is deprecated because select is an html tag - // {selection: selection class, id: selected id} - // or: choosed, choosable, selection - // or: selector, selectable, selection - // or: opted, options, selection - /* self.log('select'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - if (Array.isArray(params)) { - for (var obj of params) - self.choose(obj, args); - } else { - - //if (selectorParams) params = self.extend({}, selectorParams, params); - var selId, selClass, selValue; - - selValue = params['data-value']; // || params.value - if (params.id) selId = self.replaceProperties(params.id, args); - if (params.class) selClass = self.replaceProperties(params.class, args); - if (selValue) selValue = self.replaceProperties(selValue, args); - - //var selector = self.selector(params.selector, undefined, true) || self.selector(selectorParams, undefined, true); - if (params.selection) { - - var selectionClass = params.selection; - /* self.log('selClass'); - self.log(selClass); - self.log('selValue'); - self.log(selValue); - self.log('selectionClass'); - self.log(selectionClass); */ - var selector = self.selector({ class: selClass }); - var elements = document.querySelectorAll('.' + selClass); // convert to any string selector (move the point to the code) - elements.forEach(function (element, index) { - self.removeClass(element, selectionClass); - }); - - //$(selector).removeClass(selectionClass); - if (selId || selValue) { - var selector = self.selector({ id: selId, class: selClass, 'data-value': selValue }); - - //self.log('selector'); - //self.log(selector); - //var elements = self.query(selector); - //self.log('elements'); - //self.log(elements); - //if (elements) - //self.addClass(elements, selectedIconClass); - var elements = document.querySelectorAll(selector); - elements.forEach(function (element, index) { - self.addClass(element, selectionClass); - }); - } - } else { - /* self.log('select'); - self.log('selClass'); - self.log(selClass); - self.log('selValue'); - self.log(selValue); - self.log('selectionClass'); - self.log(selectionClass); */ - self.hide({ - "selector": { - "class": selClass - } - }); - self.show({ - "selector": { - "id": selId, - "class": selClass, - "data-value": selValue - } - }); - - //self.log('selectselection" class parameter is required in "select" object'); - } - - //self.updateCodeEditors(); // workaround known ACE bug - self.uiUpdate(); // resize event trigger - - } - - }; - - /* this.select = function (params, selectorParams) { - // { [container, class, value, id] - self.log('self.select'); - if (Array.isArray(params)) { - for (var index in params) - self.choose(params[index], selectorParams); - } else { - - if (selectorParams) params = self.extend({}, selectorParams, params); - - params = self.replaceProperties(params); - //params = self.replaceTags({text:params}); - - self.selectItem(params); - } - } -*/ - this.toggle = function (params, selectorParams, args) { - self.log('toggle'); - self.log(params); - if (Array.isArray(params)) { - for (var index in params) - self.toggle(params[index], selectorParams, args); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var element = self.query(selector); - /* self.log('selector'); - self.log(selector); - self.log('element'); - self.log(element); - self.log('self.isVisible(element)'); - self.log(self.isVisible(element)); */ - //if ($(selector).is(":visible")) - if (self.isVisible(element)) - //self.fadeOut(params, selectorParams); - self.out(params, selectorParams, args); - - else - //self.fadeIn(params, selectorParams); - self.in(params, selectorParams, args); - //$(selector).toggle(500); // jquery bugs // , self.resizeEvent - } - }; - - this.in = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.in(params[index], selectorParams, args); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - - var transition = params.transition || 'fadeIn'; - var duration = params.duration || '500ms'; - - //self.log('selector'); - //self.log(selector); - var start = [{ - "show": { - "selector": selector, - } - }]; - var end = [ - { - "do": self.resizeEvent - } - ]; - if (params.on && params.on.start) - start.push(params.on.start); - if (params.on && params.on.end) - end.push(params.on.end); - - var animation = { - "animate": { - "selector": selector, - "transition": transition, - "duration": duration, - "on": { - "start": start, - "end": end - } - } - }; - //self.do(animation, args); - self.do(animation, undefined, args); - //self.resizeEvent(); - } - - }; - - this.out = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.out(params[index], selectorParams); - } else { - - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - - var transition = params.transition || 'fadeOut'; - var duration = params.duration || '500ms'; - - var start = []; - var end = [ - { - "hide": { - "selector": selector, - } - }, - { - "do": self.resizeEvent - } - ]; - if (params.on && params.on.start) - start.push(params.on.start); - if (params.on && params.on.end) - end.push(params.on.end); - - var animation = { - "animate": { - "selector": selector, - "transition": transition, - "duration": duration, - "on": { - "start": start, - "end": end - } - } - }; - //self.do(animation, args); - self.do(animation, undefined, args); - } - }; - - this.show = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.show(params[index], selectorParams); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - elements.forEach(function (element, index) { - self.removeClass(element, 'hidden'); - self.removeClass(element, 'opacity-0'); - self.removeClass(element, 'invisible'); - self.removeClass(element, 'd-none'); // bootstrap - - //element.style.display = 'block'; - element.style.visibility = 'visible'; - /* - container = element.getAttribute('data-selector'); - //container = self.dataStorage.get(element, 'selector'); - var action = [ - { - "if": { - "container": container, - "hasClass": "opacity-0", - "then": { - "attr": { - "container": container, - "removeClass": "opacity-0" - } - } - } - }, - { - "if": { - "container": container, - "hasClass": "invisible", - "then": { - "attr": { - "container": container, - "removeClass": "invisible" // bootstrap & tailwind - } - } - } - }, - { - "if": { - "container": container, - "hasClass": "d-none", - "then": { - "attr": { - "container": container, - "removeClass": "d-none" // bootstrap - } - } - } - }, - { - "if": { - "container": container, - "hasClass": "hidden", - "then": { - "attr": { - "container": container, - "removeClass": "hidden" // taliwind - } - } - } - }, - { - "if": { // should be if style.display == none - "container": container, - "isDisplay": "none", - "then": { - "attr": { - "container": container, - "style": { - "display": "" - } - } - } - } - } - ]; - //element.style.display = ' '; - //alert(JSON.stringify(element.style)); - if (element.style.visibility && element.style.visibility !== 'visible') - element.style.visibility = 'visible'; - //self.do(action, args); - //self.do(action, undefined, args); - self.do(action, undefined, args); */ - }); - } - }; - - this.hide = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.hide(params[index], selectorParams); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - elements.forEach(function (element, index) { - self.addClass(element, 'hidden'); - - /* container = element.getAttribute('data-selector'); - var action = [ - { - "attr": { - "container": container, - "addClass": "d-none" // bootstrap (to be removed) - } - }, - { - "attr": { - "container": container, - "addClass": "hidden" // tailwind - } - } - ]; - //self.do(action, args); - self.do(action, undefined, args); */ - }); - } - }; - - - /* this.fadeIn = function (params, selectorParams, args) { - //self.log('fadeIn'); - //self.log(params); - if (Array.isArray(params)) { - for (var index in params) - self.fadeIn(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - var duration = params.duration || 500; - var done = (params.done) ? function () { - self.resizeEvent(); - self.do(params.done); - } : null; - $(selector).stop().fadeIn(duration, done); - } - } - - this.fadeOut = function (params, selectorParams, args) { - //self.log('fadeOut'); - //self.log(params); - // add onComplete and duration - if (Array.isArray(params)) { - for (var index in params) - self.fadeOut(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - var duration = params.duration || 500; - var done = (params.done) ? function () { - self.do(params.done); - } : null; - $(selector).stop().fadeOut({ - duration: duration, - done: function () { - self.resizeEvent(); - self.do(params.done); - } - }); - } - } */ - /* this.show = function (params, selectorParams, args) { - //self.log('show'); - //self.log(JSON.stringify(params)); - if (Array.isArray(params)) { - for (var index in params) - self.show(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - //self.log('selector'); - //self.log(selector); - $(selector).show(); - self.resizeEvent(); - } - } - - this.hide = function (params, selectorParams, args) { - //self.log('hide'); - //self.log(JSON.stringify(params)); - if (Array.isArray(params)) { - for (var index in params) - self.hide(params[index], selectorParams); - } else { - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var selector = self.selector(self.extend({}, params, selectorParams), {}, true); - //self.log('selector'); - //self.log(selector); - $(selector).hide(); - self.resizeEvent(); - } - } */ - this.matchMedia = function (mediaAction, mediaEvent) { - const mediaQuery = window.matchMedia(mediaEvent); - mediaQuery.addListener(function (e) { - /* self.log('matchMedia'); - self.log('e'); - self.log(e); */ - if (e.matches) { - self.do(mediaAction); - //self.do(mediaAction); - } - }); - //self.do(mediaAction); - }; - - - /* this.firebaseEventAction = function (newObj) { - - var path = newObj.path; - delete newObj.path; - - document.querySelectorAll('[data-firebase="'+path+'"]').forEach(function (element, index) { - - var pathString = 'self.json.var.db.' + self.replaceAll(element.getAttribute('data-firebase'), '/', '.'); // data('firebase') - var dbObj = self.docElement(pathString); - - var firebaseValue = newObj[element.getAttribute('data-value')]; // TODO: not works for nested nodes - var container = element.getAttribute('data-selector'); - //var template = element.getAttribute('data-template'); - var template = self.dataStorage.get(element, 'data-template'); - - if (element.tagName == 'UL') { // se $(this) è un ul - - var liTemplate = template.li; - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - //if (dbPath == 'lessons') - //prompt(JSON.stringify(liTemplate)); - var dbParams = self.replaceItems(liTemplate, item, 'item') || ''; - // var dbParams = self.replaceProperties(liTemplate, undefined, item) || ''; - self.li(dbParams, {container: container}); - } - - //} else if ( $(element).is('span') || $(element).is('p')) { - } else if (element.tagName == 'SPAN' || element.tagName == 'P') { - - //$(element).text(firebaseValue); - element.textContent = firebaseValue; - - } else { // se $(this) non è un ul - - if (template.blocks || template.html) { - var blocksTemplate = template.html || template.blocks; - - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - self.log('newObj'); - self.log(newObj); - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - var dbParams = self.replaceProperties(blocksTemplate, undefined, item) || ''; - - self.html(dbParams, {container: container}); - } - } - - if (template.init) self.do(template.init); - - } - - - }); - }; */ - /* self.jsonic = function () { - } */ - this.addFirebaseTag = function (params) { - // self.log('addFirebaseTag'); - var dataObj = params.database; - - if (dataObj) { - - dataObj = self.replaceProperties(dataObj); - /* self.log('dataObj'); - self.log(dataObj); */ - //var path = self.replaceTags({text:params.firebase}); - var path, success; - if (typeof dataObj == 'string') { - path = dataObj; - } else { - path = dataObj.path; - success = dataObj.success; - } - - if (path) { - var selector = self.selector(params, undefined, false); - //var element = self.query(selector); - var elements = self.queryAll(selector); - //var elements = document.querySelectorAll(selector); - if (elements) - elements.forEach(function (element, index) { - - var listenerObj = { - path: path - //success: dataObj.success - }; - - var elementsDataPath = document.querySelectorAll('[data-firebase="' + path + '"]'); - - //if ($('[data-firebase="'+path+'"]').length == 0) { - if (elementsDataPath.length == 0) { - listenerObj.action = [ - /* { - "firebaseEvent.action": {} // should use self.get function to parse "self" - // todo: remove "jsonic". The function firebaseEventAction can be stored in self.do (or?) - } */ - ]; - - if (dataObj.success) - listenerObj.action.push(dataObj.success); - - } - - //$(selector).attr('data-firebase', path); - //$(selector).data('data-template', params); - if (element) { - element.setAttribute('data-firebase', path); - self.dataStorage.set(element, 'data-template', params); - } else { - self.log('!element selector:' + selector + ' / firebase path:' + path); - self.log('params'); - self.log(params); - } - - //if (params.on && params.on.data) $(selector).data('ondata', params.on.data); // maestry - if (dataObj.orderByChild !== undefined) listenerObj.orderByChild = dataObj.orderByChild; - if (dataObj.equalTo !== undefined) listenerObj.equalTo = dataObj.equalTo; - - self.firebaseAddListener(listenerObj); - }); - - } else { - self.log('data object requires path parameter'); - self.log(params); - } - } - }; - - this.dbObject = function (path) { - var pathString = 'self.json.var.db.' + self.replaceAll(path, '/', '.'); - return self.docElement(pathString); - }; - - this.only = function (permissions, user) { - // "visitor" or "only" - if (user) { - return (user == self.user('uid')); - } else { - var permission = (permissions) ? String(permissions).split(',') : false; - return (!permission || (permissions.indexOf(self.userRole()) >= 0)); - } - }; - - this.extendJsonFromElement = function (p) { - /* self.log('extendJsonFromElement'); - self.log(p); */ - - var params = self.cloneObject(p); - - // properties - if (params.resources) self.extendJson(self.json, { "resources": params.resources }); - if (params.plugins) self.extendJson(self.json, { "plugins": params.plugins }); - if (params.parts) self.extendJson(self.json, { "parts": params.parts }); - if (params.blocks) self.extendJson(self.json, { "blocks": params.parts }); // obsolete - if (params.shortcuts) self.extendJson(self.json, { "shortcuts": params.shortcuts }); - if (params.css) self.extendJson(self.json, { "css": params.css }); - if (params.setup) self.extendJson(self.json, { "setup": params.setup }); - if (params.data) self.extendJson(self.json, { "data": params.data }); - if (params.var) self.extendJson(self.json, { "var": params.var }); - if (params.texts) self.extendJson(self.json, { "texts": params.texts }); // maybe used in self.text - - - // can't be extended "setup" (is relative to the full app) and "on" (is relative to the element) - }; - - - this.query = function (selector, element) { - //self.log('query: '+selector); - if (selector) { - if (typeof selector == 'object') - selector = self.selector(selector, undefined, true); - - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - - if (element && element[0]) element = element[0]; - - if (element && element.isConnected) { - - var route = routes[index]; - - - - /* route.replace(/([^\s])\[/g, function(match, p1) { // -> .class [data-value=...] - return p1 + ' [' - }); */ - //self.log('route'); - //self.log(route); - var routeParts = route.match(/(.*):eq\((\d*)\)/); - - //self.log('routeParts'); - //self.log(routeParts); - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - - if (routeElement.startsWith('.')) - routeElement = '.' + self.classSelector(routeElement); - - //if (self.exist(routeElement)) - element = element.querySelectorAll(routeElement)[routeIndex]; - - /* self.log('routeElement'); - self.log(routeElement); - self.log('routeIndex'); - self.log(routeIndex); */ - } else { - //if (self.exist(route)) - if (route.startsWith('.')) - route = '.' + self.classSelector(route); - element = element.querySelectorAll(route)[0]; - } - } else { - element = undefined; - } - } - //element.innerHTML = 'test'; - //element.style.display = 'none'; - //self.log(element); - //if (element && !Array.isArray(element)) element = [element]; - if (!element) - self.log('can\'t find the element "' + selector + '" ("query" function)'); - - return element; - } else { - //self.log('function "query" without selector parameters'); - // BUG: many calls from addtag - } - }; - - /* this.queryAllTest = function (selector, element) { - //self.log('query: '+selector); - if (selector) { - - //route = self.replaceAll(route, '[', ' ['); - selector.replace(/([^\s])\[/g, function(match, p1) { // -> .class [data-value=...] - return p1 + '[' - }); - - - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - self.log('routes'); - self.log(routes); - - for (var index in routes) { - self.log('index'); - self.log(index); - - if (element.isConnected) { - - var route = routes[index]; - - var routeParts = route.match(/([^:]*):eq\((\d*)\)/); - - self.log('routeParts'); - self.log(routeParts); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - //if (self.exist(routeElement)) - element = element.querySelectorAll(routeElement)[routeIndex]; - - self.log('routeElement'); - self.log(routeElement); - self.log('routeIndex'); - self.log(routeIndex); - - } else { - //if (self.exist(route)) - self.log('route'); - self.log(route); - element = element.querySelectorAll(route); - } - } else { - self.log('Not in the DOM '+ selector); - self.log('route'); - self.log(route); - element = []; - } - } - //element.innerHTML = 'test'; - //element.style.display = 'none'; - //if (element && !Array.isArray(element)) element = [element]; - //self.log(element); - - return element; - } else { - self.log('DOM "query" without selector parameters'); - } - } */ - /* this.convertRoute = function (route) { - var routeElement, routeValue; - - route = route.replace(/([^\s])\[/g, function(match, p1) { // -> .class [data-value=...] - return p1 + ' [' - }); - - if (route.indexOf(' ')) { - var parts = route.split(' '); - routeElement = parts[0]; - routeValue = parts[1]; - } else { - routeElement = route - } - self.log(routeElement); - self.log(routeValue); - - if (routeElement.startsWith('.')) - routeQuery = '[class='+routeElement+']'; - else if (routeElement.startsWith('#')) - routeQuery = '[id='+routeElement+']'; - else - routeQuery = routeElement + routeValue; - - if (routeValue) - routeQuery += ' ' + routeValue; - - return routeQuery; - } */ - /* - // https://www.examplefiles.net/cs/1222124 - var querySelectorAllWithEq = function(selector, document) { - var remainingSelector = selector; - var baseElement = document; - var firstEqIndex = remainingSelector.indexOf(':eq('); - - while (firstEqIndex !== -1) { - var leftSelector = remainingSelector.substring(0, firstEqIndex); - var rightBracketIndex = remainingSelector.indexOf(')', firstEqIndex); - var eqNum = remainingSelector.substring(firstEqIndex + 4, rightBracketIndex); - eqNum = parseInt(eqNum, 10); - - var selectedElements = baseElement.querySelectorAll(leftSelector); - if (eqNum >= selectedElements.length) { - return []; - } - baseElement = selectedElements[eqNum]; - - remainingSelector = remainingSelector.substring(rightBracketIndex + 1).trim(); - // Note - for now we just ignore direct descendants: - // 'a:eq(0) > i' gets transformed into 'a:eq(0) i'; we could maybe use :scope - // to fix this later but support is iffy - if (remainingSelector.charAt(0) === '>') { - remainingSelector = remainingSelector.substring(1).trim(); - } - - firstEqIndex = remainingSelector.indexOf(':eq('); - } - - if (remainingSelector !== '') { - return Array.from(baseElement.querySelectorAll(remainingSelector)); - } - - return [baseElement]; - }; */ - this.queryAll = function (selector, element) { - //self.log('queryAll: '+selector); - if (selector) { - - if (Array.isArray(selector)) { - let elements = self.queryAll(selector[0]); - selector.shift(); - for (let str of selector) { - elements = Array.prototype.slice.call(elements).concat(Array.prototype.slice.call(self.queryAll(str))); - - //elements = elements.concat(self.queryAll(str)); - } - /* console.log('queryAll'); - console.log(elements); */ - return elements; - - } else { - - /* - if (selector.indexOf(',')>= 0) { - return element.querySelectorAll(selector) - } - // TO DO: check why all the rest - */ - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - /* self.log('routes'); - self.log(routes); */ - /* self.log('element[0]'); - self.log(element[0]); */ - for (var index in routes) { - - if (element && element[0]) element = element[0]; - - /* self.log('element'); - self.log(element); */ - if (element && element.isConnected) { - - var route = routes[index]; - - var routeParts = route.match(/([^:]*):eq\((\d*)\)/); - - /* self.log('route'); - self.log(route); - self.log('routeParts'); - self.log(routeParts); */ - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - /* self.log('routeElement'); - self.log(routeElement); - self.log('routeIndex'); - self.log(routeIndex); */ - if (routeElement.startsWith('.')) - routeElement = '.' + self.classSelector(routeElement); - - //if (self.exist(routeElement)) - element = element.querySelectorAll(routeElement)[routeIndex]; - - if (index == (routes.length - 1) && element) { - /* console.log('index:'+index); - console.log('routes.length:'+routes.length); */ - element = [element]; - } - - } else { - //if (self.exist(route)) - if (route.startsWith('.')) - routeElement = '.' + self.classSelector(route); - - /* self.log('route'); - self.log(route); */ - element = element.querySelectorAll(route); - } - } else { - //self.log('!element.isConnected'); - element = []; - } - } - - //if (element && !Array.isArray(element)) element = [element]; - //if (element && !element.length) element = [element]; - if (!element) - self.log('No element selected by ' + selector); - //else - // if (!Array.isArray(element)) - // element = [element]; - return element; - } - } else { - console.log('%cDOM queryAll requires selector argument', 'color: orange'); - //self.log('DOM "query" without selector parameters'); - } - }; - - /* this.queryAll = function (selector, element) { - //self.log('query: '+selector); - if (selector) { - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - var route = routes[index]; - - //onsole.log('route'); - //self.log(route); - - var routeParts = route.match(/(.*):eq\((\d*)\)/); - - //self.log('routeParts'); - //self.log(routeParts); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - //if (self.exist(routeElement)) - element = [element.querySelectorAll(routeElement)[routeIndex]]; - } else { - //if (self.exist(route)) - element = element.querySelectorAll(route); - } - } - //element.innerHTML = 'test'; - //element.style.display = 'none'; - //if (element && !Array.isArray(element)) element = [element]; - //self.log(element); - - return element; - } else { - self.log('DOM "query" without selector parameters'); - } - } */ - /* var querySelectorAllWithEq = function(selector, document) { - var remainingSelector = selector; - var baseElement = document; - var firstEqIndex = remainingSelector.indexOf(':eq('); - - while (firstEqIndex !== -1) { - var leftSelector = remainingSelector.substring(0, firstEqIndex); - var rightBracketIndex = remainingSelector.indexOf(')', firstEqIndex); - var eqNum = remainingSelector.substring(firstEqIndex + 4, rightBracketIndex); - eqNum = parseInt(eqNum, 10); - - var selectedElements = baseElement.querySelectorAll(leftSelector); - if (eqNum >= selectedElements.length) { - return []; - } - baseElement = selectedElements[eqNum]; - - remainingSelector = remainingSelector.substring(rightBracketIndex + 1).trim(); - // Note - for now we just ignore direct descendants: - // 'a:eq(0) > i' gets transformed into 'a:eq(0) i'; we could maybe use :scope - // to fix this later but support is iffy - if (remainingSelector.charAt(0) === '>') { - remainingSelector = remainingSelector.substring(1).trim(); - } - - firstEqIndex = remainingSelector.indexOf(':eq('); - } - - if (remainingSelector !== '') { - return Array.from(baseElement.querySelectorAll(remainingSelector)); - } - - return [baseElement]; - }; */ - this.jitcss = function (classes) { - // https://tailwindcss.com/docs/just-in-time-mode - if (classes.indexOf('-[') > -1) { - let classesArr = classes.split(' '); // change to one or more spaces - - // (sm\:|md\:|lg\:|xl\:|2xl\:)? - self.log('jitcss'); - - for (cl of classesArr) { - self.log(cl); - let par = [...cl.matchAll(new RegExp('([^-]+)[\-][\[](.+)\]', 'g'))]; - self.log('jitcss'); - self.log(par); - } - } - - /* sm:w-1 - - .w-1 { - width: 1em; - } - - @media (min-width: 640px) { - .sm\:w-1 { width: 1em } - } - */ - }; - - this.compileClasses = function (string) { - - var classesString = string; - - // classes shortcuts - if (self.json.shortcuts && self.json.shortcuts.class) { - for (shortcut in self.json.shortcuts.class) { - if (string.indexOf(shortcut) > -1) { - classesString = self.replaceAll(string, shortcut, self.json.shortcuts.class[shortcut]); - } - } - } - - // dynamic classes - if (string.indexOf('(') >= 0) { - //self.log('compileClasses'); - classesString = ''; - let classesArr = string.split(' '); - for (cl of classesArr) { - /* self.log('cl'); - self.log(cl); */ - if (cl.indexOf('(') >= 0 && cl.endsWith(')')) { - let classArr = cl.split('('); - classArr[1] = classArr[1].slice(0, -1); // remove ) - - - - - - - - //let par = [...cl.match(new RegExp('([^\(]+)\(([^\)]+)\)$'))]; // doesn't work - /* self.log('classArr'); - self.log(classArr); - self.log('classArr[1]'); - self.log(classArr[1]); - self.log('self.js(classArr[1])'); - self.log(self.js(classArr[1])); */ - if (Boolean(self.js(classArr[1]))) { - if (classesString !== '') classesString += ' '; - classesString += classArr[0]; - } - - } else { - if (classesString !== '') classesString += ' '; - classesString += cl; - } - } - - if (string == classesString) { - self.log('wrong dynamic class syntax'); - self.log(string); - } - - } - - return classesString; - - }; - - this.createElement = function (params, selectorParams) { - - let selector = params.selector || params.container; - var container = selector || self.selector(selectorParams); - var containerElement = self.query(container); - var newSelector = self.selector(params, selectorParams); // from 0.9.6: must stay before document.createElement - - - - - - - /* console.log('append'); - console.log('selector:'+selector); - console.log('container:'+container); - console.log('newSelector:'+newSelector); */ - var newElements = []; - - //if (containerElement) - //containerElements.forEach(function (containerElement, index) { - if (containerElement) { - - if (!params) params = {}; - - var element = document.createElement(params.tag); - - containerElement.appendChild(element); - - if (params.attr) { - // shortcuts (windy property not in twind) and dynamic classes with js condition - if (params.attr.class) { - // replace shortcuts and dynamic classes: class(condition) - params.attr.class = self.compileClasses(params.attr.class); - } - } - - //if (container) element.setAttribute('data-selector', self.selector(params, selectorParams)); - //if (container) element.setAttribute('data-selector', newSelector); // from 0.9.6. removed 1.0.12 - // for IDE - self.dataStorage.set(element, 'code', params); - self.dataStorage.set(element, 'key', params.key); - - /* if (params.attr && params.attr.class) - self.jitcss(params.attr.class); */ - newElements.push(element); - - if (params.attr) self.setAttributes(newElements, params.attr); - if (params.style) self.css(params, newSelector); // TO DO: deprecated / to be removed; - - - - - - - - - /* // attributes TO DO: move up / call self.attr - if (params.attr) - for (var attrId in params.attr) - self.attribute(newElements, attrId, self.replaceProperties(params.attr[attrId])); - //self.log(self.replaceProperties(params.attr[attrId])); - //$(selector).attr(attrId, params.attr[attrId]); */ - } - - //}); - return newElements; - - /* for (let element of elements) { - element.appendChild(string); - } */ - }; - - /* this.newSelector = function (params, selectorParams) { - var container = self.selector(self.extend({}, params, selectorParams), undefined, true); - if (container) { - var selectorObj = { - container: container, - //class: params.class, - //value: params.value, - //'data-value': params['data-value'] - }; // , selectorParams); - self.log('container'); - self.log(container); - var index = document.querySelectorAll(container).length; - if (index > 1) selectorObj.index = index-1; - self.log('newSelector'); - self.log(selectorObj); - return selectorObj; - } else { - self.log('container undefine in newSelector'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } -*/ - /* - this.editor = function (params, selectorParams, args) { - self.log('editor'); - self.log('params'); - self.log(params); - var selector = self.selector(selectorParams, undefined, true); // self.selector(params, undefined, true) || - if (selector) { - var element = self.query(selector); - - if (element) { - - if (!self.quillElements[selector]) { - self.quillElements[selector] = new Quill(element, { - modules: params.modules || { // or default modules - toolbar: [ - [{ header: [1, 2, false] }], - ['bold', 'italic', 'underline'], - ['image', 'code-block'] - ] - }, - // scrollingContainer: '#scrolling-container', - placeholder: params.placeholder || 'Write here', - theme: params.theme || 'bubble' - }); - } - - if (self.quillElements[selector]) { - - if (params.setContents) { - var contents = self.replaceProperties(params.setContents, args); - self.quillElements[selector].setContents(contents); - } - - if (params.getContents) { - self.quillElements[params.getContents].getContents(); - } - - if (params.on) { - - for (var eventId in params.on) { - self.editorChangeFunctions[selector] = params.on; - - if (params.on[eventId]) { - - self.quillElements[selector].on(eventId, function(delta, oldDelta, source) { - var action = self.editorChangeFunctions[selector][eventId]; - var actionWithResult = self.replaceResult(action, delta); - //self.do(actionWithResult); - self.do(actionWithResult); - - }); - } - } - } - } - } else { - self.log('can\'t find the element "'+ selector + '" ("editor" function)'); - self.log(params); - } - } else { - self.log('the "editor" function has a wrong selector'); - self.log(params); - } - - } - */ - this.do = this.action = this.execute = function (params, selectorParams, args) { - /* self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - self.log('args'); - self.log(args); */ - - if (params !== undefined && params !== null) { // empty string is ok - - /* - // problematic for nested {args} / {selector} - if (selectorParams && typeof selectorParams == 'string') { - params = self.replaceProperty(params, 'selector', selectorParams); - } - if (args) { - params = self.replaceProperty(params, 'args', args); - } - */ - if (typeof params == 'string') - params = self.replaceProperties(params, args); - - let pluginsRequired = self.pluginsRequired(params); - /* self.log('pluginsRequired'); - self.log(pluginsRequired); */ - if (pluginsRequired.length > 0) - //let params = [params, args, selectorParams]; - self.pluginsLoader(pluginsRequired, self.do, [params, selectorParams, args]); - else { - - if (Array.isArray(params)) - for (var obj of params) - self.do(obj, selectorParams, args); // -> execute dopo aver portato qui pluginsLoaded - else if (typeof params == 'object') { - - /* if (params.after) { - let paramsAfter = params.after; - let paramsWithoutAfter = self.cloneObject(params); - delete paramsWithoutAfter.after; - self.timer({ - after: paramsAfter, - do: paramsWithoutAfter - }); - } else { - */ - if (params.if == undefined || self.if(params.if)) { // || Boolean(self.js(params.if))) { // , args - /* console.log('IF---------------'); - console.log(params.if); - console.log(params); */ - if (self.only(params.roles, params.user)) { - - //if (!params) params = {}; - //var newContainer; //self.newSelector(params, selectorParams); // {container: selector} - // Add an element in the DOM - if (params.tag) { - - var selector = self.selector(params, selectorParams); - - /* self.log('selector'); - self.log(selector); */ - self.extendJsonFromElement(params); // or selectorParams - - - - - - //newContainer = {selector: selector}; - //if (1) //self.user('uid') == 'L0y20rjPp6a6ejqVuDXuTWCU2rH3') //'ocXuFBV4aWcy7KZMAmi6mICFi872') - // create new html element - var newElements = self.createElement(params, selectorParams); - - /* if (params.key == 'text') - //let element = self.query(self.selector(params.selector)); - newElements.innerText = self.text(nested); */ - if (params.matchMedia) { - for (var mediaEvent in params.matchMedia) { - self.matchMedia(params.matchMedia[mediaEvent], mediaEvent); - } - } - - if (params.html) { - - self.html(params.html, selector, args); - - } else { - - // nested html tags as property - for (var par in params) // && (par !== 'attr') - if ((nodes.exclude.indexOf(par) < 0) && (nodes.params.indexOf(par) < 0)) - self.nested({ key: par, obj: params[par], selector: { selector: selector }, args: args }); - - } - - self.on(params.on, { selector: selector }); - - - } else { - - var selector = self.selector(params, selectorParams); - - for (var par in params) - if ((nodes.exclude.indexOf(par) < 0) && (nodes.params.indexOf(par) < 0)) - self.nested({ key: par, obj: params[par], selector: selector, args: args }); - - if (params.on) - self.on(params.on, { selector: selector }); - - } - - - } // end of self.only - - } - //} - } else if (typeof params == 'function') - return params(selectorParams); - - else - self.log('can\'t execute: ' + params); - } - - } - }; - - this.callback = function (params) { - /* console.log('callback'); - console.log(params); */ - // {do, find, replace} - if (params) { - var path = params.to; - if (params.var) path = 'var ' + params.var; // TO DO: remove - let selector; - let element = params.element; // elementToSelector ? - if (element && element.isConnected) params.value = self.elementToSelector(element); - if (path) { - var context = self.context(path); - self.element({ path: path, value: params.value, root: context }); - } - if (params.do) - self.do(params.do, selector); - } - }; - - this.nested = function (params) { - /* console.log('nested'); - console.log(params); */ - // check plugins required - let pluginsRequired = self.pluginsRequired(params.key); - if (pluginsRequired.length > 0) { - self.pluginsLoader(pluginsRequired, self.nested, [params]); - } else { - - - - // TO DO: regular expression like in this.element (should include setup and also :) - if (params.key.startsWith('set ')) { - self.setData({ key: params.key.substr(4), value: params.obj }); - } else if (params.key.startsWith('var ') || params.key.startsWith('data ') || params.key.startsWith('set ')) { - // TO DO: remove this option. Is too ambiguous for debug -> use set - // deprecated from 1.0.4 - console.log('%cdeprecated key: "' + params.key + '". Use "set key": "value"}', 'color:orange'); - - // Data setting prefix - // should be removed and replaced with the method "set" to improve the compatibility - // with the other possible keys (js functions, jsonic methods, html tags ex. ) - // https://www.w3schools.com/tags/tag_data.asp - self.setData({ key: params.key, value: params.obj }); - - } else { - - // CHECK IF KEY IS METHOD - //console.log('check if is a method'); - var method = self.element({ path: params.key, root: self.methods }); - - if (method) { // search in jsonic.methods - self.log('METHOD: ' + params.key, 'grey'); - var methodArgs = params.obj; - - /* if (params.key == 'swiper init') { - self.log('method: ' + params.key); - self.log('methodArgs'); - self.log(methodArgs); - self.log('params.selector'); - self.log(params.selector); - self.log('-----------'); - } */ - //methodArgs = self.replaceProperty(methodArgs, 'selector', params.selector); - method(methodArgs, params.selector, params.args); - - - /* } else if (params.key == 'set') { // TO DO: REMOVE - - // JS METHOD (old) - - var actionObj = {}; - actionObj[params.key] = params.obj; - self.do(actionObj, params.selector); */ - /* } else if (nodes.functions.indexOf(params.key) >= 0) { // TO DO: REMOVE - - // JS METHOD (old) - - var actionObj = {}; - actionObj[params.key] = params.obj; - //self.do(actionObj, undefined, params.selector); - self.do(actionObj, params.selector); */ - } else { - - // CHECK IF KEY IS A PARTS - //console.log('check if is a part'); - // shortcut: content - let nested; - let part; - - var jsonicPart = false; - if (self.json.parts) { // && par.match(/[.>]+/)) - part = self.element({ path: self.replaceAll(params.key, ':', '.'), root: self.json.parts }); - /* if (par.indexOf(':')>0 && !part) { - jsonicPart = true; - self.firebaseGetPart({localPath:localPath, container: params.selector, arg:params.obj}); - } */ - } - - if (part) { - self.log('PART: ' + params.key, 'grey'); - - /* console.log('params'); - console.log(params); */ - var partObj = params.obj; - //nested = self.replaceProperty(part, 'value', params.obj); // obsolete? - //nested = self.replaceProperty(part, 'arg', partObj); // obsolete - //if (typeof partObj == 'string' && partObj.indexOf('{') >= 0) { // obsolete? - // TO DO: this should be already inside self.do - partObj = self.replaceProperties(partObj); - // for backward compatibility can be partObj, null, true) // true is removeUndefined - //} - /* console.log('partObj'); - console.log(partObj); - */ - //var partSelector = params.selector || partObj.selector; - // TO DO: Check this - // seems a workaround for fantacards/ui:qrcode - // parts can receive the parameters {selector:..., setup:...} - partObj.selector = partObj.selector || params.selector; - - // TO DO: deprecated fantacards:setPlayer - if (partObj.setup) partObj = partObj.setup; - // overwrites partObj.selector but execute receive params.selector - // TO DO: replaceProperty should be improved to get also sub values like {arguments:on.success} - //nested = self.replaceProperty(part, 'setup', partObj); // {setup} -> {arguments} - //nested = self.replaceProperty(nested, 'arguments', partObj); - //nested = self.replacePropertyWithPrefix(part, 'setup:', partObj); // {setup} -> {arguments} - //nested = self.replacePropertyWithPrefix(nested, 'arguments:', partObj);// to tix - nested = self.replacePropertyWithPrefix(part, 'setup', partObj); // {setup} -> {arguments} - nested = self.replacePropertyWithPrefix(nested, 'arguments', partObj); // to tix - - - self.extendJsonFromElement(nested); // or selectorParams - - //self.do(nested, partSelector, partObj); - self.do(nested, params.selector, partObj); - - /* - self.log('nested'); - self.log(nested); - - self.log('part key'); - self.log(params.key); - self.log('part obj'); - self.log(part); - */ - } else { // if (!jsonicPart) { // should be if (par !== 'on', 'attr', 'style', 'items/data') - // params.key is not var/data, a method, a part - //var jsFunction = self.element({path: params.key, root: self.functions}); - if (self.json && self.json.functions && params.key && self.json.functions[params.key]) { - //if (self.json.functions[params.key]) { - self.log('FUNCTION: ' + params.key, 'grey'); - - - /* self.log('pluginsRequired'); - self.log(pluginsRequired); */ - let args = self.replaceProperties(params.obj, undefined, true); // undefined properties -> '' - - - - - /* console.log('%cargs', 'color:red'); - console.log(args); */ - if (!args || !Array.isArray(args)) args = [args]; - - if (self.json.functions[params.key].requires) { - let pluginsRequired = []; - for (let plugin of self.json.functions[params.key].requires) { - if (!self.pluginsLoaded[plugin]) - pluginsRequired.push({ "name": plugin, version: "" }); - } - - if (pluginsRequired.length > 0) - //self.pluginsLoader(pluginsRequired, self.functions[params.key], args); - self.pluginsLoader(pluginsRequired, self.function, [{ name: params.key, arguments: args }]); - else { - self.log('Plugins already loaded: ' + params.key, 'grey'); - self.function({ name: params.key, arguments: args }); - //self.functions[params.key](...args); - } - } else { - /* let args = self.replaceProperties(params.obj); - if (!args || !Array.isArray(args)) args = [args]; */ - self.log('Function without plugin required: ' + params.key, 'grey'); - self.function({ name: params.key, arguments: args }); // TO DO: check why here it can't have [] - - //self.functions[params.key](...args); - } - - } else { - var windowFunction = self.element({ path: params.key, root: window }); - if (typeof windowFunction === 'function') { - self.log('WINDOW function: ' + params.key, 'grey'); - windowFunction(self.replaceProperties(params.obj, undefined, true)); // undefined properties -> '' - - //windowFunction(self.replaceProperties(params.obj)); - } else if (windowFunction !== undefined) { - self.log('window.' + params.key + ' is not a function', 'red'); - //self.log(params.key + ' not found', 'red'); - // use set for window assignment - /* - self.element({path: params.key, value:params.obj, root: window}); */ - } else { - // NESTED HTML - // Need to be improved. with nestedAction and nestedTag - // here we can search only nestedAction - // and from html we can search only for nestedTag's - //nested = params.obj; // removed in 1.0.1 - // if is a nested html params.selector is required - // impossible to understand if we are inside an html method - // because the html tags can be nested and with any name - if (params.selector) { // added in 1.0.1 - self.log('TAG: ' + params.key, 'grey'); - // should be also in this.html function if params is an array - let pluginsRequired = self.pluginsRequiredByTag(params.obj, params.key); - if (pluginsRequired.length > 0) { - let htmlTagParams = [params.obj, params.selector, params.key]; - self.pluginsLoader(pluginsRequired, self.htmlTag, htmlTagParams); - } else { - self.htmlTag(params.obj, params.selector, params.key); // tagParam = params.key - - //if (nested.database) self.addFirebaseTag(self.extend({}, nested, params.selector)); - } - } else { - self.log(params.key + ' not found', 'red'); - } - } - } - } - } - } - - } - }; - - this.setData = function (params) { - //self.log('setData'); - let setObj = {}; - setObj[params.key] = params.value; - self.set(setObj); - - /* if (params.path.indexOf('{') >= 0) - params.path = self.replaceProperties(params.path); - - if (typeof params.value == 'string' && params.value.indexOf('{') >= 0) - params.value = self.replaceProperties(params.value); - - self.element({path: params.path, value: params.value}); */ - /* self.log(params.path); - self.log(self.element({path: params.path})); */ - }; - - this.partContainers = {}; - - - - this.pluginsRequiredByTag = function (params, tagKey) { - // self.log('pluginsRequiredByTag'); - /* self.log('params'); - self.log(params); - self.log('par'); - self.log(par); */ - - if (self.json.resources) { - - // analize function object or array of objects - const pluginsTags = self.json.resources.pluginsTags; - const pluginsAttr = self.json.resources.pluginsAttr; - var pluginsRequired = []; - - if (pluginsTags[tagKey] && !self.pluginsLoaded[pluginsTags[tagKey].name]) - pluginsRequired.push(pluginsTags[tagKey]); - - - - if (typeof params == 'string') { - // for example: "tagName": "string" where tagName requires a plugin - } else if (typeof params == 'object') { - - var objArray; - if (Array.isArray(params)) objArray = params; else objArray = [params]; - - for (var obj of objArray) { - if (obj.attr) { // attr - var attr = 'data-icon'; - if (obj.attr[attr]) { - if (pluginsAttr[attr] && !self.pluginsLoaded[pluginsAttr[attr].name]) - pluginsRequired.push(pluginsAttr[attr]); - } - } - } - } - return pluginsRequired; - } else { - // should load resources - return false; - } - }; - - /* - - 'locale': { - unit: month, weekday - format: long, short, narrow - index: 1, - lang: page:language - */ - this.calendar = function (params, args) { - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-US'; - let calendarArr, todayIndex; - - if (params.unit) { - switch (params.unit) { - case 'month': - const monthFormat = params.format || 'long'; - var format = new Intl.DateTimeFormat(localeName, { month: monthFormat }).format; - calendarArr = [...Array(12).keys()].map((m) => format(new Date(Date.UTC(2021, m)))); - todayIndex = new Date().getMonth(); - break; - case 'weekday': - const weekdayFormat = params.format || 'long'; - var format = new Intl.DateTimeFormat(localeName, { weekday: weekdayFormat }).format; - calendarArr = [...Array(7).keys()].map((day) => format(new Date(Date.UTC(2021, 5, day)))); - todayIndex = self.weekday(); - break; - default: - self.log('"calendar" function can\'t recognize "unit" parameter'); - self.log(params.unit); - break; - } - - if (calendarArr) { - if (params.index !== undefined) { - params.index = self.js(params.index); - let index = Number(self.replaceProperties(params.index, args)); - return calendarArr[index]; - } else { - return calendarArr[todayIndex]; - } - } else { - self.log('"calendar" function can\'t recognize "unit" or "format" parameters'); - } - - } else { - self.log('"calendar" function requires "unit" parameter'); - } - - }; - - - - this.month = function (params, monthFormat = 'long') { - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-GB'; - const format = new Intl.DateTimeFormat(localeName, { month: monthFormat }).format; - const weekdayArr = [...Array(12).keys()].map((m) => format(new Date(Date.UTC(2021, m)))); - if (params !== undefined) { - var index = Number(self.replaceProperties(params)); - return weekdayArr[index]; - } - else - return weekdayArr; - }; - - this.weekday = function (params, weekdayFormat) { - //weekdayFormat = weekdayFormat || 'long'; - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-GB'; - const format = new Intl.DateTimeFormat(localeName, { weekday: weekdayFormat }).format; - const weekdayArr = [...Array(7).keys()].map((day) => format(new Date(Date.UTC(2021, 5, day)))); - var result; - if (params !== undefined) { - var index = Number(self.replaceProperties(params)); - result = weekdayArr[index]; - } - else - result = weekdayArr; - - //if (weekdayFormat == 'short') result = result.substring(0,3); - return result; - - }; - - /* this.array = function (params, args) { // TO DO: to be removed - self.log('array'); - self.log(params); - - if (Array.isArray(params)) - return params; - else if (typeof params == 'string') - return self.docElement(params); - else if (typeof params == 'object') { - if (params && Object.keys(params).length > 0) { // actionObj !== {} - var actionKey = Object.keys(params)[0]; // -> for - var actionFunction = self.docElement('Array.prototype.' + actionKey); // method in window - var actionValue = params[actionKey]; - - //actionValue = self.compile(actionValue, args); // array -> undefined - if (!Array.isArray(actionValue)) - actionValue = [actionValue]; - - if (actionFunction) { - if (typeof actionFunction == 'function') - return actionFunction.call(actionValue); - else - return actionFunction; - } else { - self.log('unknown window function'); - return params; // return the same object - } - } else { - self.log('empty function'); - //self.log(actionObj); - return undefined - } - } - } */ - this.method = function (params, args) { - - var value; - - if (typeof params == 'string') { - return self.docElement(params); - } else { - - if ((params.if == undefined) || self.if(params.if, undefined, args)) { - - if (self.notEmptyObject(params)) { - var actionKey = Object.keys(params)[0]; // -> for - var actionFunction = self.docElement(actionKey); // method in window - var actionValue = params[actionKey]; - //actionValue = self.compile(actionValue, args); - if (!Array.isArray(actionValue)) - actionValue = [actionValue]; - if (actionFunction) { - if (typeof actionFunction == 'function') - return actionFunction(...actionValue); - - else - return actionFunction; - } else { - self.log('unknown function'); - self.log(params); - return params; // return the same object - } - } else { - //self.log('empty function'); - //self.log(params); - return undefined; - } - } - } - - /* - var methodArgs = self.compile(actionValue, args); - - if (value !== undefined) { - - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - - self.log('params'); - self.log(params); - - for (let method of methodArgs) { - for (let key in method) { - if (key !== 'args') { - self.log('key'); - self.log(key); - if (value[key]) - if (method[key] && method[key] !== '') { // va aggiunto? -> && value[key](method[key]) method[key] !== undefined && - methodArgs = method[key]; - self.log('methodArgs'); - self.log(methodArgs); - - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - for (let index in methodArgs) { - let methodArg = self.compile(methodArgs[index], args); - //if (typeof methodArg == 'string' && methodArg !== '' && methodArg == Number(methodArg)) // can be in compile - methodArgs[index] = methodArg; // Number(methodArg) - } - //try { - //} catch (error) { - // self.log('Dayjs function error'); - if (typeof value[key] == 'function') - value = value[key](...methodArgs); // ES6 way - } else - if (typeof value[key] == 'function') - value = value[key](); - else - value = value[key]; - } else { - self.log('Method ' + key + ' in ' + methodName + ' not exist'); - } - } - } - - } else { - self.log('method '+ methodName +' undefined'); - - } - */ - }; - - this.Number = function (params, args) { - self.log('Number'); - return self.method({ "Number": params }, args); - }; - - this.String = function (params, args) { - self.log('String'); - return self.method({ "String": params }, args); - - // jsonic.compile({String:{args:'1',padStart:[2, '0']}}) - /* - "text": { - "String": { - "args": "{hour}", - "padStart": [ - "0", - 2 - ] - } - } - */ - }; - - this.Math = function (params, args) { - return self.method(params, args, 'Math'); - - /* if (!Array.isArray(params)) - params = [params]; - - for (let method of params) { - for (let key in method) { - self.log(key); - if (method[key] && method[key] !== '' && value[key](method[key])) { - //methodArgs = self.compile(method[key]); - methodArgs = method[key]; - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - for (let index in methodArgs) { - let methodArg = self.compile(methodArgs[index]); - if (typeof methodArg == 'string' && methodArg !== '' && methodArg == Number(methodArg)) // can be in compile - methodArgs[index] = Number(methodArg); - } - value = value[key](...methodArgs); // ES6 way - } else - value = value[key](); - } - } - - return value; */ - }; - - - this.dayjs = function (params, args) { - - return self.method(params, args, 'dayjs'); - - /* self.log('dayjs'); - - var value = dayjs(); - if (params.time) - value = dayjs(params.time); - //value = self.compile(value); - - if (!Array.isArray(params)) - params = [params]; - - - for (let method of params) { - for (let key in method) { - - if (key == 'time') { - } else if (value[key]) { - if (method[key] && method[key] !== '' && value[key](method[key])) { - //methodArgs = self.compile(method[key]); - methodArgs = method[key]; - if (!Array.isArray(methodArgs)) - methodArgs = [methodArgs]; - for (let index in methodArgs) { - let methodArg = self.compile(methodArgs[index]); - if (typeof methodArg == 'string' && methodArg !== '' && methodArg == Number(methodArg)) // can be in compile - methodArgs[index] = Number(methodArg); - } - value = value[key](...methodArgs); // ES6 way - } else - value = value[key](); - } else { - try { - } catch (error) { - self.log('Dayjs function error'); - self.log(error); - self.log('key'); - self.log(key); - self.log('method[key]'); - self.log(method[key]); - } - - } - } - self.log('value'); - self.log(value); - } - return value; */ - }; - - this.moment = function (params, args) { - - return self.method(params, args, 'moment'); - - /* self.log('moment'); - - var value = moment(); - if (params.time) - value = moment(params.time); - - if (!Array.isArray(params)) - params = [params]; - - for (let method of params) { - for (let key in method) { - if (key !== 'time') { - if (key == 'add') { - value = value.add(Number(method[key].value), method[key].unit); - } else if (key == 'subtract') { - value = value.add(Number(method[key].value), method[key].unit); - } else if (method[key] && method[key] !== '' && value[key](method[key])) { - value = value[key](method[key]); - } else { - self.log('Moment function error: '); - self.log('key'); - self.log(key); - self.log('method[key]'); - self.log(method[key]); - } - } - } - self.log('value'); - self.log(value); - - } - return value; - */ - }; - - - /* const methodsList = ['day, format', 'year', 'years', 'quarter', 'dayOfYear', 'month', 'months', 'date', 'minute', 'minutes', 'hour', 'hours', 'second', 'seconds', 'millisecond', 'milliseconds', 'weekday', 'weekdays', 'isoWeekday', 'weekYear', 'isoWeekYear', 'weeksInYear', 'week', 'isoWeek', 'set', 'max', 'min', 'local', 'parseZone', 'unix', 'utc', 'utcOffset', 'zone', 'isValid', 'invalid', 'valueOf', 'startOf', 'endOf', 'fromNow', 'toNow', 'from', 'to', 'calendar', 'diff', 'daysInMonth', 'toDate', 'toArray', 'toJSON', 'toString', 'toISOString', 'toObject', 'inspect', 'isBefore', 'isSame', 'isAfter', 'isSameOrBefore', 'isSameOrAfter', 'isBetween', 'isDST', 'isLeapYear', 'isDate', 'locale', 'localeData', 'lang', 'monthsShort', 'weekdaysShort', 'weekdaysMin', 'defineLocale', 'updateLocale', 'monthsParse', 'weekdaysParse', 'longDateFormat', 'isPM', 'meridiem', 'relativeTime', 'pastFuture', 'ordinal', 'preparse', 'postformat', 'invalidDate', 'firstDayOfWeek', 'firstDayOfYear', 'duration', 'clone', 'humanize', 'asMilliseconds']; - for (var method in methodsList) { - if (params[method]) value = value[method](params[method]); - } */ - /* for (let param in params) { - if (param !== 'time') { - if (typeof value == 'object') { - //if (param == 'day') value = value.day(Number(params[param])); - if (param == 'add') { - self.log('params.add.value'); - self.log(params.add.value); - self.log('params.add.unit'); - self.log(params.add.unit); - self.log('value'); - self.log(value); - value.add(Number(5), params.add.unit); - self.log('value.format(H)'); - self.log(value.format('H')); - } - else if (param == 'subtract') value.add(Number(params.subtract.value), params.subtract.unit); - else if (value[param] && value[param](params[param])) - value = value[param](params[param]); - else - self.log('Moment function error: '+ params[param]); - } - self.log('value'); - self.log(value); - } - } -*/ - /* this.addNestedTag = function (params, selectorParams) { - var selector = self.selector(self.extend({}, params, selectorParams)); - // remove tag params - var nestedParams = self.cloneObject(params); - var tagParams = ['tag', 'container', 'id', 'class', 'value', 'data-value', 'style', 'attr', 'title', 'text', 'animation', 'action', 'on', 'src', 'media', 'color', 'background', 'width', 'height', 'margin', 'padding', 'firebase']; - for (var par in nestedParams) { - if (tagParams.indexOf(par) >= 0) - delete nestedParams[par] - } - - // serach for nested params - var mainTags = ['div', 'ul', 'p', 'span', 'a', 'button', 'input', 'textarea', 'iframe', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'figure', 'figcaption', 'svg', 'small', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'icons']; - for (var par in nestedParams) { - self.log(par + ' NESTED IN ' + selector); - if (mainTags.indexOf(par) >= 0) { - self.htmlTag(nestedParams[par], {container: selector}, mainTags[mainTags.indexOf(par)]); - } - } - } */ - this.dynamicCss = function (selector, property, value) { - if (value.indexOf('{') >= 0) { - var resizeData = self.dataStorage.get(element, "resize"); - //var resizeData = $(selector).data('resize'); - if (!resizeData) resizeData = {}; - resizeData[property] = value; - var resizeData = self.dataStorage.set(element, "resize", resizeData); - //$(selector).data('resize', resizeData); - if (!self.resizeActions[selector]) self.resizeActions[selector] = {}; - self.resizeActions[selector][property] = value; - var result = self.replaceProperties(value) || ''; - //$(selector).css(property, result); // al cambio di pagina su this.page applichiamo self.resizeEvent() - /* self.log('----------------------'); - self.log('dynamicCss'); - self.log('selector'); - self.log(selector); - self.log('property'); - self.log(property); - self.log('value'); - self.log(value); - self.log('result'); - self.log(result); - self.log('----------------------'); - */ - } else { - var style = {}; - style[property] = value; - self.css({ - style: style - }); - //$(selector).css(property, value); - } - }; - - /* this.calc = function (selector, property, value) { - if (value.indexOf('{')>= 0) { - //var calcFunction = String(element.match(/calc\(([^\)]*)\)/)[0]); - var result = self.replaceProperties(value) || ''; - return result; - } else { - return value; - } - } */ - /* this.hTag = function (params, selectorParams, index) { // this.img already exist - if (Array.isArray(params)) { - for (var index in params) - self.hTag(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.hTag(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'h'+index; - var paramsReplaced = self.replaceProperties(params); - self.addTag(paramsReplaced, selectorParams); - } - } - } */ - /* this.img = function (params, selectorParams, args) { - //self.log('img'); - var tagParam = 'img'; - var mainParam = 'src'; - - if (Array.isArray(params)) { - for (var index in params) - self.img(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.img(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {src: params}}; - params.tag = 'img'; - //if (params.media) params.src = '{media:' + params.media + '}'; // can go under replaceProperties - var paramsReplaced = self.replaceProperties(params, args); - //var container = params.container || self.selector(selectorParams); - - self.addTag(paramsReplaced, selectorParams); - } - } - } */ - /* this.small = function (params, selectorParams) { // bootstrap - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.small(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.small(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'small'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* this.button = function (params, selectorParams) { // bootstrap - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.button(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.button(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'button'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* - this.input = function (params, selectorParams) { - var tagParam = 'input'; - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.input(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.input(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - self.addTag(self.createTagParams(params, tagParam, mainParam), selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } - - this.span = function (params, selectorParams) { - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.span(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.span(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - params.tag = 'span'; - // qui ci andrebbe replaceProperties - if (typeof params == 'string') {params = {text: params}}; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } - */ - /* this.a = function (params, selectorParams) { - var mainParam = 'text'; - var tagParam = 'a'; - if (Array.isArray(params)) { - for (var index in params) - self.a(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.a(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {text: params}}; - params.tag = 'a'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* this.p = function (params, selectorParams) { - var mainParam = 'html'; - if (Array.isArray(params)) { - for (var index in params) - self.p(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.p(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {html: params}}; - params.tag = 'p'; - self.addTag(params, selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } */ - /* this.lottie = function (params, selectorParams, args) { - self.htmlTag(params, selectorParams, 'lottie-player', 'src'); - } */ - //this.lottie = function (params, selectorParams, args) { - // self.htmlTag(params, selectorParams, 'lottie-player', 'src'); - /* self.log('lottie'); - var mainParam = 'src'; - var tagParam = 'lottie-player'; - if (Array.isArray(params)) { - for (var index in params) - self.lottie(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.lottie(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - var container = params.container || self.selector(selectorParams); - // qui ci andrebbe replaceProperties - //this.alert(self.selector(self.extend({}, params, selectorParams))); - self.addTag(self.createTagParams(params, tagParam, mainParam), {container: container}); - //if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } */ - //} - /* this.iframe = function (params, selectorParams) { - var mainParam = 'src'; - if (Array.isArray(params)) { - for (var index in params) - self.iframe(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.iframe(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') {params = {src: params}}; - params.tag = 'iframe'; - var paramsReplaced = self.replaceProperties(params); - self.addTag(paramsReplaced, selectorParams); - } - } - } */ - /* this.textarea = function (params, selectorParams) { - if (Array.isArray(params)) { - for (var index in params) - self.textarea(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.textarea(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (!params.tag) params.tag = 'textarea'; - //params.container = params.container || self.selector(selectorParams); - self.addTag(params, selectorParams); - } - } - } */ - /* - this.div = function (params, selectorParams) { - if (params.firebase) { - self.log('=========='); - self.log('div'); - self.log(params); - self.log('=========='); - } - - var tagParam = 'div'; - var mainParam = 'text'; - if (Array.isArray(params)) { - for (var index in params) - self.div(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.div(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - self.addTag(self.createTagParams(params, tagParam, mainParam), selectorParams); - if (params.firebase) self.addFirebaseTag(self.extend({}, params, selectorParams)); - } - } - } - - this.ul = function (params, selectorParams) { - if (Array.isArray(params)) { - for (var index in params) - self.ul(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - self.ul(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - params.tag = 'ul'; - - var paramsReplaced = self.replaceProperties(params); - self.addTag(paramsReplaced, selectorParams); - if (params.firebase) self.addFirebaseTag(params); - } - } - } - */ - this.li = function (params, selectorParams) { - if (Array.isArray(params)) { - for (var index in params) - self.li(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = (typeof params.items == 'string') ? self.json.items[params.items] : params.items; - //var itemsArray = params.items; - delete params.items; - for (var index in itemsArray) { - if (self.only(itemsArray[index].roles)) - self.li(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') { params = { html: params }; }; - params.tag = 'li'; - //params.container = params.container || self.selector(selectorParams); - self.do(params, selectorParams); - } - } - }; - - this.remove = function (params, selectorParams, args) { - var selector = self.selector(params.selector || self.selector(selectorParams)); - if (selector) { - var elements = self.queryAll(selector); - if (elements) { - elements.forEach(function (element, index) { - element.remove(); - }); - } - } - }; - - this.dispatchEvent = function (params, selectorParams, args) { - var selector = self.selector(params.selector || self.selector(selectorParams)); - if (selector) { - var elements = self.queryAll(selector); - if (elements) { - elements.forEach(function (element, index) { - element.dispatchEvent(new Event(params.name)); - }); - } - } - }; - - /* this.element with "selector" and "method": (remove/dispatchEvent) */ - this.html = function (params, selectorParams, args) { - /* self.log('html'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); */ - - // TO DO: update - // html properties can be only: - // selector, attr, html, on, for, if - // can't be: - // animate (should go inside on: init?) - // tags (div etc) because it should go inside html - // do - // functions, window functions... - // text should be alternative to html tag. if inside html, it should give an error - // TO DO: verificare se args viene portato agli elementi annidati (non andava con svg) - if (params) { - - if (Array.isArray(params)) { - - // TO DO: shoud check if params require plugins - for (var obj of params) - self.html(obj, selectorParams, args); - } else { - - //if (params.container == '#weatherReport') alert() - //var container = (selectorParams) ? self.selector(selectorParams) : params.container; // unused - //var selector = self.selector(self.extend({}, params, selectorParams), undefined, true); //), undefined, true); - /* - self.log('selector'); - self.log(selector); */ - var container = self.selector(params.selector || params.container) || self.selector(selectorParams); - //var container = self.selector(selectorParams, undefined, true) || self.selector(params, selectorParams, true); - /* self.log('container'); - self.log(container); */ - /* var element = self.query(container); - self.log('element'); - self.log(element); - */ - if (container) { - var element = self.query(container); - - // empty or not? probably yes (like jquery) but we need append/prepend method - // append only all the items in the array - // TO DO: queryAll -> elements - if (element) { - - if (typeof params == 'string') { - - //var paramsCompiled = self.compile(params, args); - var paramsCompiled = self.replaceProperties(params, args); - - //$(container).append(paramsCompiled); // should be .html not append - //element.appendChild(paramsCompiled); - if (paramsCompiled) { - if (typeof paramsCompiled == 'object') { - // should be a nested tag or actions on,for,if,empty - self.do(paramsCompiled, { selector: container }, args); - - } else if (typeof paramsCompiled == 'string') { - element.innerHTML += paramsCompiled; // TO DO: now is like append. Is it correct? - } - } - - } else { - - if (params.empty || params.do == 'empty') { - element.innerHTML = ''; - delete params.empty; - } - - if (params.tag) { - self.do(params, container, args); - //self.nested({key: params.tag, obj: params[par], selector: {selector: container}, args: args}); - } - else if (params.html) { - // replace \" to " - //var htmlCompiled = self.compile(params.html, args); // is undefined - // TO DO: replace all the following "compile" with replaceProperties? - /* self.log('params.html'); - self.log(params.html); */ - var htmlCompiled = self.replaceProperties(params.html, args); - /* self.log('htmlCompiled'); - self.log(htmlCompiled); */ - self.html(htmlCompiled, { selector: container }); - } else if (params.lang) { - //alert(self.json.setup.language); - var textLang = params.lang[self.json.setup.language] || params.lang['en'] || params.lang[Object.keys[0]]; - if (Array.isArray(textLang)) { - var paragraphs = []; - for (var paragraph of textLang) - paragraphs.push({ p: paragraph }); - self.html(paragraphs, selectorParams, args); - } - else - element.innerHTML = self.replaceProperties(textLang, args); - - if (element) { - self.attribute(element, 'data-text', true); // textKey instead of lang? - self.dataStorage.set(element, 'params', params); - } - - } else if (params.text) { // string - //params.text = self.replaceTags({text:params.text}); - //params.text = self.text(params.text); // verifica presenza di tags e traduzioni - //$(selector).text(self.compile(params.text, args)); - element.textContent = self.replaceProperties(params.text, args); - //} else if (params.empty || params.do == 'empty') { - // element.innerHTML = ''; - } else if (params.append) { // string - //params.append = self.replaceTags({text:params.append}); - //$(selector).append(self.compile(params.append, args)); - //element.appendChild(self.compile(params.append, args)); - element.innerHTML += self.replaceProperties(params.append, args); - - } else if (params.prepend) { // string - //params.prepend = self.replaceTags({text:params.prepend}); - //$(selector).prepend(self.compile(params.prepend, args)); - //element.insertBefore(self.compile(params.prepend, args)); - element.innerHTML = self.replaceProperties(params.prepend, args) + element.innerHTML; - - } else if (params.blocks) { // obsolete - self.blocks(params.blocks, { selector: container }, args); - } else { - - let nestedParams = self.cloneObject(params); - if (nestedParams.style) delete nestedParams.style; - if (nestedParams.attr) delete nestedParams.attr; - - console.warn('UNKNOWN TAG'); - console.warn(params); - // on, for, if... (can be changed to include also html) - self.do(nestedParams, { selector: container }, args); - - - if (element.isConnected) { - // case "html":{selector:... attr: } - // the wrong use "html":{selector, attr, html:...} - // now doesn't work (because is inside the last else) - /* if (params.on) { - alert(container); - self.on(params.on, { selector: container }, args); - } */ - - if (params.attr) self.setAttributes(element, params.attr, args); - if (params.style) self.css(params, selectorParams, args); // to be removed - - // TO DO: params.style is deprecated (now in attr or css) - } - //self.blocks(params, selectorParams, args); - } - - - - } - } else { // !element - } - } else { - self.log('"html" object requires selector property', 'red'); - self.log(params); - //self.log(selectorParams); - } - - //} - //} - } - } else { - self.log('"html" object without params'); - } - - }; - - /* this.add = function (params) { // obsoleto, sostituito da html - var selector = self.selector(params); - if (params.inverse) - $(selector).append(params.html); - else - $(selector).prepend(params.html); - } */ - /* this.attr = function (params, selectorParams, args) { - var selector = self.selector(params); - var element = self.query(selector); - for (var attribute in params.attr) - elements.forEach(function (element, index) { - element.setAttribute(attrId, attrValue); - }); - } - */ - /* this.empty = function (params) { - // { [container, class, value, id] } - var selector = self.selector(params); - $(selector).empty(); - } */ - /* this.addClass = function (params) { - var selector = self.selector(params); - $(selector).addClass(params); - } - - this.removeClass = function (params) { - self.log('removeClass'); - var selector = self.selector(params); - $(selector).removeClass(params); - } */ - /* this.toggleClass = function (params) { - var selector = self.selector(params); - $(selector).toggleClass(params); - } */ - //"#wifi > ul > li > span[data-field=share]:contains('Private')" - this.setAttributes = function (elements, attrs, args) { - for (var attribute in attrs) - if (attrs[attribute]) - self.attribute(elements, attribute, self.replaceResult(attrs[attribute], args)); - else - self.attribute(elements, attribute, ""); - //self.attribute(elements, attribute, attrs[attribute]); - //self.attribute(elements, attribute, self.replaceWithPrefix(attrs[attribute], 'result', args)); // TO DO: check - // before remove and check all the {result} occurrence (result excludes do/then/success etc.) - // replaceResult replace {result} from Alert (should be obsolete) - // check in the actual apps if {result} is used - }; - -/* this.setAttributes = function (elements, attrs, args) { - if (!Array.isArray(elements)) elements = [elements]; - elements.forEach(function (element, index) { - for (var attribute in attrs) { - if (typeof attrs[attribute] == 'boolean' && attrs[attribute]) { // it consider also firebase (empty values are removed) - element.setAttribute(attribute, ""); - } else { - //if (attrs[attribute] == undefined) attrs[attribute] = ''; - element.setAttribute(attribute, self.replaceProperties(attrs[attribute])); - } - } - }); - self.attribute(elements, attribute, self.replaceResult(attrs[attribute], args)); - }; */ - - // TO DO: distinguish setAttribute from getAttribute - // because we need to set attribute empty - this.attribute = function (elements, attrId, attrValue) { - if (typeof attrValue !== undefined) { - if (!Array.isArray(elements)) elements = [elements]; - elements.forEach(function (element, index) { - if (typeof attrValue == 'boolean' && attrValue) { // it consider also firebase (empty values are removed) - element.setAttribute(attrId, ""); - } else { - element.setAttribute(attrId, self.replaceProperties(attrValue)); - } - }); - } else { - if (!Array.isArray(elements)) - return elements.getAttribute(attrId); // todo: intercept the error "Cannot read properties of undefined (reading 'getAttribute" - - else - return elements[0].getAttribute(attrId); - } - }; - - this.attr = function (params, selectorParams, args) { - // deprecated. to be replaced with "css" {selector, style, addClass, removeClass, toggleClass} - // css is used as an action to apply addClass removeClass toggleClass - // and to apply style: {...} - //params = self.replaceProperties(params); - self.css(self.replaceProperties(params), selectorParams, args); - }; - - this.styleElement = function (params, element, args) { - for (var styleName in params) { - if (styleName.startsWith('--')) - element.style.setProperty(styleName, self.replaceProperties(params[styleName], args)); - - else - element.style[styleName] = self.replaceProperties(params[styleName], args); - } - }; - - this.css = function (params, selectorParams, args) { - // {selector, style, addClass, removeClass, toggleClass} - - /* console.log('selectorParams'); - console.log(selectorParams); - console.log('css'); - console.log(params); */ - if (Array.isArray(params)) { - for (var obj of params) - self.css(obj, selectorParams, args); - /* } else if (params.selector && Array.isArray(params.selector)) { - for (let selector of params.selector) { - let obj = self.cloneObject(params); - obj.selector = selector; - self.css(obj, selectorParams, args); */ - } else { - - var selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - - //var selector = params.selector || selectorParams; - //var elements = document.querySelectorAll(selector); - //console.log(elements); - if (elements) { - elements.forEach(function (element, index) { - - if (element) { - - if (typeof params.style == 'object') { - self.styleElement(params.style, element, args); - } - - if (params.addClass) - self.addClass(element, params.addClass); - if (params.removeClass) - self.removeClass(element, params.removeClass); - if (params.toggleClass) - self.toggleClass(element, params.toggleClass); - - } else { - self.log('the function "css" can\'t find the selector ' + selector); - self.log(params); - self.log(selectorParams); - } - }); - } else { - self.log('"css" function is unable to select: ' + selector); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } - }; - - /* this.class = function (params) { // obsolete -> css - self.log('self.class'); - self.log(params); - // { [container, class, value, id] - // [style, addClass, removeClass] } - var selector = self.selector(params); - if (params.style) - $(selector).css(params.style); - if (params.add) - $(selector).addClass(params.add); - if (params.remove) - $(selector).removeClass(params.remove); - if (params.toggle) - $(selector).toggleClass(params.toggle); - } */ - /* this.createPage = function (data) { - // SPOSTATA SOTTO fixo.pages.js - - //self.log('createPage'); - //self.log(data); - if (!$('#'+data.id).length) { - $(data.container).append('
      '); - if (data.background) { - $('#'+data.id).css({ - 'background-color': data.background - }); - } - } - } */ - /* this.iconPng = function(icon) { - return 'https://'+self.domain+'/app/files/icons/100white/'+icon+'.png'; - } */ - /* this.imgTag = function (data) { - // DIPENDENZA CON iconPng - - var imgId = data.id || ''; - var imgClass = data.class || ''; - var imgValue = data.value || ''; - var imgStyle = data.style || ''; // || 'width: 84px; margin:6px 10px;'; // ATTENZIONE: stile predefinito da rimuovere - var onClick = (data.action) ? 'onclick="javascript:self.do(\''+data.action+'\',\''+imgValue+'\')" ' : ''; - return ''; - } */ - /* this.setImg = function (data) { - // Sembra inutilizzata - // DIPENDENZA CON iconPng - - // data = {icon, style} - var selector = self.selector(data); - var imgValue = data.value || ''; - $(selector).attr('src', self.iconPng(data.icon)); - if (data.style) $(selector).css(style); - if (data.action) { - $(selector).attr('onclick', 'javascript:self.do(\''+data.action+'\',\''+imgValue+'\')'); - } - } */ - // -------------- - // SVG - // -------------- - /* this.svgSet = function (params) { - //self.log('svgSet'); - //self.log(params); - if (self.json && self.json.icons) { - //if (self.json.setup && self.json.setup.icons) { - - if (params.icon) { - var iconObj = {}; - iconObj.icon = (params.icon.indexOf(':')) ? params.icon.split(/:/)[1] : string; - iconObj.set = (params.icon.indexOf(':')) ? params.icon.split(/:/)[0] : undefined; - - var svgIcons = self.json.icons || {}; // {src, prefix, suffix} - //var svgIcons = self.json.setup.icons || {}; // {src, prefix, suffix} - if (iconObj.set) - if (svgIcons[iconObj.set]) - svgIcons = svgIcons[iconObj.set]; - else - self.log('Can\'t find the icons set "'+iconObj.set+'" in "icons"'); - iconObj.src = svgIcons.src || ''; // serve? - var svgPrefix = svgIcons.prefix || ''; - var svgSuffix = svgIcons.suffix || ''; - //if (iconObj.src !== '' && iconObj.icon) iconObj.src = '#' + svgPrefix + iconObj.icon + svgSuffix; - if (iconObj.icon) { - - if (!svgIcons.preload) - // siamo vicini - iconObj.src = svgIcons.src + '#' + svgPrefix + iconObj.icon + svgSuffix; - else - iconObj.src = '#' + iconObj.set + '_' + svgPrefix + iconObj.icon + svgSuffix; - } - iconObj.viewbox = svgIcons.viewbox; // || '0 0 25 25'; - return iconObj; // {src, set, name, viewbox} - } else { - self.log('icon "name" parameter undefined'); - } - } else { - self.log('Can\'t find "icons" in "setup"'); - } - } - - this.svgChange = function (data) { - self.log('svgChange'); - self.log(data); - - var selector = self.selector(data); //), undefined, true); - var containerElement = self.query(selector); - - var elementSvg = containerElement.querySelectorAll('svg')[0]; - var elementSvgUse = elementSvg.querySelectorAll('use')[0]; - var elementSvgText = elementSvg.querySelectorAll('text')[0]; - var elementSvgCircle = elementSvg.querySelectorAll('circle')[0]; - - var iconObj = self.svgSet(data); // {src, set, name, viewbox} - - if (iconObj.src) - elementSvgUse.setAttribute('xlink:href', iconObj.src); - //$(data.container + ' > svg > use').attr('xlink:href', iconObj.src); - - if (data.text !== undefined) { - elementSvgText.textContent = data.text; - // $(data.container + ' > svg > text').text(data.text); - - var textY = 6.5; // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor - if (data.textSize !== undefined) {textY = data.textSize/2;} - - if (data.textPosition == 'bottom') { // textPosition should be removed - elementSvgUse.setAttribute('transform', 'translate(0, -20) scale(0.80)'); - //$(data.container + ' > svg > use').attr("transform", "translate(0, -20) scale(0.80)"); - textY += 26; - } - - elementSvgText.setAttribute('y', textY); - //$(data.container + ' > svg > text').attr('y',textY); - elementSvgText.style['font-size'] = data.textSize+'px'; - //$(data.container + ' > svg > text').css('font-size',data.textSize+'px'); - - } else { - elementSvgText.textContent = ''; - //$(data.container + ' > svg > text').text(''); - - } - if (data.background !== undefined){ - - elementSvgCircle.setAttribute('fill', data.background); - elementSvgCircle.setAttribute('fill-opacity', 1); - elementSvgCircle.style['stroke'] = data.background; - } - if (data.border !== undefined) { - elementSvgCircle.setAttribute('stroke-opacity', 1); - elementSvgCircle.style['stroke'] = data.border; - } - - if (data.color !== undefined && data.color !== 'colored') { - elementSvgUse.style['fill'] = data.color; - } - if (data.textColor !== undefined){ - elementSvgText.style['fill'] = data.textColor; - } else if (data.color) { - elementSvgText.style['fill'] = data.color; - } - - } - - this.svgImage = function (data) { - //$(data.container).hide(); - //$(data.container).css({opacity:0}); - - var selector = self.selector(data); //), undefined, true); - var containerElement = self.query(selector); - //var containerElement = self.query(data.container); - - //if (data.value !== undefined) $(data.container).data('value', data.value); - - var iconObj = self.svgSet(data); // {src, set, name, viewbox} - var viewBox = iconObj.viewbox || '-50 -50 100 100'; - var htmlString = ''; - - if (containerElement) { - containerElement.innerHTML = htmlString; - - //$(data.container).append(''); - - var elementSvg = containerElement.querySelectorAll('svg')[0]; - var elementSvgUse = elementSvg.querySelectorAll('use')[0]; - var elementSvgText = elementSvg.querySelectorAll('text')[0]; - var elementSvgCircle = elementSvg.querySelectorAll('circle')[0]; - - elementSvgUse.setAttribute('xlink:href', iconObj.src); - //$(data.container + ' > svg > use').attr('xlink:href', iconObj.src); - - if (data.text !== undefined) { - - elementSvgText.textContent = data.text; - // $(data.container + ' > svg > text').text(data.text); - - var textY = 6.5; // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor - if (data.textSize !== undefined) {textY = data.textSize/2;} - - if (data.textPosition == 'bottom') { // textPosition should be removed - elementSvgUse.setAttribute('transform', 'translate(0, -20) scale(0.80)'); - //$(data.container + ' > svg > use').attr("transform", "translate(0, -20) scale(0.80)"); - textY += 26; - } - - elementSvgText.setAttribute('y', textY); - //$(data.container + ' > svg > text').attr('y',textY); - elementSvgText.style['font-size'] = data.textSize+'px'; - //$(data.container + ' > svg > text').css('font-size',data.textSize+'px'); - } - - - if (data.background !== undefined) { - - elementSvgCircle.setAttribute('fill', data.background); - elementSvgCircle.setAttribute('fill-opacity', 1); - elementSvgCircle.style['stroke'] = data.background; - } - if (data.border !== undefined){ - elementSvgCircle.setAttribute('stroke-opacity', 1); - elementSvgCircle.style['stroke'] = data.border; - - //$(data.container + ' > svg > circle').attr('stroke-opacity', 1); - // FORSE DEVE DIVENTARE attr ANZICHE' css - //$(data.container + ' > svg > circle').css({'stroke': data.border}); - } - - //if ((data.color === undefined) && (data.color !== 'colored')) {data.color = '#fff';} - if (data.color !== undefined && data.color !== 'colored') { - elementSvgUse.style['fill'] = data.color; - //$(data.container + ' > svg > use').css({'fill': data.color}); - //$(data.container + ' > svg > text').css({'fill': data.color}); - } - if (data.textColor !== undefined){ - elementSvgText.style['fill'] = data.textColor; - //$(data.container + ' > svg > text').css({'fill': data.textColor}); - } else { - elementSvgText.style['fill'] = data.color; - //$(data.container + ' > svg > text').css({'fill': data.color}); - } - - - - self.css({style: data.style}, {container: data.container + ' > svg'}); - } - - } - - this.svg = function (params, selectorParams, args) { - var paramsReplaced = self.replaceProperties(params, args); - - //var container = self.selector(self.extend({}, params, selectorParams)); - - var container = self.selector(paramsReplaced, undefined, true) || self.selector(selectorParams, undefined, true); - - var element = self.query(container); - var color = paramsReplaced.color || getComputedStyle(element).color; - //if (element.getElementsByTagName('SVG').length == 0) { - //if (element.querySelectorAll('svg').length == 0) { - - self.svgImage({ - container: container, - - // special param - icon: paramsReplaced.icon, - text: paramsReplaced.text, - textSize: paramsReplaced.textSize, // verify (obsolete when span will be nested) - textPosition: paramsReplaced.textPosition, // verify (obsolete when span will be nested) - textColor: paramsReplaced.textColor, // verify (obsolete when span will be nested) - background: paramsReplaced.background, - border: paramsReplaced.border, - color: paramsReplaced.color || color, // $(container).css("color"), - style: paramsReplaced.style, // da fare css in svgImage - class: paramsReplaced.class - //hoverBackground: data.hoverBackground, // verify - //hoverBorder: data.hoverBorder, // verify - //hoverColor: data.hoverColor, // verify - }); - - } */ - // -------------- - // ITEM - // -------------- - /* - this.checkItem = function (data) { - - var selectedIconClass = data.selection || 'selectedIcon'; // self.json.setup.classes.selectedIcon; - - //self.log('checkItem'); - //self.log(data); - var checked = 0; - // var selector = ''; - var selector = self.selector(data); - - if (data.style === undefined) {data.style = selectedIconClass;} - if (data.checked !== undefined) { - checked = self.replaceProperties(data.checked); - //checked = self.replaceTags({text:data.checked}); - checked = data.checked; - if (data.checked) { - $(selector).addClass(data.style); - } else { - $(selector).removeClass(data.style); - } - } else { - checked = $(selector).hasClass( data.style ); - } - return checked; - } */ - /* - this.toggleItem = function (data) { // modificato 20180709 da changeCheckItem in toggleItem - self.log('toggleItem'); - //self.log(data); - var checked; - checked = self.checkItem({ - id: data.id, - class: data.class, - value: data.value - //style: data.style - }); - checked = !checked; // inverte il valore - self.checkItem({ - id: data.id, - class: data.class, - value: data.value, - checked: checked - //style: data.style, - }); - return checked; - } - */ - /* this.selectItem = function (data) { - - var selectedIconClass = self.json.setup.classes.selectedIcon; - - - var selector = self.selector({container: data.container, class: data.class}); - if (data.style === undefined) {data.style = selectedIconClass;} - $(selector).removeClass(data.style); - - self.log('selector'); - self.log(selector); - - - if (data.value || data.id) { - selector = self.selector(data); - - $(selector).addClass(data.style); - } - - } - - this.unselectItems = function (data) { - var selectedIconClass = self.json.setup.classes.selectedIcon; - //if (data.style) - if (data.style === undefined) {data.style = selectedIconClass;} - if (data.class.indexOf('.') < 0) {data.class = '.' + data.class} - $(data.class).removeClass(data.style); - } - */ - /* this.removeImage = function (data) { - var selector = self.selector(data); - $(selector).css({'background-image':'url()'}); - } - - this.loadImage = function (data) { - var selector = self.selector(data); - //if (!data.style) data.style = {}; - //if (data.background) data.style['background-color'] = data.background; - if (data.image || data.image === '') { - self.getImage({ // ex fixo.loadImage - object: selector, - url: data.image - //style: data.style, - //animation: data.animation, - }); - } else { - self.removeImage(data); - } - } */ - /* this.changeItem = function (data, selectorParams, args) { - self.log('changeItem'); - self.log(data); - var container = (selectorParams) ? self.selector(selectorParams) : data.container; - var selector = self.selector(self.extend({}, data, selectorParams)); - - var iconClass = ''; //self.json.setup.classes.icon || ''; - var badgeClass = 'iconBadge'; //self.json.setup.classes.badge || ''; - - if (data.svg || data.text || data.background || data.border || data.color) { - $(selector + ' > svg').css({opacity:1}); - self.svgChange({ - container: selector, - name: data.svg, - text: data.text, - background: data.background, - border: data.border, - color: data.color, - }); - } else { - $(selector + ' > svg').css({opacity:0}); - } - - // IMMAGINE - if (data.image && data.image !== '') { - var imgData = data; - imgData.style = { - width: '82px', - height: '82px', - 'margin-bottom': '27px' - }; - if (data.background) imgData.style['background-color'] = data.background; - self.loadImage(imgData); - $(selector + ' > svg').css({opacity:0}); - } else { - self.removeImage(data); - $(selector + ' > svg').css({opacity:1}); - } - - if (data.badgeIcon || data.badgeText) { - if (!$('.'+badgeClass).length) - $(selector).append('
      '); - self.svgImage({ - container: selector + ' > .'+badgeClass, - icon: data.badgeIcon, - text: data.badgeText, - background: data.badgeBackground, - border: data.badgeBorder, - color: data.badgeColor, - }); - } else { - $(selector + ' > .'+badgeClass).remove(); - } - - - if (data.titleColor) - $(selector + ' > span').css({'color':data.titleColor}); - else if (data.color) - $(selector + ' > span').css({'color':data.color}); - - if (data.titleSize) $(selector + ' > span').css({'font-size':data.titleSize}); - if (data.title) { - $(selector+' > span').text(data.title); - if ($(selector+' > span').hasClass('textFitted')) { - self.textFit($(selector+' > span'), { - alignHoriz: false, - multiLine: false, - alignVert: false, - minFontSize: 10, - maxFontSize: data.titleSize || 12, - }); - } - } - - if (data.checked !== undefined) { - self.checkItem({ - container: data.container, - class: data.class, - value: data.value, - id: data.id, - checked: data.checked - //style: data.style, - }); - } - - // action (obsolete) - if (data.action) { - var onData = $(selector).data('onData'); - onData.action = data.action; - $(selector).data('onData', onData); // nuova versione - } - // events - if (data.on) self.on(data.on, {container: selector}); - - } */ - /* this.enableIcon = function (params, selectorParams) { - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - $(selector).css({'opacity':'1'}); - $(selector).off().on(self.touch, function(event){ - event.stopPropagation(); - self.onEvent(this, event); - }); - } - - this.disableIcon = function (params, selectorParams) { - var badgeClass = self.json.setup.classes.badge || ''; - - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - $(selector + ' > .'+badgeClass).remove(); - $(selector).css({'opacity':'0.5'}); - $(selector).off(); - } - */ - /* this.getFileExtension = function (path) { - var dotPosition=path.lastIndexOf("."); - var stringLength=path.length; - var extensionFile=path.substring(dotPosition+1,stringLength); - return extensionFile; - } */ - // -------------------- - // SLIDER - // -------------------- - /* var slides = {}; - - var sliderLib = 'fixoSlider'; - var sliderWrapperClass = 'fixoSlider'; - //var sliderSlideClass = 'fixoSlidez'; - var sliderSelectedClass = 'slideSelected'; */ - /* - var sliderLib = 'flickity'; - var sliderWrapperClass = 'fixoSlider'; - var sliderSlideClass = 'fixoSlide'; - var sliderSelectedClass = 'is-selected'; - */ - /* - var sliderLib = 'sliderpro'; - var sliderWrapperClass = 'sp-slides'; - var sliderSlideClass = 'sp-slide'; - var sliderSelectedClass = 'sp-selected'; - */ - /* - var sliderLib = 'swiper'; - var sliderWrapperClass = 'swiper-wrapper'; - var sliderSlideClass = 'swiper-slide'; - var sliderSelectedClass = 'swiper-slide-active'; - */ - /* - this.sliderResume = function (data) { - var selector = self.selector(data); - if (slides[selector]) slides[selector].object.resume(); - } - - this.sliderFreeze = function (data) { - var selector = self.selector(data); - if (slides[selector]) slides[selector].object.freeze(); - } - - this.sliderNext = function(data) { - var selector = self.selector(data); - if (sliderLib == 'fixoSlider') slides[selector].object.next(); - //if (sliderLib == 'flickity') slides[selector].object.flickity('next'); - } - - this.sliderPrev = function(data) { - var selector = self.selector(data); - if (sliderLib == 'fixoSlider') slides[selector].object.prev(); - //if (sliderLib == 'flickity') slides[selector].object.flickity('previous'); - } - - this.autoSliderEvent = function() { - var selector = self.selector(data); - if (self.sliderSelected) - slides[self.sliderSelected].object.autoSliderEvent(); - } - - this.addSlideIcon = function(data) { - // creata per rendere più leggibile createSlide - var selector = self.selector(data); - var isImage = self.getFileExtension(data.icon); - if (isImage == 'gif' || isImage == 'jpg' || isImage == 'jpeg' || isImage == 'png') - fixo.loadImage({ - object: selector + ' > .slideIcon', - url: data.icon, - style: {height: '150px', - width: '150px', - marginTop: '25px', - marginLeft: '-75px', - backgroundSize: 'cover' - } - }); - else - //if (data.icon) - self.svgImage({ - container: selector + ' > .slideIcon', - icon: data.icon, - color: '#fff', - }); - if (data.iconName) - $(selector + ' > .slideIconName').html(data.iconName); // da cancellare? - if (data.iconAction) { - var value = data.iconValue || ''; - $(selector + ' > .slideIcon').attr('onclick', 'javascript:self.do(\''+data.iconAction+'\', \''+value+'\')'); - } - } - - this.changeSlideIcon = function(data) { - var selector = self.selector(data); - // verificare se si può usare changeItem - if (data.icon) - self.svgChange({ - container: selector + ' > .slideIcon', - name: data.icon, - color: '#fff', - }); - if (data.iconName) - $(selector + ' > .slideIconName').html(data.iconName); - } - - this.updateSlide = function(data) { - self.log('updateSlide'); - if (!data.class) data.class = 'fixoSlide'; - var selector = self.selector(data); - // ICONA - self.changeSlideIcon(data); - // BACKGROUND - if (data.background) $(selector).css({'background-color':data.background}); - // TITOLO E TESTO - var alertTitleObj = $(selector).children('.slideTitle'); - var alertTextObj = $(selector).children('.slideText'); - var titleAndText = (alertTitleObj.text() !== '' && alertTextObj.text() !== ''); - if (titleAndText) { - alertTitleObj.css({'margin-top':'-225px'}); - } else { - alertTitleObj.css({'margin-top':'-60px'}); - } - if (data.title !== undefined) { - alertTitleObj.html(data.title); - self.textFit(titleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 40, maxFontSize: 56}); - } - if (data.text !== undefined) { - alertTextObj.html(data.text); - self.textFit(textObj, {alignHoriz: true, multiLine: false, alignVert: !titleAndText, minFontSize: 17, maxFontSize: 40}); - } - // BOTTONE - if (data.button !== undefined) { - if (data.button) { - if (data.buttonLabel) { - $(selector + ' > .slideButton').html(data.buttonLabel); - } - if (data.buttonAction) { - $(selector + ' > .slideButton').data('action', data.buttonAction); - $(selector + ' > .slideButton').data('value', data.value); - $(selector + ' > .slideButton').attr('onclick', 'javascript:self.do(\'' + data.buttonAction + '\',\''+data.value+'\')'); - } - $(selector + ' > .slideButton').show(); - } else { - $(selector + ' > .slideButton').hide(); - } - // aggiungere changeItem dell'icona - } - } - - this.slideTextFit = function() { - //self.log('slideTextFit'); - - //if (!data.class) data.class = 'fixoSlide'; - //var selector = self.selector(data); - var slideSelector = self.sliderSelected + ' > .' + sliderSelectedClass; - - titleObj = $(slideSelector).children('.slideTitle'); - textObj = $(slideSelector).children('.slideText'); - - var titleAndText = (titleObj.text() !== '' && textObj.text() !== ''); - if (titleAndText) { - titleObj.css({'margin-top':'-225px'}); - //textObj.css({'top':(384+125-30)+'px'}); - } else { - titleObj.css({'margin-top':'-60px'}); - } - self.textFit(titleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 40, maxFontSize: 56}); - - self.textFit(textObj, {alignHoriz: true, multiLine: false, alignVert: !titleAndText, minFontSize: 17, maxFontSize: 40}); - - } - - this.sliderTo = function(data) { - // apre la slide data.index - self.log('sliderTo'); - var selector = self.selector(data); - if (data.index !== undefined) // comprende il caso = 0 - if (slides[selector] && slides[selector].object) - slides[selector].object.to(data.index); - - //if (sliderLib == 'swiper') - // slides[selector].object.slideToLoop(data.index); // slideToLoop - //if (sliderLib == 'flickity') - // slides[selector].object.flickity('select', data.index); - //if (sliderLib == 'extraslider') - // $(selector+' > .extra-slider').trigger('extra:slider:goto', data.index); - - if (data.value !== undefined) { // comprende il caso = 0 - self.log(self.selector(data)); - if (!data.class) data.class = 'fixoSlide'; - var slideToSelect = self.selector(data); - var index = $(slideToSelect).index(); - if (index > -1) slides[selector].object.to(index); - //var slideToSelect = '.' + sliderSlideClass + '[data-value="' + data.prefix + data.value + '"]'; - } - - //if (sliderLib == 'flickity') - // slides[selector].object.flickity('selectCell', slideToSelect); - } - - this.sliderExist = function(data) { // si può cancellare? - var selector = self.selector(data); - //alert(($(selector + ' > .extra-slider').length > 0)); - return ($(selector + ' > .extra-slider').length > 0) - // return (slides[selector]) - } - - this.createSlide = function(data) { - self.log('createSlide'); - //if (!data.prefix) data.prefix = ""; - if (!data.class) data.class = "fixoSlide"; - //var containerSelector = self.selector(data); - var slideContent = '
      '; - - if (data.inverse) { - $(data.container).prepend(slideContent); - } else { - $(data.container).append(slideContent); - } - var selector = self.selector(data); - var infoButtons = data.infoButtons || {}; - - // STORE DATA - $(selector).data('container', data.container); - if (data.value) $(selector).data('value', data.value); - //if (data.id) $(selector).data('id', data.id); - //if (data.prefix) $(selector).data('prefix', data.prefix); - - var textHtml = (data.text) ? data.text.replace(/\r?\n/g, '
      ') : ''; - - // PRICE - //if(data.price && data.price !== '') textHtml += '
      € '+data.price; - - // BACKGROUND - if (data.background) $(selector).css({'background-color':data.background}); - - // IMAGE - if (data.image && data.image !== '') { - if (data.title !== '' || textHtml !== '' ) - { - //$(selector).css({'background-image':'linear-gradient(to right,rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('+data.image+')'}); - //} else { - //$(selector).css({'background-image':'url('+data.image+')'}); - $(selector).append('
      ') - } - - if (sliderLib == 'fixoSlider') { - $(selector).css({'background-image':'url('+data.image+')'}); - // DA GESTIRE INTERNAMENTE A fixo.slider.js - // DOVRA' CARICARE SOLO SLIDE ATTUALE, PREC. E SUCC - - //fixo.loadImage({ - // object: selector, - // url: data.image, - // animation: 'fadeIn', - //}); - - } - - //if (sliderLib == 'swiper') { - // $(selector).addClass('swiper-lazy'); - // $(selector).attr('data-background', data.image); - //} - //if (sliderLib == 'flickity') { - // $(selector).attr('data-flickity-bg-lazyload', data.image); - //} - - } else { - - $(selector).css({'background-image':'none'}); - // SERVICE ICON - //$(selector).append('
      '); - //self.addSlideIcon(data); - - // if (data.icon) - // self.svgImage({ - // container: selector + ' > .slideIcon', - // icon: data.icon, - // color: '#fff', - // }); - // if (data.iconName) - // $(selector + ' > .slideIconName').html(data.iconName); - - // if (data.icon) - // self.svgImage({ - // container: selector + ' > .slideIcon', - // icon: data.icon, - // color: '#fff', - // }); - // if (data.iconName) - // $(selector + ' > .slideIconName').html(data.iconName); - } - - // ICONA - $(selector).append('
      '); - self.addSlideIcon(data); - - // TITLE & TEXT - $(selector).append('
      '); - - var alertTitleObj = $(selector + ' > .slideTitle'); - var alertTextObj = $(selector + ' > .slideText'); - var alertInfoObj = $(selector + ' > .slideInfo'); - - // BOTTONI INFO - - var btnInfo = ''; - for (var i in infoButtons) { - if (infoButtons[i].icon !== '') - btnInfo += self.imgTag({ - icon: infoButtons[i].icon, - action: infoButtons[i].action, - class: infoButtons[i].class, - value: infoButtons[i].value, - //style: 'width: 84px; margin:6px 10px;' - }); - //alertInfoObj.html(btnInfo); - } - alertInfoObj.html(btnInfo); - - // TESTO - - if (data.title && data.title !== '') { - alertTitleObj.html(data.title); - } else { - alertTitleObj.html(data.iconName); - } - alertTextObj.html(textHtml); - - //alertInfoObj.html() - - - // if (data.link && data.link !== '') { // serviva a costruire il div con il qrcode, sostituito dal link per aprire lo swal alert - // var link = data.link; - - // self.log('DATALINK: '+link); - - // if (link.indexOf('musement.com') || link.indexOf('booking.com')) { - // link = link.replace(/^https?:\/\//,''); //rimuovo https dal link - // self.log('link: '+link); - // link = 'https://c83.travelpayouts.com/click?shmarker=219111&promo_id=2015&source_type=customlink&type=click&custom_url=' + link; - // } - - // self.log('DATALINK1: '+link); - - // $(selector).append('
      '); - // self.qrCode({ - // container: selector, - // class: 'slideQrCode', - // text: link, - // size: 100 - // }); - // // attributo sul Codice QR per la visualizzazione dell'alert - // $('.slideQrCode > img').attr('onclick','javascript:self.do(\'app.hot.alertQRCode\')'); - // } else { - - - $(selector).append(''); - if (data.button) { - if (data.buttonLabel) { - $(selector + ' > .slideButton').html(data.buttonLabel); - } - if (data.buttonAction) { - $(selector + ' > .slideButton').data('action', data.buttonAction); - $(selector + ' > .slideButton').data('value', data.value); - $(selector + ' > .slideButton').attr('onclick', 'javascript:self.do(\'' + data.buttonAction + '\',\''+data.value+'\')'); - } - $(selector + ' > .slideButton').show(); - - // $(selector + ' > .slideButton').off().on(self.touch, function(){ - // var action = $(this).data('action'); - // var key = $(this).data('value'); - // self.do(action, value); - // }); - - } else { - $(selector + ' > .slideButton').hide(); - } - //} chiude l'IF del data.link - var titleAndText = (alertTitleObj.text() !== '' && alertTextObj.text() !== ''); - - // POSIZIONE TITOLO - var titleTop = -70 -170 * (titleAndText); - alertTitleObj.css({'margin-top': titleTop + 'px'}); - self.textFit(alertTitleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 30, maxFontSize: 56}); - - // ALTEZZA TESTO - var textHeight = 340 - 100 * (infoButtons.length > 0); - alertTextObj.css({'height': textHeight + 'px'}); - - - //self.textFit(alertTitleObj, {alignHoriz: true, multiLine: false, alignVert: true, minFontSize: 30, maxFontSize: 56}); - - //self.textFit(alertTextObj, {alignHoriz: true, multiLine: false, alignVert: !titleAndText, minFontSize: 15, maxFontSize: 45}); - //self.log('END createSLIDE'); - - - } - - this.createSlider = function (data) { - self.log('createSlider'); - //if (!data.prefix) data.prefix = ""; - var selector = self.selector(data); - var startIndex = data.index || 0; - //self.log('pre DATAINDEX: '+data.index); - - // RIMUOVE ISTANZA PRECEDENTE - - if (slides[selector] && slides[selector].object) { - // Memorizza posizione - var slideSelector = selector + ' > .' + sliderSelectedClass; - //self.log('slideSelector di self.createSlider: '+slideSelector); - startIndex = data.index || $(slideSelector).index(); - // Rimuove slider precedente - //self.log('startIndex: di '+data.index+' .index() '+$(slideSelector).index()); - $(selector).empty(); - delete slides[selector].object; - } - - slides[selector] = {}; - - - // FRECCE - // if (data.buttons) { - // if (sliderLib == 'swiper') { - // $(selector).append('
      '); - // $(selector).append('
      '); - // } - // } - - for (var key in data.slides) { - var slide = data.slides[key]; - slide.inverse = data.inverse; - //slide.container = selector; //+' > .' + sliderWrapperClass; - slide = self.extend({ - container: selector, - class: 'fixoSlide', //sliderSlideClass, - value: data.value, //data.prefix + data.value - }, slide); - self.createSlide(slide); - - } - - // CREAZIONE OGGETTO SLIDER - - if (sliderLib == 'fixoSlider') { - - var params = { - container: selector, //+' > .' + sliderWrapperClass, - play: data.play, - interval: data.interval, // ms - onChange: data.onChange, - onChangeStart: self.slideTextFit, - index: startIndex // prima slide - // direction: 1, // from right to left - // opts.swipeDuration: 0.6, // sec - // opts.swipeTreshold: 0.2, // Swipe from +/-20% - }; - - slides[selector].object = $.fn.slide(params); - } - //self.log('END createSlider'); - } -*/ - /* - this.getSelectedSlide = function (data) { - self.log('getSelectedSlide'); - //self.log(data); - var selector = self.selector(data); - if (sliderLib == 'fixoSlider') { - var slideSelector = selector + ' > .' + sliderSelectedClass; - - self.log($(slideSelector).data('value')); - return $(slideSelector).data('value'); - } - - } - - var sliderSelect = function (currentItem, currentIndex) { //si può cancellare? - var id = $(currentItem).parent().parent().parent().attr('id'); - self.log('slideId:'+id); - self.log('currentItem:'+currentItem); - self.log('currentIndex:'+currentIndex); - slides[id].currentItem = currentItem; - slides[id].currentIndex = currentIndex; - } - - var sliderPause = function (currentItem, currentIndex) { // si può cancellare? - $(currentItem).parent().parent().trigger('extra:slider:pause'); - var id = $(currentItem).parent().parent().parent().attr('id'); - self.log('slideId:'+id); - self.log('currentItem:'+currentItem); - self.log('currentIndex:'+currentIndex); - slides[id].currentItem = currentItem; - slides[id].currentIndex = currentIndex; - } - - var sliderPlay = function (currentItem, currentIndex) { // si può cancellare? - $(currentItem).parent().parent().trigger('extra:slider:pause'); - $(currentItem).parent().parent().trigger('extra:slider:resume'); - var id = $(currentItem).parent().parent().parent().attr('id'); - self.log('slideId:'+id); - self.log('currentItem:'+currentItem); - self.log('currentIndex:'+currentIndex); - slides[id].currentItem = currentItem; - slides[id].currentIndex = currentIndex; - } - - var sliderResume = function (currentItem, currentIndex) { //si può cancellare? - var id = $(currentItem).parent().parent().parent().attr('id'); - if (slides[id].active) { - sliderPlay(currentItem, currentIndex); - } else { - sliderPause(currentItem, currentIndex); - } - } - - var sliderClick = function (currentItem, currentIndex) { // si può cancellare ? - var id = $(currentItem).parent().parent().parent().attr('id'); - if (slides[id].active) { - slides[id].active = false; - } else { - slides[id].active = true; - } - } */ - /* this.addItem = function (data, selectorParams) { // obsolete - - var container = (selectorParams) ? self.selector(selectorParams) : data.container; - var selector = self.selector(self.extend({}, data, selectorParams)); - - // app default - // aggiungere anche dimensione di default - - var iconClass = self.json.setup.classes.icon || ''; - var badgeClass = self.json.setup.classes.badge || ''; - - var style = (data.style) ? data.style : {}; - - // retro-compatibility - if (data.size) { - if (data.size == 'small') - style.width = '50px'; - else if (data.size == 'medium') - style.width = '80px'; - else if (data.size == 'big') - style.width = '120px'; - else if (data.size) - style.width = data.size; - } - - style = self.extend({}, style, { // retrocompatibilità / obsoleto - color: data.color, - background: data.background, - border: data.border, - display: data.display, - margin: data.margin, - padding: data.padding, - width: data.width, - height: data.height - }); - - - // Create - if (data.id === undefined) {data.id = '';} - if (data.value === undefined) {data.value = data.id}; - if (data.class === undefined) {data.class = iconClass} else if (data.class !== iconClass) {data.class += ' ' + iconClass}; - - var itemDiv = '
      '; - - if (data.prepend) { - $(data.container).prepend(itemDiv); - } else { - $(data.container).append(itemDiv); - } - - self.css({style: { - width: style.width, - display: style.display, - padding: style.padding, - margin: style.margin - }}, {container: selector}); - - // SVG - - if (data.svg || data.text) { - self.svgImage({ - container: selector, - icon: data.svg, - text: data.text, - textSize: data.textSize, // verify (obsolete when span will be nested) - textPosition: data.textPosition, // verify (obsolete when span will be nested) - textColor: data.textColor, // verify (obsolete when span will be nested) - background: style.background, - border: style.border, - color: style.color - //hoverBackground: data.hoverBackground, // verify - //hoverBorder: data.hoverBorder, // verify - //hoverColor: data.hoverColor, // verify - }); - } else { - - } - - // image - - if (data.image) { - var imgData = data; - imgData.style = { - width:'82px', - height:'82px', - 'margin-bottom':'27px' - }; - if (style.background) imgData.style['background-color'] = style.background; - self.loadImage(imgData); - } - - // badge - - if (data.badgeIcon || data.badgeText) { - $(selector).append('
      '); - self.svgImage({ - container: selector + ' > .'+badgeClass, - icon: data.badgeIcon, - text: data.badgeText, - background: data.badgeBackground, - border: data.badgeBorder, - color: data.badgeColor, - }); - } - - - if (data.title) { - //data.title = self.text(data.title); - data.titleColor = data.titleColor || style.color; - if (data.titleColor == undefined) {data.titleColor = ''} - if (data.titleSize == undefined) {data.titleSize = ''} - //if (data.titleSizeMin == undefined) {data.titleSize = '7px'} - - $(selector).append(''); - $(selector + ' > span').css({ - color: data.titleColor, - 'font-size': data.titleSize - }); - //if (typeof data.title == 'object') alert(data.title.text); - self.text(data.title, {container: selector + ' > span'}); - //var title = self.text(data.title); - //$(selector + ' > span').text(title); - - //self.text(data.title); - - // itemSelectedBorderWhite GESTITO IN INDEX.CSS - - // questo stile dovrebbe essere fisso e con posizione assoluta - if (data.image) - $(selector + ' > span').css({ - 'margin-top':'89px', - position: 'absolute' - }); - - - if (data.textFit !== false) { - self.textFit($(selector+' > span'), { - alignHoriz: false, - multiLine: false, - alignVert: false, - minFontSize: 10, - maxFontSize: data.titleSize, - }); - } - } - - // action (obsolete) - if (data.action || data.functions) { - var.functions[selector] = data.functions || data.action; // obsoleto - $(selector).data('onData', data); // nuova versione - $(selector).off().on(self.touch, function(event){ - event.stopPropagation(); - self.onEvent(this, event); - }); - } - - // matchMedia - if (data.matchMedia) { - for (var mediaEvent in data.matchMedia) { - self.matchMedia(data.matchMedia[mediaEvent], mediaEvent); - } - } - - // events - if (data.on) self.on(data.on, {container: selector}); - - if (data.checked !== undefined) { - self.checkItem({ - container: data.container, - class: data.class, - value: data.value, - id: data.id, - checked: data.checked - //style: data.style, - }); - } - } */ - // -------------- - // TABS - // -------------- - /* this.addTab = function (data, selectorParams) { - //self.log('addTab'); - //self.log(data); - - var containerParams = self.cloneObject(selectorParams); - - data.container = containerParams.container; - var selector = self.selector(data); - - var tabClass = ''; //self.json.setup.classes.button || ''; - var badgeClass = 'iconBadge'; //self.json.setup.classes.badge || ''; - - var style = (data.style) ? data.style : {}; - - // span height - //style["line-height"] = (style.height) ? style.height : '42px'; - - style = self.extend({}, style, { - color: data.color, - background: data.background, - border: data.border, - display: data.display, - margin: data.margin, - padding: data.padding, - width: data.width, - height: data.height - }); - - if (data.id === undefined) {data.id = '';} - if (data.value === undefined) {data.value = data.id}; - if (data.class === undefined) {data.class = tabClass} else if (data.class !== tabClass) {data.class += ' ' + tabClass}; - - var tabDiv = '
      '; - - $(data.container).append(tabDiv); - - self.css({style: style}, {container: selector}); - - //if (data.key) {$(selector).data('key', data.key);} - - //var iconColor = style.color || $(selector).css("color"); - - // ICON - if (data.icon) { - self.addItem({ - class: 'icon', - value: data.value, - svg: data.icon, - image: data.image, - style: { - color: style.color || $(selector).css("color"), - width: style.height - } - }, {container: selector}); - } - - // TEXT - if (data.text !== undefined) { - //alert(JSON.stringify(data.text)); - - $(selector).append(''); - - self.text(data.text, {container: selector + ' > span'}); - - - } else { - //alert(JSON.stringify(data.text)); - } - - if (data.icon) $(selector + ' > span').css({'padding-left': '0px'}); - - // SPAN - if(style.color) $(selector + ' > span').css({'color':style.color}); - - // BADGE - if (data.badgeIcon || data.badgeText) { - if (!$('.'+badgeClass).length) - $(selector).append('
      '); - self.svgImage({ - container: selector + ' > .'+badgeClass, - icon: data.badgeIcon, - text: data.badgeText, - background: data.badgeBackground, - border: data.badgeBorder, - color: data.badgeColor, - }); - } else { - $(selector + ' > .'+badgeClass).remove(); - } - - // data - if (data.action || data.functions){ - var.functions[selector] = data.functions || data.action; // obsoleto - $(selector).data('onData', data); // nuova versione - $(selector).off().on(self.touch, function(event){ - event.stopPropagation(); - self.onEvent(this, event); - //$(this).data('value') - //var selector = $(this).data('selector'); - //var action = var.functions[selector]; - //self.do($(this).data('onData').action, $(this).data('value')); - }); - } - - // matchMedia - if (data.matchMedia) { - for (var mediaEvent in data.matchMedia) { - self.matchMedia(data.matchMedia[mediaEvent], mediaEvent); - } - } - - // events - if (data.on) self.on(data.on, {container: selector}); - - if (data.selected) self.selectTab(data); - - } */ - /* this.changeTab = function (data, selectorParams) { - - var container = (selectorParams) ? self.selector(selectorParams) : data.container; - var selector = self.selector(self.extend({}, data, selectorParams)); - - if (data.icon && data.value) { - self.changeItem({ - container: selector, - class: 'icon', - value: data.value, - svg: data.icon, - color: data.color, - background: data.background - }); - } - - if(data.background) $(selector).css({'background':data.background}); - if(data.color) $(selector + ' > span').css({'color':data.color}); - - if (data.text) { - //$(selector + ' > span').text(self.text(data.text)); - self.text(data.text, {container: selector + ' > span'}); - } - - if (data.action){ - $(selector).off().on(self.touch, function(){ - data.action(data.value) - }); - } - // events - if (data.on) self.on(data.on, {container: selector}); - - if (data.selected) self.selectTab(data); - } */ - /* this.unselectTabs = function (data) { - - var selectionClass = data.selection || 'selectedButton'; - //var selectionClass = self.json.setup.classes.selectedButton; - if (data.style) selectionClass = data.style; - $(data.class).removeClass(selectionClass); - } - - this.toggleTab = function (data) { - data.toggle = true; - return self.selectTab(data); - } - - this.selectTab = function (data) { - var selectionClass = data.selection || 'selectedButton'; - //var selectionClass = self.json.setup.classes.selectedButton; - if (data.style) selectionClass = data.style; - var selector = self.selector(data); - - if (data.deselectClass) - if (data.class) $('.'+data.class).removeClass(selectionClass); - - if (data.checked !== undefined) { - if (data.checked == false) $(selector).removeClass(selectionClass); - else $(selector).addClass(selectionClass); - } else if (data.toggle !== undefined) { - // da toggleTab - if ($(selector).hasClass(selectionClass)) { - $(selector).removeClass(selectionClass); - return false; - } else { - //if (data.class) $('.'+data.class).removeClass(selectionClass); - $(selector).addClass(selectionClass); - return true; - } - } else { - //if (data.class) $('.'+data.class).removeClass(selectionClass); - $(selector).addClass(selectionClass); - } - } */ - // --------------------------- - // FUNZIONI DATEPICKER - // --------------------------- - /* - // basato su: http://www.daterangepicker.com/#options - - this.createDatePicker = function (data) { - self.log('createDatePicker'); - var calendarVisible = false; - if (!data.field) data.field = data.container + ' > .daterange'; - - if (!$(data.field).length) { - calendarVisible = true; // Crea e nasconde campo testo e mostra calendario - $(data.container).html(''); - } - - var weekD = self.weekdaysShort(1, capitalize); - weekD = weekD.unshift(weekD[6]); - var monthsOfYear = ["January","February","March","April","May","June","July","August","September","October","November","December"]; - if (data.language) { - monthsOfYear = moment.localeData(data.language).months(); - for (var index in monthsOfYear) { - monthsOfYear[index] = - monthsOfYear[index].substr(0,1).toUpperCase() - + monthsOfYear[index].substr(1); - } - } - //var datarange = $('#daterange'); - - $(data.field).daterangepicker({ - singleDatePicker: data.single, - parentEl: data.container, - startDate: data.start, - endDate: data.end, - autoApply: true, - autoUpdateInput: false, - locale: { - format: 'DD/MM/YYYY', - daysOfWeek: weekD, - monthNames: monthsOfYear, - firstDay: 1 // monday - } - }); - - - $(data.field).on('cancel.daterangepicker', function(ev, picker) { - data.onCancel(); - }); - - $(data.field).on('apply.daterangepicker', function(ev, picker) { - data.onChange({ - start: picker.startDate.format('YYYYMMDD'), - end: picker.endDate.format('YYYYMMDD') - }); - if (picker.startDate && picker.endDate && picker.startDate !== picker.endDate) { - $(data.field).val(picker.startDate.format('DD/MM/YYYY') + '-' + picker.endDate.format('DD/MM/YYYY')); - } else { - $(data.field).val(picker.startDate.format('DD/MM/YYYY')); - } - }); - - self.unselectDatePicker({container: data.container}); - - - } - - var disableDates = []; - this.updateDatePicker = function(data) { - var datePicker = $(data.container + ' > .daterange').data('daterangepicker'); - if (data.disableDates) {disableDates = data.disableDates;} - // alert(datePicker+'-'+data.container); - datePicker.isInvalidDate = function(date) { - return (disableDates.indexOf(date.format('YYYYMMDD')) >= 0) - } - datePicker.updateView(); - if (data.start && data.end) { - self.setDatePicker({ - container: data.container, - start: data.start, - end: data.end, - }); - } else { - self.unselectDatePicker({container: data.container}); - } - } - - this.unselectDatePicker = function(data) { - $(data.container).find('.start-date').removeClass('start-date active'); - $(data.container).find('.end-date').removeClass('end-date active'); - $(data.container).find('.in-range').removeClass('in-range'); - - } - - this.setDatePicker = function (data) { - var datePicker = $(data.container + ' > .daterange').data('daterangepicker'); - datePicker.setStartDate(data.start); - datePicker.setEndDate(data.end); - datePicker.updateView(); - } - - this.getDatePicker = function (data) { - var start = $(data.container + ' > .daterange').data('daterangepicker').startDate(data.start); - var end = $(data.container + ' > .daterange').data('daterangepicker').endDate(data.end); - //alert('ok: '+data.container); - return {start: start, end: end} - } - - // --------------------------- - // FUNZIONI TIMEPICKER - // --------------------------- - - this.createTimePicker = function (data) { - $(data.container).html('
      '); - - $(data.container + ' > .datetimepicker').datetimepicker({ - icons: { - up: "fixoNavUp", - down: "fixoNavDown", - previous: "fixoNavBackward", - next: "fixoNavForward" - }, - inline: true, - sideBySide: true, - //locale: 'it' - locale: { - format: 'DD/MM/YYYY', - daysOfWeek: weekD, - monthNames: monthsOfYear, - firstDay: 1 // monday - } - }); - - //self.log('now: '+Date.now()+' moment: '+moment()); - - self.setTimePicker({ - container: data.container, - time: data.time - }); - - - $(data.container + ' > .datetimepicker').off().on('dp.change', function(event) { - var datePicked = moment(event.date).unix(); - //alert(datePicked); - data.onChange(datePicked); - }); - - } - - this.setTimePicker = function (data) { - //self.log('>>> setTimePicker --> data container: '+data.container+' data time: '+data.time+' moment: '+moment.unix(data.time).calendar()); - $(data.container + ' > .datetimepicker').data('DateTimePicker').date(moment.unix(data.time));//.format('LLL')); - } - - this.getTimePicker = function (data) { - //alert('ok: '+data.container); - $(data.container + ' > .datetimepicker').data('DateTimePicker').date(); - } - */ - // --------------------------- - // TIME SLIDER - // --------------------------- - /* - this.createTimeSlider = function(data){ - var container = data.container; - var id = data.id; - - // c'è un'anomalia nella libreria bootstrap-slider - // crea il contenitore dello slider con lo stesso id del campo input - // va verificata la possibilità di configurazione della funzione .slider - - $('#'+data.container).append(''); - $('#'+id).slider(); - $('#'+id).off().on("slide slideStop", function(event) { - - self.log(event); - self.changeItem({ - id:'stepbackwardSlider'+id, - text: self.numberToHour({value: event.value[0], max: 48}) - }); - self.changeItem({ - id:'stepforwardSlider'+id, - text: self.numberToHour({value: event.value[1], max: 48}) - }); - - if (data.onChange) { - data.onChange({ - start: self.numberToHour({value: event.value[0], max: 48}), - end: self.numberToHour({value: event.value[1], max: 48}) - }) - } - - }); - - // ICONS Slider - self.addItem({ - container:'#'+id+' > .min-slider-handle', - class: 'sliderIconLeft', - id: 'stepbackwardSlider'+id, - background: '#fff', - color: 'black', - border: 1, - text: '00:00' - }); - self.addItem({ - container:'#'+id+' > .max-slider-handle', - class: 'sliderIconRight', - id: 'stepforwardSlider'+id, - background: '#fff', - color: 'black', - border: 1, - text: '24:00' - }); - //$('#'+sliderId+' .slider-selection').css({'background': '#fff'}); - - } - - this.setTimeSlider = function(data){ - //Change value on slider left/right icon - self.changeItem({ - id:'stepbackwardSlider'+data.id, - text: data.start - }); - self.changeItem({ - id:'stepforwardSlider'+data.id, - text: data.end - }); - //Convert value in 0-48 format - var start = self.hourToNumber({value: data.start, max: 48}); - var end = self.hourToNumber({value: data.end, max: 48}); - // Set value on slider - $('input[id="'+data.id+'"]').slider('setValue',[start,end]); - - } - - this.getTimeSlider = function(data){ - var slideStart = $('input[id="'+data.id+'"]').slider('getValue')[0] || 0; - var slideEnd = $('input[id="'+data.id+'"]').slider('getValue')[1] || 48; - var start = self.numberToHour({value: slideStart, max: 48}); - var end = self.numberToHour({value: slideEnd, max: 48}); - if (start == '24:00') {start = '00:00'} - var timetable = { - start: start || '00:00', - end: end || '24:00' - } - return timetable; - } - */ - this.numberToHour = function (data) { - var fraction = data.value / data.max; - var dayMin = Math.round(24 * 60 * fraction); - var hour = parseInt(dayMin / 60); - var min = dayMin - hour * 60; - var hourString = String(hour < 10 ? '0' : '') + String(hour); - var minString = String(min < 10 ? '0' : '') + String(min); - return hourString + ':' + minString; - }; - - this.hourToNumber = function (data) { - var timeArr = data.value.split(':'); - var dayMin = (60 * Number(timeArr[0])) + Number(timeArr[1]); - var fraction = dayMin / (24 * 60); - return Math.round(fraction * data.max); - }; - - this.pannellum = function (params, selectorParams, args) { - self.log('pannellum'); - var container = params.selector || params.container; - var selector = self.selector(container) || self.selector(selectorParams); - var element = self.query(selector); - pannellum.viewer(element, params); - }; - - this.qrcode = function (params, selectorParams, args) { - self.log('qrcode'); - var container = params.selector || params.container; - var selector = self.selector(container) || self.selector(selectorParams); - var element = self.query(selector); - // var obj = self.compile(data); - self.log(selector); - self.log('element'); - self.log(element); - - var QRCodeOptions = { - text: self.replaceProperties(params.text, args) || 'jsonic.io', - width: params.size || 128, - height: params.size || 128, - useSVG: true, - colorDark: params.colorDark || '#000000', - colorLight: params.colorLight || '#ffffff', - correctLevel: QRCode.CorrectLevel.H - }; - self.log('QRCodeOptions'); - self.log(QRCodeOptions); - - element.textContent = ''; - var qrcode = new QRCode(element, QRCodeOptions); - self.log('qrcode'); - self.log(qrcode); - return qrcode; - //qrcode.clear(); // clear the code. - //qrcode.makeCode(text); // make another code - }; - - /* this.qrcode = function (data) { - self.log('qrcode'); - var selector = self.selector(data); - - var options = { - // render method: 'canvas', 'image' or 'div' - render: 'image', - - // version range somewhere in 1 .. 40 - minVersion: 1, - maxVersion: 40, - - // error correction level: 'L', 'M', 'Q' or 'H' - ecLevel: 'L', - - // offset in pixel if drawn onto existing canvas - left: 0, - top: 0, - - // size in pixel - size: data.size || 200, - - // code color or image element - fill: data.color || '#000', - - // background color or image element, null for transparent background - background: data.background || null, - - // content - text: self.replaceProperties(data.text) || 'no text', - - // corner radius relative to module width: 0.0 .. 0.5 - radius: 0, - - // quiet zone in modules - quiet: 0, - - // modes - // 0: normal - // 1: label strip - // 2: label box - // 3: image strip - // 4: image box - mode: 0, - - mSize: 0.1, - mPosX: 0.5, - mPosY: 0.5, - - label: data.label || 'no label', - fontname: data.fontname || 'sans', - fontcolor: data.fontcolor || '#000', - - image: null - } - $(selector).empty().qrcode(options); - } */ - this.weekdaysShort = function (length, caseFunction) { - if (!caseFunction) caseFunction = caseUp; - var language = 'en'; - var fixoLang = fixo.getFixoLanguage(); - var userLang = fixo.getUserLanguage(); - if (fixo.device) language = fixoLang; else language = userLang; - var weekDays = self.cloneObject(moment.localeData(language).weekdays()); - - weekDays[7] = weekDays[0]; - weekDays.shift(); - - for (var i = 0; i < 7; i++) { - if (length) weekDays[i] = weekDays[i].substr(0, length); - if (caseFunction) weekDays[i] = caseFunction(weekDays[i]); - } - return weekDays; - }; - - - this.weekDaysToString = function (days) { - var text = ''; - for (var i in days) { - if (days[i]) { - if (text !== '') text += '/'; - text += self.weekdaysShort(3, capitalize)[i]; - } - } - return text; - }; - - // ----------- - // DRAG - // ----------- - /* - var draggingData; - - this.sortable = function (data) { - var rootEl = $(data.container)[ 0 ]; - var dragEl; - - draggingData = data; - var selector = self.selector(data); - $(selector).attr('draggable', 'true'); - $(data.exclude).attr('draggable', 'false'); - - // Function responsible for sorting - function onDragOver(event) { - event.preventDefault(); - event.dataTransfer.dropEffect = 'move'; - - var dragTarget = event.target; // target.nextSibling || - if ($(dragTarget).hasClass(draggingData.class)) - $( dragEl ).insertAfter( $(dragTarget) ); - if ($(dragTarget).parent().hasClass(draggingData.class)) - $( dragEl ).insertAfter( $(dragTarget).parent() ); - } - - // End of sorting - function onDragEnd(event){ - event.preventDefault(); - - $(dragEl).css({'opacity':'100%'}); - rootEl.removeEventListener('dragover', onDragOver, false); - rootEl.removeEventListener('dragend', onDragEnd, false); - - // Notification about the end of sorting - draggingData.target = dragEl; - draggingData.onDragEnd(draggingData); - } - - // Sorting starts - rootEl.addEventListener('dragstart', function (event){ - dragEl = event.target; // Remembering an element that will be moved - - $(dragEl).css({'opacity':'50%'}); - - // Limiting the movement type - event.dataTransfer.effectAllowed = 'move'; - event.dataTransfer.setData('Text', dragEl.textContent); - - - // Subscribing to the events at dnd - rootEl.addEventListener('dragover', onDragOver, false); - rootEl.addEventListener('dragend', onDragEnd, false); - - - setTimeout(function () { - // If this action is performed without setTimeout, then - // the moved object will be of this class. - $(dragEl).css({'opacity':'100%'}); - }, 0) - }, false); - } - - */ - /* - this.setWeekDays = function(data){ - - if (!data.days) data.days = {}; - - for (var i=1; i<7; i++){ - self.selectTab({ - container: data.container, - class: 'fixoTabsWeekDays', - value: String(i), - checked: data.days[String(i)] || false - }); - } - } - - this.createWeekDays = function(data){ - //var selector = self.selector(data); - var weekDays = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]; - self.log('data.language '+data.language); - if (data.language) weekDays=moment.localeData(data.language).weekdaysShort(); - for (var i=0; i<7; i++){ - var weekDay = weekDays[i]; - self.addTab({ - container: data.container, - class: data.class, - value: String(i), - id: data.container + i, - background: 'black', - color: 'white', - border: '1px solid rgba(0, 0, 0, 1)', - text: weekDay, - action: function(value){ - //alert($(this).attr(id)); - // il toggleTab deselezionava sempre gli altri giorni - // risolto usando il selectTab col parametro checked - // va sistemato toggleTab - if (!data.days) data.days = {}; - var checked = !Boolean(data.days[value]); - self.selectTab({ - container: data.container, - class: 'fixoTabsWeekDays', - value: value, - checked: checked - }); - data.days[value] = checked; - } - }); - } - } - */ - //-------------------------- - // DA FIXO.JS - //-------------------------- - /*--------------------- - UTILS - ---------------------*/ - var sortField; - - var dynamicSort = function (data) { - var sortOrder = 1; - if (data.reverse) { sortOrder = -1; } - sortField = data.field; - return function (a, b) { - var result = (a[sortField] < b[sortField]) ? -1 : (a[sortField] > b[sortField]) ? 1 : 0; - return result * sortOrder; - }; - }; - - this.sort = function (data) { - // fixo.sort({object:{}, add: {}, field:'time', reverse:true}) - if (data.object !== undefined) { - if (Array.isArray(data.object)) { - return data.object.sort(dynamicSort({ - field: data.field, - reverse: data.reverse - })); - } else { - var arr = self.objectToArray({ - object: data.object, - add: data.add, - }); - return arr.sort(dynamicSort({ - field: data.field, - reverse: data.reverse - })); - } - } else { - self.log('sort of undefined'); - return []; - } - }; - - this.objectToArray = function (data) { - // data: {object:{}, add: {}} - var arr = []; - var obj = data.object; - if (obj !== undefined) { - for (var key in obj) { - obj[key].id = key; // aggiunge la chiave dell'oggetto come proprietà - if (data.add) obj[key] = Object.assign(obj[key], data.add); - arr.push(obj[key]); - } - } - return arr; - }; - - - - /* - this.itemsFound = function(items, field, value) { - return $.grep(items, function(e){ return e.name == value; }); - } - - */ - /* this.itemFound = function(items, field, value) { - var itemFound = false; - for (var i=0; i 0); - } else { - return ($(data.class).length > 0); - } - } */ - this.equal = function (obj1, obj2) { - if (obj1 && obj2) { - return (JSON.stringify(obj1).replace('"', '') == JSON.stringify(obj2).replace('"', '')); - } else { - return (obj1 == obj2); - } - }; - - /* this.arraysEquals = function(arr1,arr2) { - return ($(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0); - } */ - var escapeRegExp = function (str) { - return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); - }; - this.replaceAll = function (str, find, replace) { - - if (str !== undefined) { - let result; - if (typeof str == 'string') result = str; else result = JSON.stringify(str); - - if (str) { - if (find) { // && replace - //if (typeof str !== 'string') self.log(str); - result = String(str).replace(new RegExp(escapeRegExp(find), 'g'), replace); - //if (typeof str == 'string') return result; else return JSON.parse(result); - if (typeof str == 'object' && result) return JSON.parse(result); - else - return result; - } else { - /* self.log('str:'+str); - self.log('find:'+find); - self.log('replace:'+replace); */ - return str; - } - } - } else { - return str; - } - }; - - this.capitalize = function (str) { - return str.replace(/\b\w/g, l => l.toUpperCase()); - }; - - - /*--------------------- - URL UTILS ----------------------*/ - this.getPageName = function (url) { - var index = url.lastIndexOf("/") + 1; - var filenameWithExtension = url.substr(index); - var filename = filenameWithExtension.split(".")[0]; // <-- added this line - return filename; // <-- added this line - }; - - this.goToMainUrl = function () { - window.location = self.mainUrl; - }; - - this.getParameterByName = function (name, url) { - if (!url) url = window.location.href; - name = name.replace(/[\[\]]/g, "\\$&"); - var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url); - if (!results) return null; - if (!results[2]) return ''; - return decodeURIComponent(results[2].replace(/\+/g, " ")); - }; - - var paramsToObject = function (params) { - params = params.split('#')[0]; - return JSON.parse('{"' + params.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}'); - }; - - var objectToParams = function (object) { - var str = ''; - for (var key in object) str += '&' + key + '=' + object[key]; - if (str) str = str.substr(1); - return encodeURI(str); - }; - - this.getParams = function () { - var params = {}; - var url = window.location.href.split('#')[0]; - if (url.indexOf('?') > -1) { - var urlParams = decodeURI(url.split('?')[1]); - self.log(urlParams); - if (urlParams) { - var k = self.getParameterByName('k', url); - //self.log(k); - if (k) { - params = self.atob(k); - } else { - params = paramsToObject(urlParams); - } - } - } - return params; - }; - - this.atob = function (k) { - self.log('atob'); - var params = paramsToObject(atob(k)); // base64 -> query -> object - - // decompress params - if (params.h) // hotel - params.h = String(parseInt(String(params.h), 36)); // base36 - if (params.c) // customer - params.c = String(parseInt(String(params.c), 36)); // base36 - if (params.n) { // phone - params.n = String(parseInt(String(params.n), 36)); // base36 - params.n = '+' + params.n; - } - //if (params.s) params.s = var.services.id[params.s]; - self.log(params); - return params; - }; - - this.btoa = function (params) { - self.log('btoa'); - //if (params.s) params.s = var.services.id.indexOf(params.s); - if (params.h) // hotel - params.h = Number(params.h).toString(36); // base36 - if (params.c) // customer - params.c = Number(params.c).toString(36); // base36 - - if (params.n) { // phone - if (params.n.startsWith('+')) params.n = params.n.substr(1); - params.n = params.n.replace(/ /g, ''); - params.n = params.n.replace(/-/g, ''); - params.n = Number(params.n).toString(36); // base36 - } - self.log(params); - return btoa(objectToParams(params)); // query -> base64 - }; - - /* - var encodeNum = function(num) { // 0..1296 es:customer - var hex = c.toString(36); - return c.toString(36); - } - - var decodeNum = function(str) { - return str.parseInt(36); // .length == 1 ? "0" + hex : hex - } - */ - this.colorToRgba = function (hex, opacity) { - if (hex == 'white') { hex = '#fff'; } - if (hex == 'black') { hex = '#000'; } - var c; - if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) { - c = hex.substring(1).split(''); - if (c.length == 3) { - c = [c[0], c[0], c[1], c[1], c[2], c[2]]; - } - c = '0x' + c.join(''); - return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ',' + opacity + ')'; - } else { - self.log('Bad Hex:' + hex); - } - }; - var hueToRGB = function (m1, m2, h) { - h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); - if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; - if (h * 2 < 1) return m2; - if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; - return m1; - }; - - var HSLToRGB = function (hsl) { - var m1, m2, r, g, b; - var h = hsl[0], s = hsl[1], l = hsl[2]; - m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s; - m1 = l * 2 - m2; - return [hueToRGB(m1, m2, h + 0.33333), - hueToRGB(m1, m2, h), - hueToRGB(m1, m2, h - 0.33333)]; - }; - - var packRGB = function (rgb) { - var r = Math.round(rgb[0] * 255); - var g = Math.round(rgb[1] * 255); - var b = Math.round(rgb[2] * 255); - // '#' + - return (r < 16 ? '0' : '') + r.toString(16) + - (g < 16 ? '0' : '') + g.toString(16) + - (b < 16 ? '0' : '') + b.toString(16); - }; - - this.degToRGB = function (deg) { - return packRGB(HSLToRGB([deg / 360, 1, 0.5])); - }; - - this.stripHtml = function (html) { - var tmp = document.createElement("DIV"); - tmp.innerHTML = html; - return tmp.textContent || tmp.innerText || ""; - }; - - //-------------------------- - // TASK MANAGER - //-------------------------- - this.log = function (value, color) { - if (self.json.setup && self.json.setup.log) { // log enabled - if (typeof value === 'string') - console.log('%c' + value, 'color:' + color); - - else - console.log(value); - } - }; - - var varlog = function (str) { - self.log(str); - self.log(window[str]); // 'var' -> var - }; - - this.logJson = function (jsonPar) { self.log(JSON.stringify(jsonPar)); }; - - this.getTimestamp = function () { - // we need also an API to get the time - // like .getTime()? - return Math.floor(Date.now()); - }; - - this.cloneObject = function (obj) { - var newObj = JSON.stringify(obj); - return self.parse(newObj); - }; - - - /*------------------------ - TEXT - ------------------------*/ - /* var caseUp = function (string) { - if (!string) string = ''; - return string.toUpperCase(); - } - - var caseDown = function (string) { - if (!string) string = ''; - return string.toLowerCase(); - } - - var capitalize = function(string) { - if (!string) string = ''; - return self.capitalize(string); - } - - var text = function (key, caseFunction) { - var t = self.json.text[key] || ''; - if (caseFunction) return caseFunction(t); else return t; - } */ - this.setElement = function (elementString, elementValue) { - var context = window; - var namespaces = elementString.split("."); - var func = namespaces.pop(); - - if (namespaces[0] == 'frame') { - namespaces.shift(); - var frameName = namespaces.shift(); - if (frameName && document.getElementById(frameName) !== null) - context = document.getElementById(frameName).contentWindow; - } else if (namespaces[0] == 'admin') { // fixo - namespaces.shift(); - context = fixoAdmin; - } - - - for (var i = 0; i < namespaces.length; i++) { - if (context[namespaces[i]]) { // var - context = context[namespaces[i]]; - } else { - if (elementValue) // scrittura - context[namespaces[i]] = {}; // crea contesto inesistente - } - } - - context[func] = elementValue; - }; - - this.context = function (path) { - const re = /^(setup|var|data|texts|parts)[\.\s]/; // reserved namespaces - if (re.test(path)) { - /* self.log('MATCHED setup|var|data|parts'); - console.log(params); */ - return self.json; - } else { - return window; - } - }; - - this.element = function (params) { - // {root, path, value} - // in respect to docElement, it includes replaceProperties for path and value - // but only if value is a string. TO DO: check it - let context; - let path = self.replaceProperties(params.path, params.args); - let value = (params.value && typeof params.value == 'string') ? self.replaceProperties(params.value, params.args) : params.value; - - // NOTE: log error if the params.root is equal to the first element of the path? (window.window works) - if (!params.root) { - context = self.context(path); - } else { - context = params.root; - } - - return self.docElement(path, value, context, params.delete); - - //self.log(value); - /* if (value && typeof value == 'string') { - if (value.startsWith('js:')) value = self.js(value.substr(3)); - else if (value.startsWith('+=')) value = self.element({path: path}) + self.js(value.substr(2)); - else if (value.startsWith('-=')) value = self.element({path: path}) - self.js(value.substr(2)); - else if (value.startsWith('/=')) value = self.element({path: path}) / self.js(value.substr(2)); - else if (value.startsWith('*=')) value = self.element({path: path}) / self.js(value.substr(2)) - } */ - // self.log(value); - /* if (value.startsWith('number:')) value = Number(self.js(value.substr(6))); - alert('dopo number:'+value); - if (value.startsWith('boolean:')) value = Boolean(self.js(value.substr(7))); - if (value.startsWith('string:')) value = String(self.js(value.substr(6))); - if (value.startsWith('+:')) value = self.element({path: path}) + self.js(value.substr(2)); - if (value.startsWith('-:')) value = self.element({path: path}) - self.js(value.substr(2)); - if (value.startsWith('/:')) value = self.element({path: path}) / self.js(value.substr(2)); - if (value.startsWith('*:')) value = self.element({path: path}) / self.js(value.substr(2)); */ - /* // verificare... - if (value.startsWith('push:')) {var obj = self.docElement(path, undefined, root); return obj.push(value.substr(3));} - if (value.startsWith('unshift:')) {var obj = self.docElement(path, undefined, root); return obj.unshift(value.substr(3));} - if (value.startsWith('pop:')) {var obj = self.docElement(path, undefined, root); return obj.pop(value.substr(3));} - if (value.startsWith('shift:')) {var obj = self.docElement(path, undefined, root); return obj.shift(value.substr(3));} */ - }; - - this.docElement = function (elementString, elementValue, context, elementDelete) { - - if (!context) context = window; // TO DO: remove - var namespaces = elementString.split(/[.\s]+/); // path nodes separed by dot or spaces - - - - - - - - - - - /* console.log('<-------'); - console.log('context'); - console.log(context); - console.log('path'); - console.log(elementString); - console.log('value'); - console.log(elementValue); - console.log('------>'); -*/ - var lastElement = namespaces.pop(); - - /* if (namespaces[0] == 'self') { - namespaces.shift(); - context = self; - } else if (namespaces[0] == 'frame') { - namespaces.shift(); - var frameName = namespaces.shift(); - if (frameName && document.getElementById(frameName) !== null) - context = document.getElementById(frameName).contentWindow; - } */ - /* console.log('namespaces'); - console.log(namespaces); */ - for (var i = 0; i < namespaces.length; i++) { - if (context[namespaces[i]]) { // var - context = context[namespaces[i]]; - } else { - if (elementValue !== undefined && elementValue !== null) { // wants to assign a value - context[namespaces[i]] = {}; // it create the context context[namespaces[i]] if it doesn't exist - context = context[namespaces[i]]; - /* self.log('crea context inesistente'); - self.log('namespaces[i]: '+namespaces[i]); */ - /* self.log('elementValue'); - self.log(elementValue); - self.log('context[namespaces[i]]'); - self.log(context[namespaces[i]]); */ - } else { - /* self.log(elementString + ' undefined'); - self.log('lastElement:' + lastElement); - self.log(elementValue); */ - } - //break; // perché? rendeva impossibile creare un listener su un nodo secondario (solo su app e non su app/dev) - } - } - - if (elementValue !== undefined) { // write - - //self.log(lastElement+'='+elementValue); - if (typeof elementValue == 'string') elementValue = self.js(elementValue); // 1.0.3 - context[lastElement] = elementValue; - - // elementValue can be a js function - /* self.log('context'); - self.log(context); - self.log('context[lastElement]'); - self.log(context[lastElement]); - self.log('====='); */ - } - - if (elementDelete) delete context[lastElement]; - - /* self.log('context'); - self.log(context); */ - /* console.log('namespaces'); - console.log(namespaces); - self.log('lastElement'); - self.log(lastElement); - self.log('context[lastElement]'); - self.log(context[lastElement]); */ - if (context[lastElement] && context[lastElement].isConnected) - return self.elementToSelector(context[lastElement]); - - else - return context[lastElement]; - }; - - /* this.openCloseDropdown = function(key) { - self.log('openCloseDropdown'); - self.log("key"); - self.log(key); - //$('.dropdown-menu').css('display','none'); - var selector = self.selector({ - "id": "dropdown" +key, - "class": 'points', - "value": key, - }); - self.log("selector"); - self.log(selector); - if ($(selector + ' > .dropdown-menu').css('display') == 'none') { - $(selector + ' > .dropdown-menu').css('display', 'block'); - } else { - $(selector + ' > .dropdown-menu').css('display', 'none'); - } - } */ - this.timeToMs = function (string) { - // bug - var timeArray = string.match(/(\d+)(\w+)/); // es: 1s / 100ms - if (timeArray) { - var value = Number(timeArray[0]); - var unit = timeArray[1]; - var unitInMs = { - ms: 1, - s: 1000, - m: 1000 * 60, - h: 1000 * 60 * 60, - d: 1000 * 60 * 60 * 24, - milliseconds: 1, - seconds: 1000, - minutes: 1000 * 60, - hours: 1000 * 60 * 60, - days: 1000 * 60 * 60 * 24 - }; - if (value) - if (unitInMs[unit]) - return value * unitInMs[unit]; - - else - self.log('wrong unit in the time string [value][unit]: ' + string); - - else - self.log('wrong value in the time string [value][unit]: ' + string); - } - else - return Number(string); - }; - - this.intervals = {}; - - this.timer = function (params, args) { - // can go in "browser.json / functions (JS Browser BOM) - // https://www.w3schools.com/js/js_window.asp - let name = self.replaceProperties(params.name); - if (!name) - name = self.getTimestamp() + Math.random(1000); - - if (params.play !== undefined && params.play == 0) { - if (self.intervals[name]) { - self.clearInterval({ - name: name - }, args); - } - if (self.timeouts[name]) { - self.clearTimeout({ - name: name - }, args); - } - } - else if (params.every !== undefined) { - let every = self.replaceProperties(params.every); - if (every) { - self.setInterval({ - name: name, - duration: every, - do: params.do - }, args); - } - } - else if (params.after !== undefined) { - let after = self.replaceProperties(params.after); - if (after) { - self.setTimeout({ - name: name, - duration: after, - do: params.do - }, args); - } else { - self.do(params.do, null, args); - } - } - }; - - this.setInterval = function (params, args) { - // could include the param "fromNow": true to execute the function - /* self.log('setInterval'); - self.log(params); */ - if (params.name && params.duration) { - if (self.intervals[params.name]) - clearInterval(self.intervals[params.name]); - - //self.do(params.do); - self.do(params.do); - self.intervals[params.name] = setInterval(function () { - //self.do(params.do); - self.do(params.do); - return params.name; - }, Number(params.duration)); // self.timeToMs - } - else - self.log('"setInterval" function requires "name" and "duration" parameters'); - }; - - this.clearInterval = function (params, args) { - /* self.log('params'); - self.log(params); - self.log('self.intervals[params.name]'); - self.log(self.intervals[params.name]); */ - if (self.intervals[params.name]) { - clearInterval(self.intervals[params.name]); - delete self.intervals[params.name]; - } - // else - // self.log('"clearInterval" name not found: ' + params.name); - }; - - this.timeouts = {}; - - this.setTimeout = function (params, args) { - // could include the param "fromNow": true to execute the function - /* self.log('setTimeout'); - self.log(params); */ - if (params.name && params.duration) { - if (self.timeouts[params.name]) - clearInterval(self.timeouts[params.name]); - - //self.do(params.do); - //self.do(params.do); - self.timeouts[params.name] = setTimeout(function () { - //self.do(params.do); - self.do(params.do); - return params.name; - }, Number(params.duration)); // self.timeToMs - } - else - self.log('"setTimeout" function requires "name" and "duration" parameters'); - }; - - this.clearTimeout = function (params, args) { - /* self.log('params'); - self.log(params); - self.log('self.timeouts[params.name]'); - self.log(self.timeouts[params.name]); */ - if (self.timeouts[params.name]) { - clearTimeout(self.timeouts[params.name]); - delete self.timeouts[params.name]; - } - //else - // self.log('"clearInterval" name not found: ' + params.name); - }; - - - - - this.on = function (params, selectorParams) { - //let selector = params.selector || params.container; - - var container = (selectorParams) ? self.selector(selectorParams) : params.selector; // 1.0.9 instead of params.container - - - - - - - - - - - /* self.log('on'); - self.log(params); - self.log('container'); - self.log(container); */ - //var selector = self.selector(self.extend({}, params, selectorParams)); - //$(container).data('onData', {events: params, container: container}); - var element; - - if (container) { - element = self.query(container); // shoud be foreach elements... - if (element) - self.dataStorage.set(element, "onData", { on: params, selector: container }); - else { - self.log('can\'t find the element "' + container + '" ("on" function)'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } /* else { - self.log('"on" function with selector undefined'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } */ - - - - - - - - for (var eventId in params) { - //var eventAction = params[eventId]; - //$(selector).data('onData').action = eventAction; - /* if (eventId == 'thunkable') { - self.thunkable(params[eventId]); - } else */ - if (eventId == 'init') { - //self.log(params.init); - //self.do(params.init, undefined, selectorParams); - self.do(params.init, selectorParams); - } else if (eventId == 'hashchange') { - self.onHashChange.push(params.hashchange); - window.addEventListener('hashchange', function () { - self.json.setup.page.hash = window.location.hash.substr(1); // potrebbe essere esplicitato sulla app - - - - //var action = self.cloneObject(params.app.on.hashchange); - //self.replaceAll("{result}", window.location.hash); - //self.do(self.onHashChange); - self.do(self.onHashChange); - self.uiUpdate(); - }); - } else if (eventId == 'scroll') { - self.onScroll.push(params.scroll); - window.addEventListener('scroll', function () { - //self.do(self.onScroll); - self.do(self.onScroll); - }); - } else if (eventId == 'resize') { - self.onResize.push(params.resize); - window.addEventListener('resize', function () { - //self.do(self.onResize); - self.do(self.onResize); - }); - } else if (eventId == 'in') { // like inViewport but only one time - if (container) { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - /* self.log('entry'); - self.log(entry); - self.log('entry.target'); - self.log(entry.target); */ - /* self.log(entry); - self.log(entry.intersectionRatio); - self.log(entry.isIntersecting); - self.log(entry.isVisible); */ - // isIntersecting, isVisible - //var element = self.query(entry.target); - //self.log(entry.intersectionRatio); - if (entry.intersectionRatio == 1) { // .isIntersecting? - var el = entry.target; - if (el.getAttribute('in') !== 'true') { - el.setAttribute('in', 'true'); // change with dataStorage - self.onEvent(entry.target, { type: 'in' }); - } - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] // if 0.5 is the half-height of the elmement - }); - //const element = self.query(container); - observer.observe(self.query(container)); - } - } else if (eventId == 'inViewport') { - if (container) { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - /* self.log('entry'); - self.log(entry); - self.log('entry.target'); - self.log(entry.target); */ - /* - self.log(entry.intersectionRatio); - self.log(entry.isIntersecting); - self.log(entry.isVisible); */ - // isIntersecting, isVisible - //var element = self.query(entry.target); - //self.log(entry.intersectionRatio); - if (entry.intersectionRatio > 0) { - self.onEvent(entry.target, { type: 'inViewport' }); - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] // if 0.5 is the half-height of the elmement - }); - //const element = self.query(container); - observer.observe(self.query(container)); - } - } else if (eventId == 'outViewport') { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - /* self.log(entry); - self.log(entry.isIntersecting); - self.log(entry.isVisible); */ - // isIntersecting, isVisible - //var element = self.query(entry.target); - //self.log(entry.intersectionRatio); - if (entry.intersectionRatio == 0) { - self.onEvent(entry.target, { type: 'outViewport' }); - /* var el = entry.target; - if (el.getAttribute('in') == 'true') { - el.setAttribute('in', 'false'); - self.onEvent(entry.target, {type: 'out'}); - } */ - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] // if 0.5 is the half-height of the elmement - }); - const element = self.query(container); - observer.observe(element); - - - } else if (eventId !== 'selector') { - - /* if (container == '.nav-link[data-value="docs"]') { - alert(JSON.stringify(params)); - //element = element[0]; - $(element).hide(); - } */ - //element.removeEventListener(eventId); - // $(container).off(eventId); - if (element) { - - // TO DO: verify - //if (element.getAttribute('listener') !== 'true') { // only one mouse event - //self.log('addEventListener: ' + eventId); - element.addEventListener(eventId, function (event) { - //$(container).off(eventId).on(eventId, function (event) { - /* self.log('event'); - self.log(event); */ - element.setAttribute('listener', 'true'); - //event.preventDefault(); - //event.stopPropagation(); - self.onEvent(this, event); - }); - //} - if (eventId == 'mousedown' || eventId == 'mouseup' || eventId == 'click') - element.style.cursor = 'pointer'; - } - - /* $(container).off(eventId).on(eventId, function (event) { - //$(container).off(eventId).on(eventId, function (event) { - self.log('event'); - self.log(event); - event.preventDefault(); - event.stopPropagation(); - self.onEvent(this, event); - }); */ - //$(container).css({cursor: 'pointer'}); - } - } - - }; - - /* this.addAction = function (params, selectorParams) { - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - $(selector).data('onData', params); - //$(selector).data('onData', {action: params.action, params: params.args}); - $(selector).off().on(this.touch, function (event) { - event.stopPropagation(); - self.onEvent(this, event); - }); - $(selector).css({cursor: 'pointer'}); - } */ - /* this.ace = function (params) { - params.container = 'blockCode'; - var editor = ace.edit("blockCode"); - var langTools = ace.require('ace/ext/language_tools'); - editor.setTheme("ace/theme/monokai"); // ambiance - editor.getSession().setMode("ace/mode/json"); - //editor.renderer.setOption('showLineNumbers', false); - editor.container.style.background="rgba(255,255,255,0)"; - - var staticWordCompleter = { - getCompletions: function(editor, session, pos, prefix, callback) { - var wordList = ["app", "setup", "pages"]; - callback(null, wordList.map(function(word) { - return { - caption: word, - value: word, - meta: "static" - }; - })); - - } - } - editor.completers = [staticWordCompleter]; - - // https://github.com/ajaxorg/ace/wiki/Configuring-Ace - editor.setOptions({ - fontSize: "11pt", - selectionStyle: "text", - highlightActiveLine: true, - wrap: true, - showLineNumbers: false, - showGutter: false, - fixedWidthGutter: false, - readOnly: true, - //enableBasicAutocompletion: true, - //enableSnippets: true, - //enableLiveAutocompletion: true, - }); - editor.setValue(var.code, -1); - } */ - /* this.edit = function (item) { - //var.code = JSON.stringify(item, null, '\t'); - - self.do( { - "alert": { - "background": "rgba(255,255,255,0.9)", - "width": "93%", - "showCancelButton": true, - "cancelButtonText": 'Cancel', - "confirmButtonText": 'Save', - "html": '
      ' - } - }); - //self.code(JSON.stringify(item, null, '\t'),); - self.code(item, {container: '#blockCode'}); - - //setTimeout(function () { - - //alert(var.blockCode); - // https://codepen.io/jjsjjja/pen/VoGYRB - //}, 100); - } */ - this.money = function (value) { - /* if (value && value.indexOf(',') == -1 && value.indexOf('.') == -1) { - value = value + '.00'; - } */ - var rounded = Math.round(Number(value) * 100) / 100; - var string = String(rounded); - if (rounded == Math.floor(rounded)) - string += ',00'; - string = String(string).replace('.', ','); - return string; - }; - - - this.offcanvas = function (params) { - self.log('offcanvas'); - self.log('params'); - self.log(params); - // https://getbootstrap.com/docs/5.0/components/offcanvas/ - // to add: toggle, getInstance, getOrCreateInstance - var container = params.selector || params.container; - var selector = self.selector(container); - var element = self.query(selector); - self.log('offcanvas'); - self.log(params); - self.log('selector'); - self.log(selector); - self.log('element'); - self.log(element); - // do: show (default) / hide (see boostrap Offcanvas docs) - if (element) { - if (params.do == 'hide') { - self.css({ - removeClass: 'show' - }, params); - //new bootstrap.Offcanvas(element).hide(); // doesn't work - } else { - new bootstrap.Offcanvas(element).show(); - } - } else { - self.log('"offcanvas" method can\'t find the selected element'); - } - }; - - /** - * Converts a DOM element to its CSS selector string representation - * @param {HTMLElement} element - The DOM element to convert - * @returns {string} The CSS selector string that uniquely identifies the element - */ - this.elementToSelector = function (element) { - // 1. Use ID if available - if (element.id) { - return '#' + element.id; - } - - // 2. Use data-value if unique - if (element.dataset?.value) { - const sameDataValue = document.querySelectorAll(`[data-value="${element.dataset.value}"]`); - if (sameDataValue.length === 1) { - return `[data-value="${element.dataset.value}"]`; - } - } - - // 3. Use class if unique - if (element.classList && element.classList.length > 0) { - for (const className of element.classList) { - if (className) { - const sameClass = document.querySelectorAll('.' + className); - if (sameClass.length === 1) { - return '.' + className; - } - } - } - } - - // 4. Use tag if unique - const tagName = element.tagName.toLowerCase(); - const sameTag = document.querySelectorAll(tagName); - if (sameTag.length === 1) { - return tagName; - } - - // 5. Fallback to tag + nth-child path - let path = []; - while (element.parentNode) { - let selector = element.tagName.toLowerCase(); - const index = Array.from(element.parentNode.children).indexOf(element) + 1; - selector += `:nth-child(${index})`; - - path.unshift(selector); - element = element.parentNode; - } - return path.join(' > '); - }; - - - this.onEvent = function (element, event) { - //self.log('element'); - //self.log(element); - /* self.log('event'); - self.log(event); */ - /* if (event) { - event.preventDefault(); // verify - event.stopPropagation(); - } */ - /* var item = {}; - if (self.dataStorage.has(element, 'onData')) - item = self.dataStorage.get(element, 'onData'); */ - var item = self.dataStorage.get(element, 'onData'); - var code = self.dataStorage.get(element, 'code') || ''; - //var item = $(element).data('onData'); - //var code = $(element).data('code'); - //var value = String($(element).data('value')); - //var selector = $(element).data('selector'); - //var value = String(self.dataStorage.get(element, 'value')); - var value = element.getAttribute('data-value'); - //var selector = element.getAttribute('data-selector'); - var selector = self.elementToSelector(element); // 1.0.12 - - - - - - - - - /* self.log('value'); - self.log(value); - self.log('args'); - self.log(args); */ - var eventType = (event.type && item.on) ? item.on[event.type] : undefined; - - /* self.log('onEvent'); - self.log('item'); - self.log(item); - self.log('selector'); - self.log(selector); - self.log('event.type'); - self.log(event.type); */ - /* - if (event) { - args = { - value: value, - event: eventType - } - } - */ - /* self.log('event.type'); - self.log(event.type); - self.log('event'); - self.log(event); */ - var action, specialKey; - - if (item.on) { - - if (event.button == '2' && event.type == 'mousedown') { // right click / long touch - - if (item.on['contextmenu']) - action = item.on['contextmenu']; - - } else if (event.type && item.on[event.type]) { - - var eventAction = item.on[event.type]; - - //const specialKeys = ['shiftKey', 'altKey', 'cmdKey']; - if (eventAction) { - if (eventAction.shiftKey && event.shiftKey) { - specialKey = 'shiftKey'; - action = eventAction.shiftKey; - } else if (eventAction.altKey && event.altKey) { - specialKey = 'altKey'; - action = eventAction.altKey; - } else if (eventAction.cmdKey && event.cmdKey) { - specialKey = 'cmdKey'; - action = eventAction.cmdKey; - } else if (!eventAction.shiftKey && !eventAction.altKey && !eventAction.cmdKey) { - action = item.on[event.type]; - } - } - } - } - - if (action) { - //console.dir(action); - //action = self.replaceProperty(action, '{on:target}', targetId); - if (event.target) { - //self.log(event); - var actionString; - var targetId = event.target.id; - var targetClass = event.target.className; - var targetValue = event.target.dataset.value; - var targetSelector = event.target.dataset.selector; // deprecated - - - - /* self.log('event'); - self.log(event); */ - //if (targetValue) alert(targetValue); - targetSelector = self.replaceAll(targetSelector, '"', '\''); // TO DO: if JSON5? - action = self.stringify(action); - if (typeof targetId !== 'string') targetId = ''; - if (typeof targetClass !== 'string') targetClass = ''; - - /* actionString = self.replaceAll(action, '{event.target.id}', targetId); - actionString = self.replaceAll(actionString, '{event.altKey}', event.altKey); - actionString = self.replaceAll(actionString, '{event.target.className}', targetClass); - actionString = self.replaceAll(actionString, '{event.target.data-value}', targetValue); // obsolete - actionString = self.replaceAll(actionString, '{event.target.dataset.value}', targetValue); - actionString = self.replaceAll(actionString, '{event.target.dataset.selector}', targetSelector); */ - actionString = self.replaceAll(action, '{on:target.id}', targetId); - actionString = self.replaceAll(actionString, '{on:altKey}', event.altKey); - actionString = self.replaceAll(actionString, '{on:target.className}', targetClass); - actionString = self.replaceAll(actionString, '{on:target.data-value}', targetValue); // obsolete - actionString = self.replaceAll(actionString, '{on:target.dataset.value}', targetValue); - actionString = self.replaceAll(actionString, '{on:target.dataset.selector}', targetSelector); // deprecated - actionString = self.replaceAll(actionString, '{on:which}', event.which); - actionString = self.replaceAll(actionString, '{on:clientY}', event.clientY); - actionString = self.replaceAll(actionString, '{on:clientX}', event.clientX); - - // custom - actionString = self.replaceAll(actionString, '{on:value}', targetValue); - actionString = self.replaceAll(actionString, '{on:dragging}', (event.which > 0)); - //actionString = self.replaceProperty(actionString, 'on', event); - if (this.isJson(actionString)) - action = self.parse(actionString); - - else - action = actionString; - } - - // TODO: let decide to the user the parameter to pass - var args = item.args; // || item.params || item.value || value; - - - - - //args.event = event; - //if (args) - // action = self.replaceResult(action, args); - let specialKeyLog = (specialKey) ? ' + ' + specialKey : ''; - //self.log('event ' + event.type + specialKeyLog); - //self.log('action'); - //self.log(action); - /* self.log('args'); - self.log(args); - self.log('{container: selector}'); - self.log({container: selector}); */ - //self.do(action, args, {selector: selector}); // TO DO: only if mouse over or - self.do(action, { selector: selector }, args); - } // (action) - - }; - - this.pluginsFunctionAvailable = []; // should use pluginsLoaded - - self.pluginsLoader = function (packs, callback, params) { - /* self.log('pluginsLoader'); - self.log('packs'); - self.log(packs); - self.log('callback'); - self.log(callback); - self.log('params'); - self.log(params); */ - //self.pluginsFunctionAvailable.push(name); // posizione giusta - var filesToLoad = []; - - for (pack of packs) { - /* self.log('pack'); - self.log(pack); */ - if (self.pluginsLoaded[pack.name] == undefined) { - - self.log('require plugin ' + pack.name, 'grey'); - var plugin = self.findPlugin(pack.name); - let version; - var pluginsFiles; - if (plugin) { - pluginsFiles = plugin.files || plugin; - version = plugin.version; - } else { - pluginsFiles = self.json.resources.pluginsFiles[pack.name]; // TO DO: obsolete, remove - version = pack.version; - } - - /* if (params) { - if (!Array.isArray(params[0])) params[0] = [params[0]]; - if (!self.pluginsCallbacks[pack.name]) self.pluginsCallbacks[pack.name] = []; - self.pluginsCallbacks[pack.name].concat(params[0]); - } */ - self.pluginsLoaded[pack.name] = version; // should contain the queue of actions to do after the plugin loads - - - - - // TO DO: move in Promise.all(promises).then(function() { - // it needs to feed a queue of actions to do after the plugin loads - if (!Array.isArray(pluginsFiles)) // multi-file plugin - pluginsFiles = [pluginsFiles]; - - /* self.log('pluginsFiles'); - self.log(pluginsFiles); */ - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({ name: item.name, url: url, type: item.type }); - } - } - - } - - //self.log(filesToLoad); - if (filesToLoad.length > 0) { - - let promises = []; - - filesToLoad.forEach(function (item) { - promises.push(loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content })); - //promises.push(loadPlugin(url)); - }); - - Promise.all(promises).then(function (files) { - // all filesToLoad are loaded (all the Promise in loadPlugin are solved) - /* self.log('all plugin files are loaded'); - self.log(files); - self.log(params); */ - callback(...params); // change with ... - - - //callback(params[0], params[1], params[2]); // change with ... - }).catch(function (script) { - self.log('failed to load error'); - self.log(item); - self.log(script); - }); - } - }; - - - this.pluginsRequired = function (params) { - /* self.log('pluginsRequired'); - self.log(params); */ - // analize function object or array of objects - if (self.json.resources) { - const pluginsFunctions = self.json.resources.pluginsFunctions; - var pluginsRequired = []; - if (typeof params == 'string') { - /* self.log('params'); - self.log(params); */ - if (pluginsFunctions[params]) { - if (!self.pluginsLoaded[pluginsFunctions[params].name]) - pluginsRequired.push(pluginsFunctions[params]); - } - } else if (typeof params == 'object') { - var objArray; - if (Array.isArray(params)) objArray = params; else objArray = [params]; - /* self.log('objArray'); - self.log(objArray); */ - for (var obj of objArray) { - /* self.log('obj'); - self.log(obj); */ - for (var key in obj) { - var mainFunction = (key.indexOf('.') >= 0) ? key.substr(0, key.indexOf('.')) : key; - //self.log('mainFunction'); - //self.log(mainFunction); - if (pluginsFunctions[mainFunction]) { - if (!self.pluginsLoaded[pluginsFunctions[mainFunction].name]) - pluginsRequired.push(pluginsFunctions[mainFunction]); - } /* else if (key == 'var') { - const functionName = self.functionName(obj.var.value); - if (functionName) { - if (!self.pluginsLoaded[pluginsFunctions[functionName].name]) - pluginsRequired.push(pluginsFunctions[functionName]); - } - } */ - - - - - - - } - } - } - return pluginsRequired; - } else { - return []; - } - }; - - this.functionName = function (obj) { - if (obj == 'object') { - const name = Object.keys(obj)[0]; - const pluginFunctions = ['database', 'ace', 'moment', 'dayjs']; - if (pluginFunctions.indexOf(name) >= 0) - return name; - } - }; - - /* - this.runParts = function (actionObj, container, argumentsPar, handleOtherActions) { - console.log('runParts'); - console.log(actionObj); - if (Array.isArray(actionObj)) { - for (var action in actionObj) - self.runParts(action); - } else { - var otherMethods = false; - var otherActions = {}; - for (var partKey in actionObj) { - - if (partKey.startsWith('var ') || partKey.startsWith('data ') || partKey.startsWith('set ')) - self.setData({path: partKey, value: actionObj[partKey]}); - else { - var methodOrPart = false; - var method = self.element({path: partKey, root: self.methods}); - if (method) { // search in jsonic.methods - methodOrPart = true; - if (typeof method == 'function') { - //self.docElement(actionObj[partKey]); - self.log('method: ' + partKey); - method(actionObj[partKey], container, argumentsPar); - } - } else if (self.json.parts) { // search in self.json.parts - var part = self.element({path: 'parts.'+self.replaceAll(partKey,':','.')}); - if (part) { - part = self.replaceProperty(part, 'arg', actionObj[partKey]); - if (actionObj[partKey].setup) - part = self.replaceProperty(part, 'setup', actionObj[partKey].setup); - console.log('part'); - console.log(part); - self.run(part, container); - methodOrPart = true; // if (!actionFound) { will go in the else (!part) - } - } - if (!methodOrPart) otherActions[partKey] = actionObj[partKey]; - else otherMethods = true; - } - } - - //if (handleOtherActions) handleOtherActions(otherActions, container, argumentsPar); - return otherMethods; - } - } - */ - /* this.jsonicMethods = function (actions, container, argumentsPar) { - - // 'icons' should be removed from the json files - - var withContainer; - var functionFound = false; - - for (var actionKey in actions) { - - //if (nodes.functions.indexOf(actionKey) >= 0) { - - switch (actionKey) { - - case 'for': - case 'editor': - case 'ace': - case 'code': - case 'qrcode': - case 'lottie': - case 'animate': - case 'html': - case 'hide': - case 'show': - case 'toggle': - case 'in': - case 'out': - case 'if': - case 'ajax': - case 'attr': - case 'run': - case 'delay': - case 'css': withContainer = true; break; - default: withContainer = false; - } - var functionObj = actions[actionKey]; - if (functionObj) { - functionFound = true; - if ((functionObj.if == undefined) || self.if(functionObj.if, container, argumentsPar)) { - return self.doFunction({ - name: nodes.functions[actionKey], - function: functionObj, - args: argumentsPar, - selector: container, - withContainer: withContainer - }); - } else { - if (functionObj.if !== undefined) { - self.log(self.js(functionObj.if, argumentsPar)); - } - } - } else if (nodes.params.indexOf(actionKey) < 0) - return self.method(actions[actionKey], argumentsPar); - - } - - - } */ - /* this.do = function (actionPar, argumentsPar, selectorParams) { // ex this.action - - if (actionPar !== undefined && actionPar !== null) { // !== undefined - - // check plugins required - let pluginsRequired = self.pluginsRequired(actionPar); - if (pluginsRequired.length > 0) { - let params = [actionPar, argumentsPar, selectorParams]; - self.pluginsLoader(pluginsRequired, self.do, params); - - } else { - - if (Array.isArray(actionPar)) { - - if (actionPar.length > 0) { - var actionArray = []; - for (var index in actionPar) - if (typeof actionPar[index] == 'object') - actionArray[index] = self.cloneObject(actionPar[index]); - else - actionArray[index] = actionPar[index]; - //actionArray = actionArray.concat(actionPar); - //actionArray = self.cloneObject(actionPar); - var actionFunction = actionArray.shift(); - self.do(actionFunction, argumentsPar, selectorParams); - if (actionArray.length > 0) - self.do(actionArray, argumentsPar, selectorParams); - } - } else { - - if (typeof actionPar == 'function') { - - return actionPar(argumentsPar); - - } else if (typeof actionPar == 'string') { - - var actionPart = self.element({path: 'parts.' + actionPar}); // it includes replaceProperties - self.log('actionPar stringa'); - self.log(actionPar); - if (actionPart) - return self.do(actionPart, argumentsPar); - //else if (json.actions[actionPar]) // obsolete - // return self.do(json.actions[actionPar], argumentsPar); - else - return actionPar; //return self.js(actionPar); // TO DO: finisce qui anche una stringa di un tag p ("p": "string") - - - } else if (typeof actionPar == "object") { - - var actionObj = actionPar; - var container = actionObj.selector || actionObj.container || selectorParams; - - // events - if (actionObj.on) {self.on(actionObj.on, container);} - - - if (self.notEmptyObject(actionObj)) { - - - var actionFound = self.runParts(actionObj, container, argumentsPar, self.jsonicMethods); - - - if (!actionFound) { - - var functionFound = false; - - for (var index in nodes.functions) { - //if (nodes.params.indexOf(actionKey) < 0) - - //var action = Object.keys(actionObj)[0]; - var withContainer = (nodes.functionsWithContainer.indexOf(nodes.functions[index]) >=0 ); - var functionObj = actionObj[nodes.functions[index]]; - if (functionObj) { - functionFound = true; - if ((functionObj.if == undefined) || self.if(functionObj.if, container, argumentsPar)) { - //if ((functionObj.if == undefined) || Boolean(self.js(functionObj.if, argumentsPar))) { - return self.doFunction({ - name: nodes.functions[index], - function: functionObj, - args: argumentsPar, - selector: selectorParams, - withContainer: withContainer - }); - } else { - if (functionObj.if !== undefined) { - - self.log(self.js(functionObj.if, argumentsPar)); - } - } - } - } - - if (!functionFound) { - self.log('actionPar'); - self.log(actionPar); - self.log('!functionFound'); - self.log(actionObj); - return self.method(actionObj, argumentsPar); - } - - } - } - - } else { - //self.log('Function not found'); - //self.log(actionPar); - //self.log(argumentsPar); - return actionPar; - // functions from this.do - //actionPar(argumentsPar); - } - } - } - } else { - // TO DO: check - //self.log('function with actionPar undefined'); - } - - } - */ - /* this.jsonicMethod2 = function (actionObj, selectorParams, argumentsPar) { - - var functionFound = false; - - for (var action in actionObj) { - var functionObj = actionObj[action]; - if (functionObj) { - var withContainer = (nodes.functionsWithContainer.indexOf(action) >=0 ); - functionFound = true; - if ((functionObj.if == undefined) || Boolean(self.js(functionObj.if, argumentsPar))) { - return self.doFunction({ - name: action, - function: functionObj, - args: argumentsPar, - selector: selectorParams, - withContainer: withContainer - }); - } - } - - if (!functionFound) { - self.log('!functionFound'); - self.log('actionObj'); - self.log(actionObj); - return self.method(actionObj, argumentsPar); - } - } - - - } */ - this.for = function (params, selectorParams, args) { - /* self.log('for'); - self.log(params); */ - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - - // TO DO: doesn't go as an automous function (needs to be inside a div) - /* self.log('for'); - self.log('container'); - self.log(container); */ - //if (params.html) { // new version - let itemsName = params.id || params.name; - //self.log('itemsArray'); - //self.log(itemsArray); - /* if (params.reverse) { - var itemsReversed = {}; - for (var key in Object(itemsArray).keys().reverse()) { - itemsReversed[key] = itemsArray[key]; - } - itemsArray = itemsReversed; - } */ - if (params.of) { - //var itemsArray = self.cloneObject(params.of); // value is the previous array id - //if (typeof itemsArray == 'string') - //itemsArray = self.compile(itemsArray, args); // compile includes functions and create bugs - //self.log('params.of'); - //self.log(params.of); - var itemsArray = self.replaceProperties(params.of, args); - - - /* self.log('itemsArray'); - self.log(itemsArray); */ - /* if (typeof itemsArray == 'string') { - itemsArray = self.js(itemsArray); // TO DO: check - } */ - if (itemsArray) { - - /* if (typeof itemsArray == 'string') { - if (itemsArray.startsWith('js:')) itemsArray = self.js(itemsArray.substr(3)); - //else itemsArray = self.replaceProperties(itemsArray, args); - } */ - /* else { - itemsArray = self.actionResult(itemsArray, args); - itemsArray = self.replaceProperties(itemsArray, args); - } */ - /* self.log('itemsArray replaced'); - self.log(itemsArray); */ - /* self.log('for'); */ - /* self.log(itemsName); */ - /* self.log(itemsArray); */ - if (params.html) { // 1.0.6 html in for is deprecated - if (!params.do) params.do = []; - else if (!Array.isArray(params.do)) params.do = [params.do]; - params.do.push({ html: params.html }); - } - - - //delete params; // needed to avoid infinite loop - if (typeof itemsArray == 'object') { - - let indexNum = 0; - - for (var index in itemsArray) { - - var item = itemsArray[index]; - - if (typeof item == 'object') { - item.key = index; // obsolete - item.index = index; // obsolete - } - - if (typeof item.output == 'object') { // TO DO: obsolete - - /* self.log('item.for.output'); - self.log(item.for.output); */ - for (let key in item.output) { - - var output = item.output[key]; - if (typeof output == 'string') { - output = self.js(output, args); - } else if (typeof output == 'object') { - //output = self.compile(output, args); - output = self.replaceProperties(output, args); - } - - item = self.replaceItems(item, output, key); // replace - - - - //item = self.replaceProperty(item, key, output); - } - } - - if (params.do.length > 0) { - - //alert(JSON.stringify(params.do)); - //self.do(self.replaceProperty(params.do, itemsName, item), undefined, {selector: container}); - //let objWithIndex = self.replaceStringInObject(params.do, '{' + params.index + '}', index); - let objWithIndex = params.do; - - if (params.var) { // TO DO: obsolete (remove when used) - self.element({ path: params.var, value: item, root: self.json.var }); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, 'index:' + params.var, index); - //objWithIndex = self.replaceStringInObject(objWithIndex, '{index:'+params.var+'}', index); - } - - if (itemsName) { - //objWithIndex = self.replaceStringInObject(objWithIndex, '{index:'+itemsName+'}', index); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, 'index:' + itemsName, index); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, itemsName, item); - //objWithIndex = self.replaceProperty(objWithIndex, 'value:'+itemsName, item); - //objWithIndex = self.replaceProperty(objWithIndex, itemsName, item); // obsolete - } - - if (params.delay) { - params.delay = self.replaceProperties(params.delay); - - let forId = params.var || itemsName; - self.timer({ - name: 't' + forId + index, - after: indexNum * params.delay, - do: objWithIndex - }); - } else { - self.do(objWithIndex, { selector: container }); - } - } - - /* if (params.html) { // should be inside a do // commented from 1.0.6 - let indexName = params.index || 'index'; - let objWithIndex = self.replaceStringInObject(params.html, '{'+indexName+':'+itemsName+'}', index); - objWithIndex = self.replaceProperty(objWithIndex, itemsName, item); - self.do(objWithIndex, {selector: container}); - } */ - indexNum += 1; - - } - } - } - - } else if (params.from !== undefined && params.to !== undefined) { - - /* var step = Number(params.step) || 1; - var from = Number(params.from) || 0; - var to = Number(params.to); */ - var step = self.js(self.replaceProperties(params.step)) || 1; - var from = self.js(self.replaceProperties(params.from)) || 0; - var to = self.js(self.replaceProperties(params.to)); - /* var step = Number(self.replaceProperties(params.step)) || 1; - var from = Number(self.replaceProperties(params.from)) || 0; - var to = Number(self.replaceProperties(params.to)); */ - /* self.log('from'); - self.log(from); - self.log('to'); - self.log(to); - self.log('step'); - self.log(step); */ - if (to !== undefined) { - - for (var index = Number(from); index <= Number(to); index += Number(step)) { - - if (params.var) - self.element({ path: params.var, value: index, root: self.json.var }); - - // TO DO: find "if (params.html) { // 1.0.6" and modify also the following code - var item = self.replaceItems(params, String(index), itemsName); // obsolete: replaced with {index:itemsName} - - - - - - - - - - - //var item = self.replaceProperty(params, itemsName, String(index)); - /* self.log('itemsName'); - self.log(itemsName); - self.log('index'); - self.log(index); - self.log('item'); - self.log(item); */ - if (item.output && typeof item.output == 'object') { //} !== undefined) { - - /* self.log('item.for.output'); - self.log(item.for.output); */ - for (let key in item.output) { - - var output = item.output[key]; - if (typeof output == 'string') { - output = self.js(output, args); - } else if (typeof output == 'object') { - //output = self.compile(output, args); - output = self.replaceProperties(output, args); - } - - item = self.replaceItems(item, output, key); - //item = self.replaceProperty(item, key, output); - } - } - - // item = self.replaceItems(item, itemValue, itemsName); old version - //delete item.for; // needed to avoid infinite loop - if (item.do) { - params.do = self.replacePropertyWithPrefix(item.do, 'index:' + itemsName, index); - //params.do = self.replaceStringInObject(item.do, '{index:'+itemsName+'}', index); - self.do(item.do, selectorParams, args); // return? - - //self.do(item.do, args, selectorParams); // return? - } - if (item.html) { - //params.html = self.replaceStringInObject(item.html, '{index:'+itemsName+'}', index); - params.html = self.replacePropertyWithPrefix(item.html, 'index:' + itemsName, index); - self.html(item.html, selectorParams); - } - } - } - } else { - self.log('"for" element requires "value" or "from" and "to" parameters'); // link to see the documentation - self.log(params); - } - //} - // } - }; - - this.htmlTag = function (params, selectorParams, tagParam, mainParam) { - /* self.log('htmlTag'); - self.log(tagParam); */ - if (Array.isArray(params)) { - for (var index in params) - self.htmlTag(params[index], selectorParams, tagParam, mainParam); - } else { - - //---------------------------------- - // attributes of the tag in the key - // example: "div id=btn btn" - // (classes are without identifier) - //---------------------------------- - let htmlTagSplitter = tagParam.indexOf(' '); - if (htmlTagSplitter > 0) { - let tagClass = tagParam.substr(htmlTagSplitter + 1); - tagParam = tagParam.slice(0, htmlTagSplitter); - if (tagClass) { - if (typeof params !== 'object') params = { 'text': String(params) }; - if (!params.attr) params.attr = {}; - - // attributes in key: attribute=value - let tagArr = tagClass.split(' '); - var attrClass = ''; - for (let tagProp of tagArr) { - let tagAttr = new RegExp("([_a-zA-Z]+[_a-zA-Z0-9-]*)=(.+)"); // [_a-zA-Z0-9-/] - if (tagAttr.test(tagProp)) { - //console.log('attribute found '+tagProp); - let tagPropArr = tagProp.split('='); - params.attr[tagPropArr[0]] = tagPropArr[1]; - } else { - attrClass += ' ' + tagProp; - } - } - - // classes - if (params.attr.class) - params.attr.class = params.attr.class + attrClass; - else { - params.attr.class = attrClass; - } - //alert(tagParam + '/'+ tagClass+ '#'); - } - } - - let htmlTagObj = self.createTagParams(params, tagParam, mainParam); - - self.do(htmlTagObj, selectorParams); - - if (params.database) self.addFirebaseTag(self.extend({}, params, selectorParams)); - - } - }; - - this.createTagParams = function (params, tagParam, mainParam) { - if (!mainParam) { - switch (tagParam) { - case 'header': - case 'main': - case 'footer': - case 'div': - case 'p': - mainParam = 'html'; - break; - case 'img': - mainParam = 'src'; - break; - default: - mainParam = 'text'; // TO DO: -> html (to test with actual apps) - break; - } - } - var paramsObj = {}; - if (typeof params == 'string') paramsObj[mainParam] = params; else paramsObj = params; - paramsObj.tag = tagParam; - return paramsObj; - }; - - - - this.onResize = []; - this.onHashChange = []; - this.onScroll = []; - //let swup; - this.notEmptyObject = function (obj) { - return (obj // null and undefined check - && Object.keys(obj).length > 0); - // && Object.getPrototypeOf(obj) === Object.prototype - // https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object - }; - - this.run = function (params, selectorParams, args) { - /* self.log('run'); - self.log(params); */ - if (Array.isArray(params)) { - for (var index in params) - self.run(params[index], selectorParams, args); - } else { - - - var codeToRun; - if (typeof params == 'object') - codeToRun = self.cloneObject(params); - else if (typeof params == 'string') - codeToRun = self.replaceProperties(params); - else if (typeof params == 'function') - return params(args); - - else - return params; - - /* self.log('codeToRun'); - self.log(codeToRun); */ - if (typeof codeToRun == 'object') { - var selector = codeToRun.selector || codeToRun.container; - if (!selector) selector = selectorParams; - if (typeof selector == 'string') selector = { selector: selector }; - - - - var actions = {}; - for (key in codeToRun) { - - if (nodes.extend.indexOf(key) >= 0) { - var obj = {}; - obj[key] = codeToRun[key]; - self.extendJson(self.json, obj); - } else if (['setup', 'container', 'selector', 'resources', 'on', 'do'].indexOf(key) < 0) - actions[key] = codeToRun[key]; - } - - /* self.log('codeToRun.on'); - self.log(codeToRun.on); - - self.log('selector'); - self.log(selector); */ - // actions - //if (codeToRun.container) {self.empty(codeToRun.container);} // reset - // .in SIGNIFICA CONTENITORE (select) - if (codeToRun.on) { self.on(codeToRun.on, selector); } - if (codeToRun.do) { self.do(codeToRun.do, selector, args); } - - if (self.notEmptyObject(actions)) { - /* self.log('notEmptyObject actions'); - self.log(actions); - self.log('selector'); - self.log(selector); */ - return self.do(actions, selector, args); - //return self.do(actions, args, codeToRun.in); - } - } - } - - //self.extendJsonFromElement(codeToRun); // style, actions, texts, data, var. no setup, on, do, blocks, container - }; - /* - this.execute = function (params, selectorParams, args) { // obsolete - - // should create a new jsonicApp instance and assign it to jsonic[id] - // jsonicApp should load the plugins required and not are already loaded - // jsonicApp should import the json not already imported - // jsonicApp should load the icons not already loaded - - // jsonicApp should init the database if not already initialized - // otherwise should copy the db object from window.jsonic? - - // to have app relative var and data these should be called as var:clock.... / var:calendar.... - - // or each app should have an ID (without id the ID is "app") - - // to have exclusive setup, var, data/items, pages and to reset var on the second execution - // for example: window.jsonic['container'] = new jsonicObject(options); - self.log('execute'); - - if (params) { - - if (params.do == 'init') { - - self.log('init'); - window.removeEventListener('hashchange'); - window.removeEventListener('resize'); - window.removeEventListener('beforeinstallprompt'); - - // PWA - if ('serviceWorker' in navigator) { - // Register a service worker hosted at the root of the - // site using the default scope. - navigator.serviceWorker.register('/app/assets/pwa/sw.js').then(function(registration) { - self.log('Service worker registration succeeded:', registration); - }, function(error) { - self.log('Service worker registration failed:', error); - }); - } else { - self.log('Service workers are not supported.'); - } - - let deferredPrompt; - - window.addEventListener('beforeinstallprompt', (e) => { - // Prevent Chrome 67 and earlier from automatically showing the prompt - e.preventDefault(); - // Stash the event so it can be triggered later. - deferredPrompt = e; - }); - - self.json.setup.page.hash = window.location.hash.substr(1); - - // we consider json.setup.modules instead of self.modules - // to be sure to follow the right order of execution - - var modules = []; // we need it to keep the order of the modules given in the setup - for (key in json.setup.modules) { - var mod = self.replaceProperties(json.setup.modules[key]); - modules = modules.concat(self.cloneObject(mod)); - } - - //modules.push({name: 'ide', url: 'https://jsonic.io/app/modules/ide.json'}); // TO DO if admin - // or can execute global before all the rest - // modules can contain {libs and apps} - // ide module can be loaded only if required - - for (var mod of modules) { - //self.log(mod.name); - var params = self.modules[mod.name]; - //self.log(params); - - if (params.html) { - - var container = selectorParams || 'body'; - - //if (params.app.html) { - - //var documentTitle = self.json.setup.title; - //if (documentTitle) - // document.title = documentTitle; - //if (document.querySelector('meta[name="description"]')) - // document.querySelector('meta[name="description"]').setAttribute("content", documentDescription); - - self.html(params.html, {container: container}); - - // window events - - //} - } - - if (params.on) { // -> this.on - - // hashchange - - if (params.on.hashchange) { - self.onHashChange.push(params.on.hashchange); - window.addEventListener('hashchange', function() { - self.json.setup.page.hash = window.location.hash.substr(1); // potrebbe essere esplicitato sulla app - //var action = self.cloneObject(params.app.on.hashchange); - //self.replaceAll("{result}", window.location.hash); - self.do(self.onHashChange); - self.uiUpdate(); - }); - } - - // resize - - window.addEventListener('resize', self.resizeEvent); - if (params.on.resize) { - self.onResize.push(params.on.resize); - window.addEventListener('resize', function () { - self.do(self.onResize); - }); - } - - - // receiveMessage - - if (params.on.thunkable && params.on.thunkable.receiveMessage) - window.receiveMessage(function (message) { - //document.querySelector('#message').value = message; - jsonic.functions(params.on.thunkable.receiveMessage, message, undefined); - }); - - - self.on(params.on, {container: container}); // init included - } - - //else - //self.log('The node "app" requires "container" and "html" properties'); - } - - - } else { - - //if (params.setup) args = self.extend(args, params.setup); // or params.args? - if (params.blocks) self.extendJson(json, {blocks: params.blocks}); - //if (params.library) self.extendJson(json, {library: params.library}); // obsolete - if (params.media) self.extendJson(json, {media: params.media}); // obsolete - if (params.functions) self.extendJson(json, {functions: params.functions}); // obsolete - if (params.actions) self.extendJson(json, {actions: params.actions}); - if (params.css) self.extendJson(json, {css: params.css}); - //if (params.styles) self.extendJson(json, {styles: params.styles}); - //if (params.iconset) self.extendJson(json, {iconset: params.iconset}); - if (params.data) self.extendJson(json, {data: params.data}); - if (params.items) self.extendJson(json, {items: params.items}); - if (params.var) self.extendJson(json, {var: params.var}); - - if (params.html) { - var container = selectorParams || 'body'; // is an object - if (typeof container == 'string') - container = {container: container}; - - - //if (self.inputValue({id: 'module'}) == 'base') { - // icons will be obsolete - - //} else { - //var setup = extendParams.setup || params.setup; - //if (container || html.container) { - - - //if (params.app.html) { - var code = self.cloneObject(params.html); - //self.log('code'); - //self.log(code); - //self.log(JSON.stringify(code)); - - self.html(code, container); - //} - //} else { - // self.log('execute method requires container parameter'); - //} - - if (params.on && params.on.init) { - self.do(params.on.init, undefined, container); - } - // args can be params.setup - //} - } else if (params.module) { - var moduleId = self.replaceProperties(params.module); - return self.do(self.modules[moduleId]); - } - - - } - - } - } */ - /* this.createApp = function (data) { - self.log('createApp'); - //self.log(self.modules); - - let deferredPrompt; - - window.addEventListener('beforeinstallprompt', (e) => { - // Prevent Chrome 67 and earlier from automatically showing the prompt - e.preventDefault(); - // Stash the event so it can be triggered later. - deferredPrompt = e; - }); - - self.json.setup.page.hash = window.location.hash.substr(1); - - for (var file in self.modules) { - var params = self.modules[file]; - - //if (params.on) self.extendJson(json, {media: params.media}); - // if (params.icons) self.extendJson(json, {icons: params.icons}); - //if (params.functions) self.extendJson(json, {functions: params.functions}); - //if (params.styles) self.extendJson(json, {styles: params.styles}); - //if (params.items) self.extendJson(json, {items: params.items}); - //if (params.var) self.extendJson(json, {var: params.var}); - //if (params.library) self.extendJson(json, {library: params.library}); - - if (params.app && params.app.container) { - - //var documentTitle = self.json.setup.title; - //if (documentTitle) - // document.title = documentTitle; - //if (document.querySelector('meta[name="description"]')) - // document.querySelector('meta[name="description"]').setAttribute("content", documentDescription); - - //alert(document.querySelector(params.app.container).isConnected); - self.html(params.app.html, {container: params.app.container}); - - // window events - - if (params.app.on) { // -> this.on - - // hashchange - - if (params.app.on.hashchange) { - self.onHashChange.push(params.app.on.hashchange); - window.addEventListener('hashchange', function() { - self.json.setup.page.hash = window.location.hash.substr(1); // potrebbe essere esplicitato sulla app - //var action = self.cloneObject(params.app.on.hashchange); - //self.replaceAll("{result}", window.location.hash); - self.do(self.onHashChange); - self.uiUpdate(); - }); - } - - // resize - - window.addEventListener('resize', self.resizeEvent); - if (params.app.on.resize) { - self.onResize.push(params.app.on.resize); - window.addEventListener('resize', function () { - self.do(self.onResize); - }); - } - - // receiveMessage - - if (params.app.on.thunkable && params.app.on.thunkable.receiveMessage) - window.receiveMessage(function (message) { - //document.querySelector('#message').value = message; - jsonic.functions(params.app.on.thunkable.receiveMessage, message, undefined); - }); - - // init - self.log('params.app.on'); - self.log(params.app.on); - self.log('params.app.container'); - self.log(params.app.container); - - self.on(params.app.on, {container: params.app.container}); - } - - } - //else - //self.log('The node "app" requires the "container" property'); - } - - - if (self.pluginsLoaded['swup'] && self.json.setup.swup) { - let swup = new Swup(self.json.setup.swup); - } - - - self.do(data); - } */ - /* this.menuToggle = function () { - self.log('menuToggle'); - //$('.offcanvas-collapse').toggleClass('open'); - $('#header').toggleClass('headerMenuOpen'); - var.menuOpen = (!var.menuOpen); - self.log(var.menuOpen); - } - - this.menuOpen = function () { - self.log('menuOpen'); - $('#menu').addClass('menuOpen'); - var.menuOpen = true; - self.log(var.menuOpen); - } - - this.menuClose = function () { - self.log('menuClose'); - $('#menu').removeClass('menuOpen'); - var.menuOpen = false; - self.log(var.menuOpen); - } */ - /* this.createMenu = function (data) { - self.log('createMenu'); - // self.userRole - var menuId = (typeof data.id == 'function') ? data.id() : data.id; - var container = data.container || '#header > ul'; - $(container).empty(); - - for (var index in self.json.menu[menuId]) { - var selector = container + ' > li:eq(' + index + ')'; // > span'; - var item = self.json.menu[menuId][index]; - // action - //if (item.page && !item.action) item.action = {page: item.page}; - if (!var.functions[container]) - var.functions[container] = {}; - var.functions[container][index] = item; - - $(container).append('
    • '); - item.color = item.color || 'inherit'; - item.background = item.background || 'transparent'; - item.border = item.border || 'transparent'; - - self.tab(item, {container: selector}); - - } - self.do(data); - } */ - /* this.changeMenu = function (menuId) { - } - */ - /* this.form = function (params, selectorParams) { - // replaceProperties può essere passato all'inizio di ogni costruttore - //params.container = params.container || self.selector(selectorParams); - //var selector = self.selector(params); - var container = params.container || self.selector(selectorParams); - //var elementContainer = self.query(container); - //var selector = self.selector(self.extend({}, params, selectorParams)); - //var element = self.query(selector); - - //params.tag = 'form'; - //if (params.id === undefined) {params.id = '';} - //if (params.value === undefined) {params.value = ''}; - //if (params.class === undefined) {params.class = ''}; - - //$(container).append('<'+params.tag+' id="'+params.id+'" class="'+params.class+'" data-value="'+params.value+'" data-selector="'+selector+'">'); - for (var itemKey in params.items) { - var item = params.items[itemKey]; - - self.html({ - "form": { - "attr": { - "id": params.id, - "class": params.class, - "data-value": params.data-value || params.value - }, - "div": [ - { - "attr": { - "class": "form-group", - "data-value": itemKey - }, - "html": [ - { - "label": { - "attr": { - "for": itemKey, - "text": item.title - } - } - }, - { - "input": { - "attr": { - "id": itemKey, - "class": "form-control", - "data-value": "formInput" + itemKey, - "value": item.inputValue, - "type": item.type, - "text": item.title, - "aria-describedby": "note"+itemKey, - "placeholder": "", - "disabled": disabled - } - } - }, - { - "small": { - "attr": { - "class": "form-text text-muted", - "data-value": "formNote"+itemKey, - "text": item.note - } - } - }, - ] - } - ] - } - }, { - container: container - }); - - } - - } */ - /* this.addList = function (params, selectorParams) { - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - if (params.id === undefined) {params.id = '';} - if (params.value === undefined) {params.value = ''}; - if (params.class === undefined) {params.class = ''}; - $(container).append('
        '); - - self.list(params, {container: container}); - - } */ - /* - this.addBlock = function (params, selectorParams) { - - if (params.icons) self.icons(params.icons, selectorParams); - if (params.tab) self.tab(params.tab, selectorParams); - if (params.html) self.html(params.html, selectorParams); - if (params.div) self.div(params.div, selectorParams); - if (params.ul) self.ul(params.ul, selectorParams); - if (params.li) self.li(params.li, selectorParams); - if (params.span) self.span(params.span, selectorParams); - if (params.img) self.img(params.img, selectorParams); - if (params.form) self.form(params.form, selectorParams); - if (params.list) self.addList(params.list, selectorParams); - //if (params.img) alert(JSON.stringify(params.img.src)); - } - */ - /* this.blocks = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.blocks(params[index], selectorParams, args); - } else { - if (typeof params == 'string') { - var blocksObj = self.get('self.json.library.'+params); - if (blocksObj) - self.blocks(blocksObj.blocks, selectorParams); - } else { - if (params.library) { - self.library(params.library, selectorParams, args); // {container: container} - } else { - self.addTag(params, selectorParams, args); // {container: container} - } - } - } - } - */ - this.inputValue = function (params) { - var selector = self.selector(params.selector || params.container); - var element = document.querySelector(selector); // self.query(p2); - return element.value; - }; - - - /* this.layout = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.layout(params[index], selectorParams, args); - } else { - if (typeof params == 'string') { - var libraryObj = self.get('self.json.layouts.'+params); // todo: get? - //var libraryHtml = libraryObj.html || libraryObj.blocks; - if (libraryObj) - self.layout(libraryObj, selectorParams, args); // TODO warning potential infinite loop (if string) - else - self.log('"theme" not found: ' + params); - } else { - var libraryHtml = params.html; - // can a library component be an object? - if (params.setup) args = self.extend(args, params.setup); // or params.args? - if (params.functions) self.extendJson(json, {functions: params.functions}); - if (params.css) self.extendJson(json, {css: params.css}); - //if (params.styles) self.extendJson(json, {styles: params.styles}); - if (params.items) self.extendJson(json, {items: params.items}); - if (params.var) self.extendJson(json, {var: params.var}); - self.html(libraryHtml, selectorParams, args); // {container: container} - //self.(params, selectorParams, args); - } - } - } */ - this.part = this.block = function (params, selectorParams, args) { - - let nested; - let part; - let partArguments; - - if (typeof params.do == 'string' && self.json.parts) { // && par.match(/[.>]+/)) - - self.log('PART: ' + params.do, 'brown'); - - params.do = self.replaceProperties(params.do); - - if (typeof params.do == 'object') - part = params.do; - - else - part = self.element({ path: self.replaceAll(params.do, ':', '.'), root: self.json.parts }); // TO DO: . -> space? - - - - /* if (par.indexOf(':')>0 && !part) { - self.firebaseGetPart({localPath:localPath, container: params.selector, arg:params.obj}); - } */ - } else if (typeof params.do == 'object') - part = params.do; - - if (part) { - //if (!params.arguments) params.arguments = {}; - // TO DO: Check this. seems a workaround for fantacards/ui:qrcode - if (params.arguments) - partArguments = self.replaceProperties(params.arguments); - - if (typeof params.arguments == 'object') { - partArguments = (params.arguments.setup) ? params.arguments.setup : params.arguments; // compatibility - partArguments.selector = partArguments.selector || params.selector; - } - - nested = self.replacePropertyWithPrefix(part, 'setup', partArguments); // {setup} -> {arguments} - nested = self.replacePropertyWithPrefix(nested, 'arguments', partArguments); // to tix - - self.extendJsonFromElement(nested); - self.do(nested, params.selector, partArguments); - } - }; - - this.blocks = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.blocks(params[index], selectorParams, args); - } else { - //self.log('blocks'); - //self.log(params); - if (typeof params == 'string') { - - var blockName = self.replaceProperties(params, args); // self.compile(params, args); - - - - //self.log('blockName'); - //self.log(blockName); - var libraryObj = self.element({ path: 'self.json.blocks.' + blockName }); // todo: get? - - - - - - //self.log('libraryObj'); - //self.log(libraryObj); - //var libraryHtml = libraryObj.html || libraryObj.blocks; - if (libraryObj) - //self.html(libraryObj, selectorParams, args); - self.run(libraryObj, selectorParams, args); - - - //self.blocks(libraryObj, selectorParams, args); // TODO warning potential infinite loop (if string) - else - self.log('library component not found: ' + params); - } else { - self.run(params, selectorParams, args); - //self.run(params, selectorParams, args); - //var libraryHtml = params.html || params.app.html; - /* // can a library component be an object? - if (params.setup) args = self.extend(args, params.setup); // or params.args? - if (params.parts) self.extendJson(json, {parts: params.parts}); - if (params.actions) self.extendJson(json, {actions: params.actions}); - if (params.css) self.extendJson(json, {css: params.css}); - if (params.data) self.extendJson(json, {data: params.data}); - if (params.var) self.extendJson(json, {var: params.var}); - if (params.texts) self.extendJson(json, {texts: params.texts}); - - self.html(params.html, selectorParams, args); // {container: container} - //self.do(params, selectorParams, args); */ - } - } - }; - - this.uiUpdate = function (option) { - window.dispatchEvent(new Event('resize')); // workaround known ACE bug - - //self.updateCodeEditors(); // workaround known ACE bug - }; - - this.resizeEvent = function (event) { - //self.log('resizeEvent'); - for (var selector in self.resizeActions) { - var element = self.query(selector); - for (var property in self.resizeActions[selector]) { - if (property == 'action') { - self.do(self.resizeActions[element].action, { selector: selector }); - //self.do(self.resizeActions[element].action, {selector: selector}); - } else { - var value = self.resizeActions[selector][property]; - var result = self.replaceProperties(value) || ''; - //$(selector).css(property, result); - element.style[property] = result; - } - } - } - }; - - - - /* var pages = {}; - var pagesSlider; - - this.createPages = function (data) { - self.log('createPages'); - - //backLink = (self.json.setup && self.json.setup.home && self.json.setup.home[var.mode]) ? self.json.setup.home[var.mode] : ''; - // class="container-fluid px-0" style="margin-top:'+self.json.setup.main.top+'" - - var pageContainer = '#pages'; // 'main > div' - - for (var pageKey in self.json.pages) { - params = self.json.pages[pageKey]; - var pageRoles = (params.roles) ? String(params.roles).split(',') : undefined; - - // se il ruolo dell'utente permette la vista della pagina e se non è stata già creata - if (!params.roles || (pageRoles.indexOf(self.userRole()) >= 0 && document.querySelectorAll('#'+pageKey).length == 0)) { // $('#'+pageKey).length == '#'+pageKey doesn't exist - - //if (params.preload) { - - params.tag = 'div'; - //params.id = pageKey; - params.class = 'page'; - params.value = pageKey; - - // the previous definition should be in layout.page - - self.addTag(params, {container: pageContainer}); - //} - - - } else { - self.log('' + self.userRole() + ' users can\'t access to the page '+pageKey); - } - } - - self.do(data); - } */ - this.pageFullScreen = function (onOff) { - self.log('pageFullScreen'); - if (onOff) - self.addClass(document.querySelector('body'), 'fullscreen'); - - else - self.removeClass(document.querySelector('body'), 'fullscreen'); - }; - - //var backLink = 'stage'; - /* this.pageBack = function () { - self.gotoPage(backLink); - //window.location.href = '?p='+backLink; - //$('body').removeClass('nav-open'); // chiude menu - } */ - this.link = function (link, args) { - /* function link() { - [native code] - } */ - //alert(link); - link = self.replaceProperties(link, args); - window.location.href = link; - }; - - this.reload = function () { - location.reload(); - }; - - this.gotoHomePage = function () { - self.gotoPage(self.homePage()); - }; - - this.homePage = function () { - //alert('homePage'); - if (self.json.pages) { - if (Object.keys(self.json.pages).length > 0) { - //var homeKey = Object.keys(self.json.pages).find(key => self.json.pages[key] === 'home'); - if (self.json.pages.home) - return 'home'; - - else - return Object.keys(self.json.pages)[0]; - } else { - self.log('No pages in "pages" node'); - } - } else { - self.log('Can\'t find the "pages" node'); - } - }; - - /* this.activePage = function () { // to check if obsolete - return var.page; - } */ - /* this.slideIndex = function (id) { - return $('#'+id).index()+1; - } */ - /* this.slideTo = function (params) { - if (pagesSlider) pagesSlider.goTo(self.slideIndex(params.id)); - $('#pages > .seq-canvas > .seq-in').addClass(params.transition); - } */ - this.updateCodeEditors = function () { - // workaround known ACE bug: - // setValue doesn't work if editor is hidden - // http://jsfiddle.net/e4r7byLn/ - var elements = document.querySelectorAll('.ace_editor'); - if (elements) { - elements.forEach(function (element, index) { - var editor = ace.edit(element); - editor.renderer.updateFull(true); - //AceColorPicker.load(ace, editor); - //AceColorPicker.load(ace, editor); // works after some ms - }); - } - }; - - this.gotoPage = function (pageId, fromHash) { - self.log('page'); // changePage - self.log('pageId'); - self.log(pageId); - self.log('fromHash'); - self.log(fromHash); - //self.log("var.page"); - //self.log(var.page); - if (pageId) { - - if (self.json.pages) { - if (self.json.pages[pageId]) { - var page = self.json.pages[pageId]; - - if (pageId !== self.json.setup.page.id || fromHash !== self.json.setup.page.hash) { - - if (fromHash) { - //var.pagePath = fromHash; // obsolete - self.json.setup.page.hash = fromHash; - } else { - //delete var.pagePath; - delete self.json.setup.page.hash; - } - - //var.page = pageId; // activePage - //var newHash = pageId; - //if (!fromHash) window.location.hash = newHash; - var fullScreen = self.json.pages[pageId].fullscreen || false; - //self.pageFullScreen(fullScreen); - var pageRoles = (page.roles) ? String(page.roles).split(',') : undefined; - - if (self.params.d || !page.roles || pageRoles.indexOf(self.userRole()) >= 0) { - - if (pageId !== self.json.setup.page.id) { - - /* self.out({ - "class": "page", - "data-value": self.json.setup.page.id, - "transition": "fadeOutLeft" - }); */ - self.json.setup.page.id = pageId; - self.json.setup.page.title = page.title; - self.json.setup.page.roles = page.roles; - - /* // TO DO: don't change document title and description - - // window title - var documentTitle = self.json.setup.title; - if (page.title) - documentTitle += ' ' + self.text(page.title); - var documentDescription = self.json.setup.description || ''; - if (documentTitle) - document.title = documentTitle; - if (document.querySelector('meta[name="description"]')) - document.querySelector('meta[name="description"]').setAttribute("content", documentDescription); */ - //$('title').text(windowTitle); - // change page - self.hide({ - "class": "page" - }); - self.in({ - "class": "page", - "data-value": pageId, - "transition": "fadeIn" - }); - - /* $('.page').hide(); - $('.page[data-value='+pageId+']').fadeIn(); */ - //self.resizeEvent(); - self.uiUpdate(); // resize event trigger - - - - - - - - - - /* // page back icon - if (page.back) { - backLink = page.back; - $('#headerLeftIcons').show((page.back)); - } else { - $('#headerLeftIcons').hide(); - } */ - } - - if (page.update) { // obsolete - self.do(page.update); //, {container: '.page[data-value='+pageId+']'}); - - //self.do(page.update); //, {container: '.page[data-value='+pageId+']'}); - } - - if (page.init) self.do(page.init); - - self.log(page); - if (page.on) - self.on(page.on, { selector: '.page[data-value=' + pageId + ']' }); - - //$('body').removeClass('nav-open'); // chiude menu - //$('.offcanvas-collapse').removeClass('open'); - } else { - if (self.userRole() == 'guest') { - /* self.do({ - "login": { - "success": { - "reload": true - } - } - }); */ - } else { - self.alert('Non hai i privilegi per accedere a questa pagina'); - } - - } - } else { - // pagina non trovata - } - } else { - self.log('Can\'t find the page "' + pageId + '"'); - } - } else { - self.log('Can\'t find the main node "pages"'); - } - } else { - return self.json.setup.page; - } - }; - - var alertInterval; - - this.getTime = function (ms) { - var sec = parseInt(ms / 1000); - var min = parseInt(sec / 60); - sec = sec - min * 60; - if (min < 10) min = '0' + min; - if (sec < 10) sec = '0' + sec; - return min + ':' + sec; - }; - - this.sortablejs = function (params, selectorParams, args) { - let container = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - let query = self.query(container); - self.log('container'); - self.log(container); - self.log('query'); - self.log(query); - var sortable = Sortable.create(query); - }; - - this.alert = function (params, args) { - /* self.log('alert'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - var paramsReplaced = self.cloneObject(params); - - //paramsReplaced = self.replaceProperties(paramsReplaced, args); - //self.log('paramsReplaced'); - //self.log(paramsReplaced); - if (paramsReplaced) { - if (paramsReplaced.do && paramsReplaced.do !== 'fire') { - return Swal[paramsReplaced.do](params); - // more info on https://sweetalert2.github.io/#methods - } else { - if (typeof paramsReplaced == 'string') paramsReplaced = self.text({ string: paramsReplaced, args: args }); // verify - - - - //self.log('paramsReplaced string replaced'); - //self.log(paramsReplaced); - if (typeof paramsReplaced == 'number') paramsReplaced = String(paramsReplaced); // avoid bug - if (paramsReplaced.title !== undefined) paramsReplaced.title = self.text({ string: paramsReplaced.title, args: args }); - - //self.log('paramsReplaced2'); - //self.log(paramsReplaced); - if (paramsReplaced.html && typeof paramsReplaced.html == 'string') paramsReplaced.html = self.replaceProperties(paramsReplaced.html, args); - if (paramsReplaced.text !== undefined) paramsReplaced.text = self.text({ string: paramsReplaced.text, args: args }); - //self.log('paramsReplaced string replaced 2'); - if (paramsReplaced.inputValue) paramsReplaced.inputValue = self.text({ string: paramsReplaced.inputValue, args: args }); - - //if (paramsReplaced.html) paramsReplaced.html = self.text({string: paramsReplaced.html, args: args}); // verify - if (paramsReplaced.cancelButtonText) paramsReplaced.cancelButtonText = self.text({ string: paramsReplaced.cancelButtonText, args: args }); - if (paramsReplaced.confirmButtonText) paramsReplaced.confirmButtonText = self.text({ string: paramsReplaced.confirmButtonText, args: args }); - if (paramsReplaced.denyButtonText) paramsReplaced.denyButtonText = self.text({ string: paramsReplaced.denyButtonText, args: args }); - //if (paramsReplaced.showConfirmButton) paramsReplaced.showConfirmButton = self.text({string: paramsReplaced.showConfirmButton, args: args}); - if (paramsReplaced.inputPlaceholder) paramsReplaced.inputPlaceholder = self.text({ string: paramsReplaced.inputPlaceholder, args: args }); - if (paramsReplaced.validationMessage) paramsReplaced.validationMessage = self.text({ string: paramsReplaced.validationMessage, args: args }); - //if (paramsReplaced.inputOptions) paramsReplaced.inputOptions = self.text({string: paramsReplaced.inputOptions, args: args}); - if (paramsReplaced.footer) { - paramsReplaced.footer = self.text({ string: paramsReplaced.footer, args: args }); - } - - //if (paramsReplaced.upload) alert('paramsReplaced.upload: '+paramsReplaced.upload); - if (paramsReplaced.upload) { - paramsReplaced.html = '
        ' + self.text('dragAndDropFiles') + '
        ' + self.text('chooseFiles') + '
        '; - // - //if (paramsReplaced.onUpload) var.onUpload = paramsReplaced.onUpload; - //var.uploadingTarget = paramsReplaced.uploadingTarget; - } - - //self.log('paramsReplaced3'); - //self.log(paramsReplaced); - alertObj.confirm = paramsReplaced.confirm; // deprecated - alertObj.cancel = paramsReplaced.cancel; // deprecated - alertObj.deny = paramsReplaced.deny; // deprecated - alertObj.on = paramsReplaced.on; - alertObj.id = paramsReplaced.id; - delete paramsReplaced.on; - - - - var alertHtml = paramsReplaced.html || paramsReplaced.blocks; - if (alertHtml) - paramsReplaced.html = " "; - - var swalParams = self.replaceProperties(paramsReplaced, args); - - // animate - if (paramsReplaced.animate) { - var animationIn = paramsReplaced.animate.in || paramsReplaced.animate; - var animationOut = paramsReplaced.animate.out || paramsReplaced.animate; - if (paramsReplaced.animate.in) - animationIn = paramsReplaced.animate.in.transition || paramsReplaced.animate.in; - if (paramsReplaced.animate.out) - animationOut = paramsReplaced.animate.out.transition || paramsReplaced.animate.out; - swalParams.showClass = { - popup: 'animate__animated animate__faster animate__animated animate__' + animationIn - }; - swalParams.hideClass = { - popup: 'animate__animated animate__faster animate__animated animate__' + animationOut - }; - } - - var customIcon; - if (swalParams.icon) { - //swalParams.icon = self.replaceProperties(swalParams.icon, args); - if (typeof swalParams.icon !== 'string') { - customIcon = self.cloneObject(swalParams.icon); - delete swalParams.icon; - } - /* var swalIcons = []; //"warning", "error", "success", "info", "question"]; - if (swalIcons.indexOf(params.icon)<0) { - customIcon = params.icon; - - //if (!params.customClass) params.customClass = {}; - //params.customClass.icon = "customIcon"; - } */ - } - - - - //if (swalParams.showConfirmButton) delete swalParams.showConfirmButton; - // swalParams.update = function() { - // self.log('swalParams.update'); - // self.log(var.updateSwal); - // } - // onRender is obsolete - /* swalParams.onRender = function () { - startUploadListeners({ - container: '.drop-zone', - onUpload: params.onUpload, - path: params.path - //uploadingTarget: var.uploadingTarget - //onError: - }); - } -*/ - delete swalParams.blocks; - delete swalParams.onUpload; - delete swalParams.upload; - - if (swalParams.confirm) delete swalParams.confirm; - if (swalParams.cancel) delete swalParams.cancel; - if (swalParams.timerProgressBar) { - swalParams.onBeforeOpen = function () { - //Swal.showLoading(); // rimuove i bottoni - alertInterval = setInterval(() => { - const content = Swal.getContent(); - if (content) { - const b = content.querySelector('b'); - if (b) { - b.textContent = self.getTime(Swal.getTimerLeft()); - } - } - }, 100); - }; - swalParams.onClose = function () { - clearInterval(alertInterval); - }; - } - - //self.log('swalParams'); - //self.log(swalParams); - Swal.fire(swalParams).then((result) => { - //self.log('alert result'); - //self.log(result); - // TO DO: if (!result) result = {} to avoid errors - var alertResult = result.value; - - if (alertObj.on) { - if (alertObj.on.value && result.value) { - //if (alertObj.id) alertObj.values[alertObj.id] = result.value; - if (alertObj.id) alertValues[alertObj.id] = result.value; - alertValues.value = result.value; - setTimeout(function () { - alertObj.on.value = self.replacePropertyWithPrefix(alertObj.on.value, 'alert', alertValues); - //alertObj.on.value = self.replaceProperty(alertObj.on.value, 'alert', result); - self.do(alertObj.on.value, undefined, result.value); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.value, result.value); // TO DO: remove result.value once removed all {result} - }, 500); - } - if (alertObj.on.isConfirmed && result.isConfirmed) { - if (alertObj.id) alertValues[alertObj.id] = result.isConfirmed; - alertObj.on.isConfirmed = self.replacePropertyWithPrefix(alertObj.on.isConfirmed, 'alert', alertValues); - alertObj.on.isConfirmed = self.replacePropertyWithPrefix(alertObj.on.isConfirmed, 'alert', result); - self.do(alertObj.on.isConfirmed, undefined, result.value); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.isConfirmed, result.value); // TO DO: remove result.value once removed all {result} - } - if (alertObj.on.isDenied && result.isDenied) { - alertObj.on.isDenied = self.replacePropertyWithPrefix(alertObj.on.isDenied, 'alert', result); - self.do(alertObj.on.isDenied, undefined, result.value); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.isDenied, result.value); // TO DO: remove result.value once removed all {result} - } - if (alertObj.on.isDismissed && result.isDismissed) { - alertObj.on.isDismissed = self.replacePropertyWithPrefix(alertObj.on.isDismissed, 'alert', result); - self.do(alertObj.on.isDismissed, undefined, result.dismiss); // TO DO: remove result.value once removed all {result} - - //self.do(alertObj.on.isDismissed, result.dismiss); // TO DO: remove result.value once removed all {result} - } - - console.log('alertValues'); - console.log(alertValues); - - - } else { - /* if (result.isConfirmed) { - self.do(alertObj.confirm, result.value); - } else if (result.isDenied) { - self.do(alertObj.deny, result.value); - } else if (result.dismiss === Swal.DismissReason.cancel) { - self.do(alertObj.cancel, result.value); - } else if (result.dismiss === Swal.DismissReason.timer) { - self.log('Alert closed by the timer'); - } */ - } - - /* - - Reason Description Related configuration - Swal.DismissReason.backdrop The user clicked the backdrop. allowOutsideClick - Swal.DismissReason.cancel The user clicked the cancel button. showCancelButton - Swal.DismissReason.close The user clicked the close button. showCloseButton - Swal.DismissReason.esc The user clicked the Esc key. allowEscapeKey - Swal.DismissReason.timer The timer ran out, and the alert closed automatically. timer - - */ - }); - - if (alertHtml) - self.do(alertHtml, { selector: '#swal2-html-container' }); - - //self.log('customIcon'); - //self.log(customIcon); - if (customIcon) { - /* self.icons({ - "class": "icon", - "svg": customIcon - }, {container: '.swal2-icon'}); */ - self.do(customIcon, { selector: '.swal2-icon' }); - //self.addTag(customIcon, {container: '.swal2-icon'}); // check - self.css({ - selector: '.swal2-icon', - style: { - 'border': '0px solid transparent' - } - }); - self.show({ - selector: '.swal2-icon' - }); - /* $('.swal2-icon').css({ - 'border': '0px solid transparent' - }); - $('.swal2-icon').show(); */ - } - - if (swalParams.on && swalParams.on.init) // to be repeated in each function - self.do(swalParams.on.init); - //self.do(swalParams.on.init); - } - } - }; - - /* var startUploadListeners = function (params) { // da FIXO - self.log('startUploadListeners'); - var.upload = params; - var obj = $(params.container); - self.log(params); - obj.on('dragenter', function (e) { - e.stopPropagation(); - e.preventDefault(); - $(this).css('border', '2px solid #0B85A1'); - }); - obj.on('dragover', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); - - $(document).on('dragenter', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); - $(document).on('dragover', function (e) { - e.stopPropagation(); - e.preventDefault(); - obj.css('border', '2px dotted #0B85A1'); - }); - $(document).on('drop', function (e) { - e.stopPropagation(); - e.preventDefault(); - }); - // automatically submit the form on file select - - obj.on('drop', function (e) { - $(this).css('border', '2px dotted #0B85A1'); - e.preventDefault(); - var files = e.originalEvent.dataTransfer.files; - - //We need to send dropped files to firebase - handleFileUpload(files); - }); - $(params.container+'-file').on('change', function (e) { - var files = $(params.container+'-file')[0].files; - self.log(params.container+'-file'); - self.log(files) - handleFileUpload(files); - }); - - } */ - /* this.uploadFileNameAndType = function(params){ - self.log('uploadFileNameAndType'); - self.log(params); - - var fileArr = params.fileName.split('.'); - var.upload.fileName = params; - var.upload.fileType = fileArr[1].toLowerCase(); - if (!$('.swal2-act').length) $('.swal2-modal').append('
        '); - if (var.upload.fileType == 'ply') { - $('.swal2-act').css({'display':'none'}); - } else { - $('.swal2-act').css({'display':'block'}); - $('.swal2-act').append(''); - } - } */ - /* var handleFileUpload = function(files) { - self.log('handleFileUpload'); - self.log(files); - self.log('var.upload'); - self.log(var.upload); - //var auth0Id = fixo.getAuth0Id(); - // Swal.close(); // chiusura popup - for (var i = 0; i < files.length; i++) { - var fd = new FormData(); - fd.append('file', files[i]); - if (!files[i].name.endsWith('png')) var.upload.fileTimestamp = self.getTimestamp(); - - self.fireBaseUpload({ - 'file': files[i], //base64toBlob(files), - 'timestamp': var.upload.fileTimestamp, - 'path': var.user.uid+'/' || '' //auth0Id+'/files/images' //path_to_where_you_to_store_the_file - }, function (data) { - self.log('data'); - self.log(data); - if (!data.error) { - //if (data.progress && data.progress == 0) $('.swal2-actions').append(''); - if (data.progress >= 0 && data.progress <= 100) { - //progress update to view here - // self.log('Uploading file'); - // self.log(var.uploadingTarget); - $('#msgFooter').html(''+data.progress+'%') - } - if (data.progress == 100) { - //$(var.uploadingTarget).removeClass('pulseFade'); - // Swal.close(); - - if (data.fileExt !== 'png'){ - self.log('diverso da png'); - $('.drop-zone-file').attr('accept','.png'); - var.upload.data = data; - } - - if (var.upload.onUpload) self.do(var.upload.onUpload, data); - } - } else { - //$(var.uploadingTarget).removeClass('pulseFade'); - self.log(data.error + ' Firebase image upload error'); - } - }); - } - }; */ - /* var uploadDone = function (data) { - self.log('uploadDone'); - // download URL here "data.downloadURL" - var auth0Id = fixo.getAuth0Id(); - var storageRef = firebase.storage().ref(); - var imageRef = storageRef.child(auth0Id+'/files/images/'+data.fileName); - // Get the download URL - imageRef.getDownloadURL().then(function(url) { - self.do(var.onUpload, url); - // Insert url into an tag to "download" - }).catch(function(error) { - self.log(error.code); - // A full list of error codes is available at - // https://firebase.google.com/docs/storage/web/handle-errors - - switch (error.code) { - case 'storage/object_not_found': - // File doesn't exist - break; - - case 'storage/unauthorized': - // User doesn't have permission to access the object - break; - - case 'storage/canceled': - // User canceled the upload - break; - - case 'storage/unknown': - // Unknown error occurred, inspect the server response - break; - } - }); - } */ - this.findKey = function (obj, key) { - return obj.filter(function (item) { - return Boolean(item[key]); - }); - }; - - /* this.fireBaseUpload = function(parameters, callBackData) { - self.log('fireBaseUpload'); - self.log('parameters'); - self.log(parameters); - - // Get a reference to the storage service, which is used to create references in your storage bucket - var storageRef = firebase.storage().ref(); - - - var file = parameters.file; - var path = parameters.path; - var timestamp = parameters.timestamp; - //var path = var.user.uid; // non riesco a passare la path come parametro da olo.app.json così come l'errore funzione onUpload - - - self.log('file'); - self.log(file); - self.log('timestamp'); - self.log(timestamp); - self.log('path'); - self.log(path); - - //Riga originale pre-modifica nome file - // var fullPath = path + '/' + file.name; - - // expected parameters to start storage upload - var metaData = {'contentType': file.type}; - var fileSize = formatBytes(file.size); // get clean file size - var fileType = file.type; - var fileName = file.name; - var fileExt = fileName.split('.')[1]; - - self.log(metaData); - self.log(fileSize); - self.log(fileType); - self.log(fileName); - self.log(fileExt); - var modFileName = timestamp+'.'+fileExt; - - //var fullFilePath = storageRef.child(path+timestamp+'-'+fileName); - var fullFilePath = storageRef.child(path+modFileName); - self.log('fullFilePath'); - self.log(fullFilePath); - - var nm = fileName.split('.'); - var name = nm[0]; - - self.log('nm'); - self.log(nm); - self.log('name'); - self.log(name); - - - - // Modifica file name generato - // var name = generateRandomString(16); //(location function below) - // var n = name+'.'+file.type.replace('image/',''); - // var fullPath = path + '/' + n; - - - //Riga originale pre-modifica nome file - // var n = file.name; - - - // generate random string to identify each upload instance - //name = generateRandomString(12); //(location function below) - - // var uploadFile = storageRef.child(parameters.path).put(file, metaData); - var uploadFile = fullFilePath.put(file, metaData); - - // first instance identifier - //callBackData({id: name, fileSize: fileSize, fileType: fileType, fileName: n}); 20200724 - callBackData({id: timestamp.toString(), fileSize: fileSize, fileType: fileType, fileName: modFileName, fileExt: fileExt}); // fileName: fileName //id: name - - uploadFile.on('state_changed', function (snapshot) { - var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; - progress = Math.floor(progress); - self.log('progress'); - self.log(progress); - callBackData({ - progress: progress, - element: timestamp.toString(), - //element: name, - fileSize: fileSize, - fileType: fileType, - fileName: modFileName, - fileExt: fileExt}); - //fileName: fileName - }, function (error) { - callBackData({error: error}); - }, function () { - var downloadURL = uploadFile.snapshot.downloadURL; - callBackData({ - downloadURL: downloadURL, - element: timestamp.toString(), - //element: name, - fileSize: fileSize, - fileType: fileType, - fileName: modFileName, - fileExt: fileExt}); - //fileName: fileName - }); - } */ - var formatBytes = function (bytes, decimals) { - if (bytes == 0) return '0 Byte'; - var k = 1000; - var dm = decimals + 1 || 3; - var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - var i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; - }; - - this.userRole = function () { - switch (Boolean(self.user('uid'))) { - case true: - return 'user'; // user logged in - break; - case false: - return 'guest'; - break; - } - }; - - this.userIn = function () { - //var user = firebase.auth().currentUser; - //if (user.emailVerified) { - return Boolean(self.user('uid')); - }; - - this.userOut = function () { - return (!self.user('uid')); - }; - - this.user = function (param) { - /* self.log('user'); - self.log(auth); */ - if (auth && auth.currentUser) - if (param == 'firstName') - return self.firstName(auth.currentUser['displayName']); - else if (auth.currentUser[param]) - return auth.currentUser[param]; - else if (!param) - return auth.currentUser; - - else - return undefined; - - else - return undefined; - }; - - this.firstName = function (nameParam) { - var firstNameStr = (nameParam) ? nameParam.split(' ')[0] : ''; - return firstNameStr; - }; - - this.userUid = function () { - if (auth) return auth.currentUser.uid; - else return undefined; - }; - - this.userVerified = function () { - if (auth) return auth.currentUser.emailVerified; - else return undefined; - }; - - /* this.value = function (valueParams) { - if (valueParams.string) - return valueParams.string - else if (valueParams.function) - //return self.doFunctionByName(valueParams.function, window, ''); - } - */ - this.thunkableMessage = function (message, callback) { - if (callback) callback(message); - }; - - this.onMessage = { - alert: "test" - }; - - this.processMessage = function (message) { - self.alert('processMessage'); - self.do(self.onMessage, message); - //self.do(self.onMessage, undefined, message); - }; - - this.thunkable = function (params, args) { - if (params.postMessage) { - var message = self.replaceProperties(params.postMessage, args); - if (message) { - try { - ThunkableWebviewerExtension.postMessage(message); - } catch (error) { - } - } - else - self.log('in function "thunkable" "postMessage" parameter is wrong'); - } - if (params.receiveMessage) { - self.onMessage = params.receiveMessage; - try { - ThunkableWebviewerExtension.receiveMessage(self.processMessage); - } catch (error) { - } - } - - }; - - /* var ThunkableWebviewerExtension = (function () { - const postMessageToWebview = (message) => { - if (window.ReactNativeWebView) { - window.ReactNativeWebView.postMessage(message); - } else { - window.parent.postMessage(message, '*'); - } - }; - - const getReceiveMessageCallback = (fxn, hasReturnValue) => (event) => { - if (typeof fxn === 'function') { - if (event.data) { - let dataObject; - try { - dataObject = JSON.parse(event.data); - } catch (e) { - // message is not valid json - } - if (dataObject && dataObject.type === 'ThunkablePostMessage' && hasReturnValue) { - fxn(dataObject.message, (returnValue) => { - const returnMessageObject = { type: 'ThunkablePostMessageReturnValue', uuid: dataObject.uuid, returnValue }; - postMessageToWebview(JSON.stringify(returnMessageObject)); - }); - } else if (!hasReturnValue && (!dataObject || dataObject.type !== 'ThunkablePostMessage')) { - fxn(event.data); - } - } - } - }; - - return { - postMessage: postMessageToWebview, - receiveMessage: function (fxn) { - const callbackFunction = getReceiveMessageCallback(fxn, false); - document.addEventListener('message', callbackFunction, false); - window.addEventListener('message', callbackFunction, false); - }, - receiveMessageWithReturnValue: function (fxn) { - const callbackFunction = getReceiveMessageCallback(fxn, true); - document.addEventListener('message', callbackFunction, false); - window.addEventListener('message', callbackFunction, false); - }, - }; - })(); */ - this.extendFunctions = function (functions) { - // change it. don't call self.function - for (var name in functions) { - if (functions[name].js) { - try { - // create or override function - self.functions[name] = new Function(functions[name].js); - } catch (error) { - console.log('ERROR creating function %c' + name, 'color:orange;'); - self.log(functions[name].js); - self.log(error.message); - // error.column is wrong - /* let col = error.column -17; - console.log( - functions[name].js.substring(0,col) - + '%c' + functions[name].js.substring(col, col+1) - + '%c' + functions[name].js.substring(col+1), 'color:orange; font-weight:bold', 'color:#ddd') - console.log('%c' + error.message, 'color:orange;'); */ - // since the script is in one row, error.columns is the exact position of the error - } - } else { - self.log(name + ' function requires js property'); - } - } - }; - - - this.function = function (obj, args) { - /* console.log('function'); - console.log(params); - console.log('args'); - console.log(args); */ - // TO DO: add "name" parameter to make the js function permanently available in self.methods[name] - // https://stackoverflow.com/questions/49125059/how-to-pass-parameters-to-an-eval-based-function-injavascript - //app[func].apply( this, args ); // or app[func]( ...args ); // ES6 (2015) - // https://stackoverflow.com/questions/1316371/converting-an-array-to-a-function-arguments-list - //args = self.replaceProperties(args); // needed? - //try { - if (obj.name && obj.js) { - // create or replace function - self.functions[obj.name] = new Function(obj.js); - } else if (obj.name && !obj.js) { - if (self.functions[obj.name]) { - // execute function - if (!obj.arguments || !Array.isArray(obj.arguments)) obj.arguments = [obj.arguments]; - try { - return self.functions[obj.name](...obj.arguments); - //return self.functions[obj.name].apply(null, obj.arguments); - } catch (error) { - console.log('ERROR in function %c' + obj.name, 'color:orange;'); - console.log('obj'); - console.log(obj); - console.log('function'); - console.log(self.json.functions[obj.name]); - console.log(error.message); - } - } else { - console.log('ERROR function undefined %c' + obj.name, 'color:orange;'); - } - //return self.functions[obj.name](...obj.arguments); // also args? - } else if (obj.js) { - // execute js code as a function - if (obj.arguments && Array.isArray(obj.arguments)) { - return new Function(obj.js).call(null, obj.arguments); - //return new Function( obj.js ).apply(this, obj.arguments ); - } else { - return new Function(obj.js).call(null, obj.arguments); - } - } - /* } catch (error) { - self.log('function ERROR'); - self.log(error); - self.log(obj); - return false - } */ - }; - - - this.eval = this.js = function (code, args) { - /* self.log('js'); - self.log(code); - self.log(args); */ - /* if (Array.isArray(code)) { - let codeCombined = ''; - for (var codePart of code) codeCombined += self.replaceProperties(codePart, args); - try { - return eval(code); - } catch (error) { - self.log('JS error'); - self.log(error); - return code; - } */ - /* if (typeof code == 'object') { - - } else { */ - - code = self.replaceProperties(code, args); - /* self.log('args'); - self.log(args); */ - try { - //return new Function( code ).call(null, args); - return eval(code); - } catch (error) { - /* self.log('javascript catch on "'+ codeString + '"'); - self.log('error'); - self.log(error); - self.log('codeString'); - self.log(codeString); - self.log('args'); - self.log(args); - return false */ - return code; - } - //} - }; - - /* this.compile = function (obj, args) { - // functions e addTag potrebbero essere eseguiti da una stessa funzione - // in reatà addTag è la funzione che andrebbe lanciata quando la chiave - // dell'azione è tra i tag html - - if (obj !== undefined) { - var result; - if (typeof obj == 'object') - result = self.actionResult(obj, args); - result = self.replaceProperties(obj, args); - if (result == 'undefined') - return undefined; - else if (typeof result == 'object') // Array is also an object type - return self.do(result, args); - else if (typeof result == 'function') - return result(args); - else { - return result; - } - } else { - return undefined; - } - } */ - this.if = function (params, selectorParams, args) { - - // add array - if (typeof params == 'object') { - - var conditionString = 'if'; - var condition; - - if (params.is !== undefined) { - if (typeof params.is == 'string') { - let isReplaced = self.replaceProperties(params.is, args, true); - self.log(isReplaced, 'grey'); - try { - condition = Boolean(eval(isReplaced)); // remove undefined values - self.log(isReplaced + ' is ' + condition, 'grey'); - } catch (error) { - self.log(isReplaced, 'red'); - self.log('"if" condition wrong', 'red'); - self.log(error, 'red'); - } - conditionString += ' is ' + params.is; - } else if (Array.isArray(params.is)) { - let i = 0; - params.is[i]; - switch (params.is[i + 1]) { - case '=': condition = Boolean(eval(params.is[i] + '===' + params.is[i + 2])); break; - } - } - } else if (params.not !== undefined) { - condition = (!Boolean(eval(self.replaceProperties(params.not, args, true)))); // remove undefined values - if (typeof params.not == 'string') conditionString += ' not ' + params.not; - } else if (params.regexp) { - const regex = new RegExp(params.regexp); - condition = Boolean(regex.test(params.string)); - } else if (params.isArray) { - condition = self.isArray(params.isArray); - conditionString += 'isArray ' + params.isArray; - } else if (params.exist) { - let elementExist = self.element({ path: params.exist }); - condition = (elementExist); - self.log('"if" exist ' + params.exist, 'grey'); - } else if (params.value && params.in) { - //let arr = self.replaceProperties(params.in, args, true); - //condition = (arr.indexOf(self.replaceProperties(params.value)) >= 0); - condition = self.valueInJson(self.replaceProperties(params.in, args, true), self.replaceProperties(params.value)); - - self.log('"if" value ' + self.replaceProperties(params.value) + ' in array is ' + condition, 'grey'); - } else if (params.key && params.in) { - condition = self.keyInJson(self.replaceProperties(params.in, args, true), self.replaceProperties(params.key)); - self.log('"if" key ' + self.replaceProperties(params.key) + ' in object is ' + condition, 'grey'); - } else { - let selector = self.selector(params.selector || params.container, undefined) || self.selector(selectorParams, undefined); - //var selector = self.selector(params.selector || params.container, selectorParams); - if (selector) { - if (params.exist) { - //var element = self.query(params.exist); - //condition = Boolean(self.query(selector)); - condition = Boolean(self.exist(selector)); - conditionString += ' ' + selector + ' exist ' + params.exist; - } - if (params.hasClass) { // to be reviewed (self.hasClass need 1 parameter) - var element = self.query(selector); - condition = Boolean(self.hasClass(element, params.hasClass)); - conditionString += ' ' + selector + ' hasClass ' + params.hasClass; - } - if (params.isVisible) { - var element = self.query(selector); - condition = Boolean(self.isVisible(element, params.isVisible)); - conditionString += ' ' + selector + ' isVisible'; - } - if (params.isHidden) { - var element = self.query(selector); - condition = Boolean(self.isHidden(element, params.isHidden)); - conditionString += ' ' + selector + ' isHidden'; - } - if (params.inViewport) { - var element = self.query(selector); - condition = Boolean(self.inViewport(element, params.inViewport)); - conditionString += ' ' + selector + ' inViewport'; - } - if (params.outViewport) { - var element = self.query(selector); - condition = Boolean(self.outViewport(element, params.outViewport)); - conditionString += ' ' + selector + ' outViewport'; - } - if (params.isDisplay) { - var element = self.query(selector); - /* self.log('element'); - self.log(element); */ - condition = Boolean(self.isDisplay(element, params.isDisplay)); - conditionString += ' ' + selector + ' isDisplay ' + params.isDisplay; - } - } else { - self.log('the "if" function requires "is" or "not" parameter'); - } - } - - /* conditionString += ': ' + condition; - self.log(condition, 'grey'); */ - if (condition) - if (params.then) { - // self.console dovrebbe diventare così - if (typeof params.then == 'object') { - return self.do(params.then); - //return self.do(params.then); - } if (typeof params.then == 'string') { - return self.replaceProperties(params.then); - } else { - return params.then; - } - - } - else - self.log('the "if" function requires "then" parameter'); - else if (params.else) { - if (typeof params.else == 'object') { - return self.do(params.else); - //return self.do(params.else); - } if (typeof params.else == 'string') { - return self.replaceProperties(params.else); - } else { - return params.else; - } - } - } else { - //self.log(Boolean(params) && params !== 'false'); - return Boolean(self.js(params, args)); // 0.9.7 - - //return Boolean(eval(self.replaceProperties(params, args))) // need try - } - }; - - this.switch = function (params, args) { - //self.log('switch'); - //self.log(params); - var value; - var answer; - if (params.expression) - value = String(self.js(params.expression, args)); - - else - self.log('"switch" function requires "expression" parameter'); - //self.log(value); - if (params.cases) { - //self.log('params.cases[value]'); - //self.log(params.cases[value]); - if (value !== undefined && params.cases[value]) { - if (typeof params.cases[value] == 'object') - answer = self.do(params.cases[value], undefined, args); - - - //answer = self.do(params.cases[value], args); - else - answer = params.cases[value]; - - } else if (params.cases['default']) { - self.log('default'); - self.log(params.cases['default']); - if (typeof params.cases['default'] == 'object') - answer = self.do(params.cases['default'], undefined, args); - - - //answer = self.do(params.cases['default'], args); - else - answer = params.cases['default']; - } - } else { - self.log('"switch" function requires "cases" parameter'); - self.log('answer'); - self.log(answer); - } - return answer; - }; - - - /* - this.varAction = this.set = function (params, args) { - // {name, value, operator} - - var value; - var operator = params.operator; - - //self.log('operator'); - //self.log(operator); - - if (operator && args) operator = self.replaceProperties(operator, args); - - - //self.log('operator'); - //self.log(operator); - - if (params.value !== undefined) { // set - value = self.js(params.value, args); - if (params.var) { - self.docElement('self.json.var.'+params.var, value); - } else if (params.name) { - var actualValue = self.docElement('self.json.var.'+params.name); - if (actualValue == undefined && typeof value == 'string') actualValue = ''; - if (actualValue == undefined && typeof value == 'number') actualValue = 0; - if (actualValue == undefined && typeof value == 'object') actualValue = {}; - if (operator) { - - if (operator == '+=') actualValue += value; - if (operator == '-=') actualValue -= value; - if (operator == '/=') actualValue /= value; - if (operator == '*=') actualValue *= value; - value = actualValue; - } - self.docElement('self.json.var.'+params.name, value); - //self.log('self.json.var[params.name]'); - //self.log(self.json.var[params.name]); - } else { - self.log('set command requires "var" parameter'); - } - } else { // get - if (params.var) { - return self.docElement('self.json.var.'+params.var); - } else if (params.name) { - return self.docElement('self.json.var.'+params.name); - } else { - self.log('set command requires "value" parameter'); - } - } - //self.log('value'); - //self.log(value); - self.log('var ' + params.name + ' = ' + value); - - } */ - this.delay = function (params, selector, args) { - self.log('delay'); - self.log('selector'); - self.log(selector); - var duration = params.duration || 1000; - duration = Number(self.replaceProperties(duration, args)); - self.log(duration); - if (params.do) { - setTimeout(function () { - self.do(params.do, selector, args); - //self.do(params.do, args, container) - }, duration); - } - }; - - this.firebasePasswordReset = function (paramEmail, paramSuccess, paramError) { - //firebase.auth().languageCode = 'it'; - firebase.auth().useDeviceLanguage(); - auth.sendPasswordResetEmail(paramEmail).then(function () { - // Email sent. - if (paramSuccess) self.do(paramSuccess); - //if (paramSuccess) self.do(paramSuccess); - }).catch(function (error) { - // An error happened. - if (paramError) self.do(paramError, undefined, error.message); - //if (paramError) self.do(paramError, error.message); - }); - }; - - this.firebaseUpdateProfile = function (params, paramSuccess, paramError) { - self.log('firebaseUpdateProfile'); - self.log(params); - auth.currentUser.updateProfile(params).then(function () { - // Update successful. - self.log('User Profile Updated Successfully'); - if (paramSuccess) self.do(paramSuccess); - //if (paramSuccess) self.do(paramSuccess); - }).catch(function (error) { - // An error happened. - if (paramError) self.do(paramError, undefined, error.message); - //if (paramError) self.do(paramError, error.message); - }); - }; - - this.firebaseRegister = function (params, success, error) { - if (params.email && params.password) { - // log the user in - auth.createUserWithEmailAndPassword(params.email, params.password).then(cred => { - self.log(cred.user); - //var.auth.cred = cred; - var user = firebase.auth().currentUser; - /* if (user.emailVerified) { - } else { - self.sendEmailVerification(params); - } */ - //if (params.success) self.do(params.success); - if (params.success) self.do(params.success); - }).catch(error => { - // Handle Errors here. - //if (params.error) self.do(params.error, error.message); - if (params.error) self.do(params.error, undefined, error.message); - }); - } - }; - - this.firebaseLogin = function (params) { - self.log('firebaseLogin'); - self.log(params); - - if (auth) { - auth.signInWithEmailAndPassword(String(params.email), String(params.password)).then(cred => { - //var.auth.cred = cred; - var user = firebase.auth().currentUser; - //firebase.auth().languageCode = 'it'; - if (user.emailVerified) { - if (params.success) self.do(self.replaceResult(params, undefined, cred)); - //if (params.success) self.do(self.replaceResult(params, cred)); - } else { - self.sendEmailVerification(params); - } - }).catch(error => { - self.log('error.code'); - self.log(error.code); - if (params.error) self.do(self.replaceResult(params, undefined, error.message)); - //if (params.error) self.do(self.replaceResult(params, error.message)); - }); - } else { - // firebase auth non inizializzato - } - }; - - this.firebaseLogout = function (params) { - self.log('firebaseLogout'); - firebase.auth().signOut().then(function () { - self.log('firebaseLogout SUCCESS'); - self.log(params.success); - if (params.success) { - //app.stopMeeting(); - localStorage.clear(); - //self.do(params.success); - self.do(params.success); - } - }).catch(function (error) { - self.log('firebaseLogout ERROR'); - self.log(error); - //if (params.error) self.do(params.error); - if (params.error) self.do(params.error); - }); - }; - - // this.firebaseUserVerify = function (params) { - // self.log('firebaseUserVerify'); - // self.log(params); - // self.log(params.oobCode); - // if (params.oobCode) self.params.codeMail = params.oobCode - // self.log(self.params.codeMail); - // //self.do(data); - // // inviare mail di verifica - // } - this.sendEmailVerification = function (params) { - self.log('sendEmailVerification'); - var user = firebase.auth().currentUser; - firebase.auth().languageCode = 'it'; - var successAction = params.success || self.reload; - user.sendEmailVerification().then(function () { - firebase.auth().signOut(); - self.alert({ - //toast: true, - icon: "success", - title: "verifyingemail", // all\'indirizzo "+params.email+" - html: "msgverifyingemail", - //confirmButtonText: "Ok", - //showCancelButton: false, - showConfirmButton: false, - confirm: successAction - }); - - }); - }; - - /* //self.log('function'); - params = self.replaceProperties(params, args); // -> compile - - if (typeof params == 'object') { - // jsonic function - //return self.do(params, args); - return self.do(params, args); - } else if (typeof params == 'function') { - // javascript function - return params(args); - } else if (typeof params == 'string') { - if (json.actions[params]) { - var functionCompiled = self.replaceResult(json.actions[params], args); // replace {result} - //functionCompiled = self.replaceProperties(functionCompiled, args); - // jsonic predefined function - //return self.do(functionCompiled); - return self.do(functionCompiled); - //return self.actionResult(json.actions[params], args); - } else { - // javascript function name - var functionName = self.docElement(params); - if (functionName) - if (typeof functionName == 'function') { - // javascript function - return functionName(args) - } else { - // javascript object - return functionName; - } - else - self.log('function undefined: '+ params); - } - } */ - this.path = function (pathParams, args, separatorParam) { - var pathString = ''; - var separator = separatorParam || '/'; - - /* self.log('this.path'); - self.log(pathParams); - self.log(args); */ - if (typeof pathParams == 'string') { - pathString = self.replaceProperties(pathParams, args); - } else { - for (var index in pathParams) { - pathObj = pathParams[index]; - if (pathString !== '') pathString += separator; - if (pathObj.string) - pathString += String(pathObj.string); - else if (pathObj.number) - pathString += Number(pathObj.number); - else if (pathObj.function) - pathString += self.doFunctionByName(pathObj.function, window, ''); - } - } - return pathString; - }; - - - this.executeFunctionByName = function (functionName, context /*, arguments */) { - //self.log('executeFunctionByName'); - //self.log(functionName); - if (functionName) { - var args = [].slice.call(arguments).splice(2); - var namespaces = functionName.split("."); - var func = namespaces.pop(); - for (var i = 0; i < namespaces.length; i++) { - context = context[namespaces[i]]; - } - if (context[func] !== undefined) { - return context[func].apply(context, args); - } else { - //self.log('Error: executeFunctionByName'); - //if (functionName !== undefined) {self.log('functionName:'+functionName);} - } - } else { - self.log('executeFunctionByName'); - self.log('functionName undefined'); - } - - }; - - this.functions = {}; - - this.methods = { - // main methods - run: function (params, container, args) { self.run(params, container, args); }, - delay: function (params, container, args) { self.delay(params, container, args); }, - ajax: function (params, container, args) { self.ajax(params, container, args); }, - do: function (params, container, args) { self.do(params, container, args); }, - module: function (params, container, args) { self.module(params, args); }, - js: function (params, container, args) { self.js(params, args); }, - function: function (params, container, args) { self.function(params, args); }, - dispatchEvent: function (params, container, args) { self.dispatchEvent(params, args); }, - - // TO DO: check - lang: function (params, container, args) { self.lang(params, args); }, - find: function (params, container, args) { self.find(params, args); }, - page: function (params, container, args) { self.page(params, args); }, - - // DA VERIFICARE - //dayjs: function (params, args) {self.dayjs(params, args)}, - //moment: function (params, args) {self.moment(params, args)}, - //data: function (params, args) {self.data(params, args)}, - //var: function (params, args) {self.var(params, args)}, - //javascript: function (params, args) {self.javascript(params, args)}, - //color: function (params, args) {self.color(params, args)}, - //select: function (params, args) {self.select(params, args)}, - // LOGIC & DATA - for: function (params, container, args) { self.for(params, container, args); }, - if: function (params, container, args) { self.if(params, container, args); }, - switch: function (params, container, args) { self.switch(params, args); }, - set: function (params, container, args) { self.set(params, args); }, - - // TO DO: check is needs to be renamed to avoid confusion with self.json.data - data: { - set: function (params, args) { - for (var param in params) { - - var value = params[param]; - - if (value) value = self.replaceProperties(value, args); - if (value && args) value = self.replacePropertyWithPrefix(value, 'result', args); // backward compatibility TO DO: remove - - self.element({ path: param, value: value }); - } - }, - get: function (params) { - return self.element(params); - }, - delete: function (params, args) { - var path = self.replaceProperties(params, args); - alert(path); - self.objToDelete = self.element({ path: path }); - delete self.objToDelete; - }, - add: function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || ''; - obj += String(value); - self.element({ path: path, value: obj }); - } - } - }, - sum: function (params, args) { - console.log('%cdeprecated key "sum". Use set{x: "{x}+1"}', 'color:orange'); - console.log(params); - console.log(args); - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj += Number(value); - self.element({ path: path, value: obj }); - } - } - }, - sub: function (params, args) { - console.log('%cdeprecated key "sub". Use set{x: "{x}+1"}', 'color:orange'); - console.log(params); - console.log(args); - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj -= Number(value); - self.element({ path: path, value: obj }); - } - } - }, - push: function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.push(value); - self.element({ path: path, value: obj }); - } - } - } - }, - - // DOM - text: function (params, container, args) { self.text(params, container, args); }, // TO DO: -> html - html: function (params, container, args) { self.html(params, container, args); }, - attr: function (params, container, args) { self.attr(params, container, args); }, - empty: function (params, container, args) { self.empty(params, args); }, - delete: function (params, args) { - var path = self.replaceProperties(params, args); - - var obj = self.element({ path: path }); - self.log(JSON.stringify(obj)); - self.element({ path: path, delete: true }); - // NOTE: obj = self.element non prende l'oggetto effettivo. quindi element deve contenere tutte le funzioni - //self.element({path: path, delete: true}); - self.log(obj); - }, - add: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - /* self.log('value'); - self.log(value); */ - if (value) { - var obj = self.element({ path: path }) || ''; - obj += String(value); - self.element({ path: path, value: obj }); - } - } - }, - sum: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj += Number(value); - self.element({ path: path, value: obj }); - } - } - }, - sub: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj -= Number(value); - self.element({ path: path, value: obj }); - } - } - }, - push: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.push(value); - self.element({ path: path, value: obj }); - self.log('push obj'); - self.log(obj); - } - } - }, - - // should go in utils.json - calendar: function (params, container, args) { self.calendar(params, args); }, // to check - array: function (params, container, args) { self.array(params, args); }, - replace: function (params, container, args) { self.replace(params, args); }, - shuffle: function (array) { - let currentIndex = array.length, randomIndex; - // While there remain elements to shuffle. - while (currentIndex != 0) { - // Pick a remaining element. - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex--; - // And swap it with the current element. - [array[currentIndex], array[randomIndex]] = [ - array[randomIndex], array[currentIndex] - ]; - } - return array; - }, - - // should go in ui.json (or ux) module - alert: function (params, container, args) { self.alert(params, args); }, // change in swal2 - offcanvas: function (params, container, args) { self.offcanvas(params, args); }, // bootstrap / obsolete - - //in: function (params, container, args) {self.in(params, container, args)}, // bootstrap TO DO: replace in code with ui:in - out: function (params, container, args) { self.out(params, container, args); }, // bootstrap TO DO: replace in code with ui:out - qrcode: function (params, container, args) { self.qrcode(params, container, args); }, // obsolete TO DO: replace in code with ui:qrcode - hide: function (params, container, args) { self.hide(params, container, args); }, // TO DO: replace in code with ui:hide - show: function (params, container, args) { self.show(params, container, args); }, // TO DO: replace in code with ui:show - toggle: function (params, container, args) { self.toggle(params, container, args); }, // TO DO: replace in code with ui:toggle - sortablejs: function (params, container, args) { self.sortablejs(params, args); }, // TO DO: replace in code with ui:sortable - lottie: function (params, container, args) { self.lottie(params, container, args); }, // TO DO: replace in code with ui:lottie - chart: function (params, container, args) { - var selector = self.selector(container); - var element = self.query(selector); - element.innerHTML = ''; - const ctx = element.querySelector('canvas'); - const myChart = new Chart(ctx, self.replaceProperties(params)); - }, - - animate: function (params, container, args) { self.animate(params, container, args); }, - //editor: function (params, container, args) {self.editor(params, container, args)}, // quill - // window.dispatchEvent(new Event('resize')); // workaround known ACE bug - uiUpdate: function (params, container, args) { self.uiUpdate(params, args); }, - swiper: { - data: {}, - init: function (params, selector, args) { - //swiperConfig.on = {}; - setTimeout(function () { - // waits the plugin... TO DO: add this function to a promise - console.log('swiper inited'); - console.log(selector || params.selector); - console.log(params.options); - var swiperConfig = params.options; - self.methods.swiper.data[params.name] = new Swiper(self.selector(selector || params.selector), swiperConfig); - console.log(self.methods.swiper.data[params.name]); - }, 1000); - } - }, - - // should go in browser.json module - //export: function (params, container, args) {self.export(params, container, args)}, -> browser - //console: function (params, container, args) {self.console(params, args)}, // obsolete, changed in log - link: function (params, container, args) { self.link(params, args); }, - scroll: function (params, container, args) { self.scroll(params, args); }, - reload: function (params, container, args) { self.reload(params, args); }, - timer: function (params, container, args) { self.timer(params, args); }, - setInterval: function (params, container, args) { self.setInterval(params, args); }, - clearInterval: function (params, container, args) { self.clearInterval(params, args); }, - setTimeout: function (params, container, args) { self.setTimeout(params, args); }, - clearTimeout: function (params, container, args) { self.clearTimeout(params, args); }, - local: { - set: function (params) { - for (var param in params) { - var value = params[param]; - if (value) value = self.replaceProperties(value); - if (typeof value == 'object') value = JSON.stringify(value); - localStorage.setItem(param, value); - } - }, - get: function (key) { - var localValue = localStorage.getItem(key); - if (localValue && self.isJsonString(localValue)) - localValue = JSON.parse(localValue); - return localValue; - }, - remove: function (key) { - localStorage.removeItem(key); - }, - clear: function () { - localStorage.clear(); - } - }, - storage: { - _storage: new WeakMap(), - set: function (element, key, obj) { - if (!self.methods.storage._storage.has(element)) { - self.methods.storage._storage.set(element, new Map()); - } - self.methods.storage._storage.get(element).set(key, obj); - }, - get: function (element, key) { - return self.methods.storage._storage.get(element).get(key); - }, - has: function (element, key) { - return self.methods.storage._storage.has(element) && self.methods.storage._storage.get(element).has(key); - }, - remove: function (element, key) { - var ret = self.methods.storage._storage.get(element).delete(key); - if (!self.methods.storage._storage.get(element).size === 0) { - self.methods.storage._storage.delete(element); - } - return ret; - } - }, - - choose: function (params, container, args) { self.choose(params, container, args); }, - remove: function (params, container, args) { self.remove(params, container, args); }, - part: function (params, container, args) { self.part(params, container, args); }, - blocks: function (params, container, args) { self.part(params, container, args); }, // obsolete - block: function (params, container, args) { self.part(params, container, args); }, - ace: function (params, container, args) { self.ace(params, container, args); }, - code: function (params, container, args) { self.code(params, container, args); }, - - // should go in firebase.json module - database: function (params, container, args) { self.database(params, args); }, // obsolete (check) - firebase: function (params, container, args) { self.firebase(params, args); }, - - firebaseEvent: { - action: function (newObj) { - /* self.logdbRef('firebaseEvent.action'); - self.log('newObj'); - self.log(newObj); */ - /* var path = newObj.path; - delete newObj.path; - var pathString = 'self.json.var.db.' + self.replaceAll(path, '/', '.'); - self.log('pathString:'+pathString); - var dbObj = self.docElement(pathString); - dbObj = newObj; // update local db */ - var path = newObj.path; - delete newObj.path; - //alert(path); - document.querySelectorAll('[data-firebase="' + path + '"]').forEach(function (element, index) { - //$('[data-firebase="'+path+'"]').each(function (index) { - // var element = this; - var pathString = 'self.json.var.db.' + self.replaceAll(element.getAttribute('data-firebase'), '/', '.'); // data('firebase') - var dbObj = self.docElement(pathString); - - var firebaseValue = newObj[element.getAttribute('data-value')]; // TODO: not works for nested nodes - - //var template = element.getAttribute('data-template'); - var template = self.dataStorage.get(element, 'data-template'); - - //if ($(element).is('ul')) { - if (element.tagName == 'UL') { // se $(this) è un ul - - //var dbObj = self.docElement(pathString); - // se il percorso ha più nodi e il dato non è presente nel db locale, - // va creato un oggetto vuoto per ogni nodo - //var context = element.getAttribute('data-firebase'); - //self.var.db[context] = newObj; // update local db - var liTemplate = template.li || template.template; // template.li retro-compatibility - - - - - - - - /* self.log('liTemplate'); - self.log(liTemplate); - self.log('newObj'); - self.log(newObj); */ - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - - /* if (params.li.class == "deviceItem d-flex flex-wrap align-items-center list-group-item list-group-item-action d-flex align-items-center justify-content-between") { - alert(JSON.stringify(params.li)); - } */ - //if (dbPath == 'lessons') - //prompt(JSON.stringify(liTemplate)); - // TO DO: replace with replaceProperty - var dbParams = self.replaceItems(liTemplate, item, 'item') || ''; - - // var dbParams = self.replaceProperties(liTemplate, undefined, item) || ''; - // -> TO DO container = self.elementToSelector(element); - var container = element.getAttribute('data-selector'); - - self.li(dbParams, { selector: container }); - } - - //} else if ( $(element).is('span') || $(element).is('p')) { - } else if (element.tagName == 'SPAN' || element.tagName == 'P') { - - //$(element).text(firebaseValue); - element.textContent = firebaseValue; - - } else if (element.tagName == 'SVG') { - // TODO without JQUERY - //$(element).children('text').text(firebaseValue); - } else { // se $(this) non è un ul - - //var dbObj = self.docElement(pathString); - // se il percorso ha più nodi e il dato non è presente nel db locale, - // va creato un oggetto vuoto per ogni nodo - //var context = element.getAttribute('data-firebase'); - //self.var.db[context] = newObj; // update local db - if (template.blocks || template.html) { - var blocksTemplate = template.html || template.blocks; - - //$(container).empty(); - element.innerHTML = ''; - - var items = newObj; - self.log('newObj'); - self.log(newObj); - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - var dbParams = self.replaceProperties(blocksTemplate, undefined, item) || ''; - /* self.log('container'); - self.log(container); - self.log('dbParams'); - self.log(dbParams); */ - self.html(dbParams, { selector: container }); - } - } - - if (template.init) self.do(template.init); //self.do(template.init); - - } - - - }); - } - }, - - auth: { - init: function (params, container, args) { - self.log("auth init"); - auth = firebase.auth(); - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - // No user logged in - self.log('authStateChanged: GUEST\n'); - // non bisognerebbe chiedere sempre di fare login - } else { - // User logged in - self.log('authStateChanged: USER\n'); - self.log('name: ' + self.user('displayName') + '\nemail: ' + user.email + '\nuid:' + user.uid); - //self.log('email verificata'); - //self.log(self.userVerified()); - } - /* self.log('params'); - self.log(params); */ - //self.do(params.onAuthStateChanged); - self.do(params.onAuthStateChanged); - - //if (!firebaseInitialized) { - // firebaseInitialized = true; - //self.do(data); - //} - }); - }, - - sendEmailVerification: function (params, container, args) { - self.sendEmailVerification(params); - }, - - login: function (params, container, args) { - self.log('params.auth'); - self.log(params.auth); // QUESTO E' {var:auth} MA SEMBRA NON RIMPIAZZARLO - self.log(args); // QUI MI RIPORTA LA PWD, ma perché ultimo args - var fba = self.replaceProperties(params.auth, args); - self.log('fba'); - self.log(fba); - var fbAuth = self.cloneObject(fba); - self.log('fbAuth'); - self.log(fbAuth); - if (params.success) fbAuth.success = params.success; - if (params.error) fbAuth.error = params.error; - self.firebaseLogin(fbAuth, params.success, params.error); - }, - - register: function (params, container, args) { - //var fbAuth = self.replaceTags({text: params.auth, args: args}); - //var fbAuth = self.replaceResult(params.auth, args); - var fbAuth = self.replaceProperties(params.auth, args); - fbAuth.success = params.success; - fbAuth.error = params.error; - //alert(JSON.stringify(fbAuth)) - self.firebaseRegister(fbAuth, params.success, params.error); - }, - - updateProfile: function (params, container, args) { - //params.profile = self.replaceTags({text: params.profile, args: args}); - //params.profile = self.replaceResult(params.profile, args); - params.profile = self.replaceProperties(params.profile, args); - self.firebaseUpdateProfile(params.profile, params.success, params.error); - }, - - passwordReset: function (params, container, args) { - //params.email = self.replaceTags({text: params.email, args: args}); - //params.email = self.replaceResult(params.email, args); - params.email = self.replaceProperties(params.email, args); - self.firebasePasswordReset(params.email, params.success, params.error); - }, - - logout: function (params, container, args) { - self.firebaseLogout(params); - } - }, - - // should go in mobile.json module - thunkable: function (params, container, args) { self.thunkable(params, args); }, - - // should go in 3d.json module - modelViewer: { - events: {}, - on: function (params) { - let container = self.selector(params.selector || params.container); - let element = self.query(container); - self.log('modelViewer on'); - self.log('container'); - self.log(container); - self.log('element'); - self.log(element); - if (element) { - self.methods.modelViewer.events[container] = {}; // use self.element - - - //let events = ['load', 'preload']; - //for (var event in events) { - var event = 'load'; - if (params[event]) { - //self.element({root: 'self.methods.modelViewer.events', path: container+'.'+event, value: params[event]}) - self.methods.modelViewer.events[container][event] = params[event]; - self.log('modelViewer element'); - self.log(element); - element.addEventListener(event, (e) => { - self.log('modelViewer event'); - self.log(e); - let container = e.path[0].getAttribute('data-selector'); - self.log(container); - //self.do(self.methods.modelViewer.events[container][e.type]); - self.do(self.methods.modelViewer.events[container][e.type]); - }); - } - } - }, - set: function (params) { - let element = self.query(self.selector(params.selector || params.container)); - if (element) { - if (params.color) { - let color = params.color.split(',').map(numberString => parseFloat(numberString)); - self.log('Changing color to: ', color); - const [material] = element.model.materials; - material.pbrMetallicRoughness.setBaseColorFactor(color); - } - if (params.exposure) element.exposure = params.exposure; - if (params.shadow) element.shadowIntensity = params.shadow; - if (params.orientation) element.orientation = params.orientation; - - } - } - } - }; - - - this.googleSignInPopup = function () { - self.log('googleSignInPopup'); - var provider = new firebase.auth.GoogleAuthProvider(); - - firebase.auth().useDeviceLanguage(); // lingua del dispositivo - - firebase.auth() - .signInWithPopup(provider) - .then((result) => { - // @type {firebase.auth.OAuthCredential} - var credential = result.credential; - // This gives you a Google Access Token. You can use it to access the Google API. - var token = credential.accessToken; - // The signed-in user info. - var user = result.user; - window.location.reload(); - // ... - }).catch((error) => { - // Handle Errors here. - var errorCode = error.code; - var errorMessage = error.message; - // The email of the user's account used. - var email = error.email; - // The firebase.auth.AuthCredential type that was used. - var credential = error.credential; - }); - }; - - - /* this.googleSignInPopup = function () { - // [START auth_google_signin_popup] - self.log('googleSignInPopup'); - var provider = new firebase.auth.GoogleAuthProvider(); - //provider.addScope('https://www.googleapis.com/auth/contacts.readonly'); //check security - //provider.addScope('https://www.googleapis.com/auth/calendar'); - //var languageApp = jsonic.var.language || 'en'; - //firebase.auth().languageCode = 'it';//languageApp; - //self.log(provider); - //return; - firebase.auth() - .signInWithPopup(provider) - .then((result) => { - // @type {firebase.auth.OAuthCredential} - var credential = result.credential; - // This gives you a Google Access Token. You can use it to access the Google API. - var token = credential.accessToken; - // The signed-in user info. - var user = result.user; - //######### result ########// - self.log("credential"); - self.log(credential); - self.log("token"); - self.log(token); - self.log("user"); - self.log(user); - window.location.reload(); - // ... - }).catch((error) => { - // Handle Errors here. - var errorCode = error.code; - self.log('errorCode'); - self.log(errorCode); - var errorMessage = error.message; - self.log('errorMessage'); - self.log(errorMessage); - // The email of the user's account used. - var email = error.email; - self.log('email'); - self.log(email); - // The firebase.auth.AuthCredential type that was used. - var credential = error.credential; - self.log('credential'); - self.log(credential); - // ... - }); - // [END auth_google_signin_popup] - } */ - /* this.auth = function (params, args) { - self.log('auth'); - self.log(params); - if (params.do == 'init') { - auth = firebase.auth(); - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - // No user logged in - self.log('authStateChanged: GUEST\n'); - // non bisognerebbe chiedere sempre di fare login - } else { - // User logged in - self.log('authStateChanged: USER\n'); - self.log('name: '+self.user('displayName') + '\nemail: '+user.email + '\nuid:'+ user.uid); - //self.log('email verificata'); - //self.log(self.userVerified()); - } - - //self.log('params.onAuthStateChanged'); - //self.log(params.onAuthStateChanged); - - self.do(params.onAuthStateChanged); - - //if (!firebaseInitialized) { - // firebaseInitialized = true; - //self.do(data); - //} - }); - } else if (params.do == 'sendEmailVerification') { - - self.sendEmailVerification(params); - - } else if (params.do == 'login') { - - self.log('params.auth'); - self.log(params.auth); - var fba = self.replaceProperties(params.auth, args); - self.log('fba'); - self.log(fba); - var fbAuth = self.cloneObject(fba); - self.log('fbAuth'); - self.log(fbAuth); - if (params.success) fbAuth.success = params.success; - if (params.error) fbAuth.error = params.error; - self.firebaseLogin(fbAuth, params.success, params.error); - - } else if (params.do == 'register') { - - //var fbAuth = self.replaceTags({text: params.auth, args: args}); - //var fbAuth = self.replaceResult(params.auth, args); - var fbAuth = self.replaceProperties(params.auth, args); - - fbAuth.success = params.success; - fbAuth.error = params.error; - //alert(JSON.stringify(fbAuth)) - self.firebaseRegister(fbAuth, params.success, params.error); - - } else if (params.do == 'updateProfile') { - - //params.profile = self.replaceTags({text: params.profile, args: args}); - //params.profile = self.replaceResult(params.profile, args); - params.profile = self.replaceProperties(params.profile, args); - self.firebaseUpdateProfile(params.profile, params.success, params.error); - - } else if (params.do == 'passwordReset') { - - //params.email = self.replaceTags({text: params.email, args: args}); - //params.email = self.replaceResult(params.email, args); - params.email = self.replaceProperties(params.email, args); - self.firebasePasswordReset(params.email, params.success, params.error); - - } else if (params.do == 'logout') { - - self.firebaseLogout(params); - } - // else - //self.database(params, args); - - } - */ - /* this.db = function (params, args) { - if (typeof params == 'string') - return self.db(params, args); - else - self.firebase(params, args); - } */ - this.console = function (params, args) { - - //value = self.replaceProperties(params); - //console.log('JSONIC: '+value, 'color:pink'); - if (typeof params.log == 'string' && params.color) { - var color = params.color || 'white'; - console.log('%c' + self.replaceProperties(params.log), 'color:' + color); - } else { - console.log(self.replaceProperties(params.log || params)); - } - }; - - this.module = function (params, args) { - if (typeof params == 'string') { - var nameReplaced = self.replaceProperties(params, args); - return self.element({ root: self.modules, path: nameReplaced }); - } else { - if (params.name) { - if (params.value) { - var name = self.replaceProperties(params.name, args); - //var value = self.actionResult(params.value, args); - var value = self.replaceProperties(value, args); - self.log('module'); - self.log(name); - self.log('value'); - self.log(value); - self.log(value.app.html.div.div[0].text.lang.en); - self.modules[name] = value; - } else if (params.url) { - self.addModule(params); // TO DO: return? - } - } - } - }; - - this.db = function (params, args) { - self.log('db'); - if (typeof params == 'string') { - var paramsReplaced = self.replaceProperties(params, args); - self.log('paramsReplaced'); - self.log(paramsReplaced); - self.log(self.var('db.' + paramsReplaced, args)); - //var varValue = self.docElement('self.json.var.db.'+name); - return self.var('db.' + paramsReplaced, args); // to do: change with self.element({path: 'db.'+paramsReplaced}}) - - - - - - - - - - /* - // questa versione non funzionava. vuol dire che this.var ha un errore nel caso di oggetto - return self.var({ - name: 'db.'+paramsReplaced - }, args); - - */ - } /* else { - return self.actionResult(params, args); - } */ - - - }; - - this.firebase = function (params, args) { - if (params.initializeApp) { - var firebaseConfig = self.replaceProperties(params.initializeApp); - firebase.initializeApp(firebaseConfig); - } else { - self.database(params, args); - } - }; - - this.database = function (params, args) { - //console.log('database'); - - if (params.do == 'init') { - database = firebase.database(); - self.log('database'); - self.log(database); - } else { - if (database) { - - if (typeof params == 'string') { - - return self.db(params, args); // local db - - } else { - - if (params) { - if (params.path) { - params.path = self.path(params.path, args); - } - /* console.log('params.path'); - console.log(params.path); */ - /* if (params.value) - params.value = params.value; */ //self.value({string: params.value}); - if (params.value) { - - /* self.log("params.value pre replace"); - self.log(params.value); */ - //params.value = self.replaceTags({text: params.value, args: args}); - //params.value = self.replaceResult(params.value, args); - //params.value = self.replaceProperties(params.value, args); - //params.value = self.actionResult(params.value, args); - params.value = self.replaceProperties(params.value, args); - - self.log("params.value post replace"); - self.log(params.value); - } - - - /* self.log('params to FIREBASE'); - self.log(params); */ - // params.value = "${var.newDevice}" - //var newDevice = `${params.value}`; - //var newDevice = `${var.newDevice}`; - if (params.do == 'init') { - } else if (params.do == 'increase') { - - self.firebaseIncrease(params); - - } else if (params.do == 'get') { - - self.firebaseGet(params.path, function (result) { - if (result.success) { - if (result.data) { - self.log('firebase get SUCCESS'); - self.log(params.success); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - } else { - self.log('firebase get no result.data ERROR'); - //if (params.on && params.on.error) self.do(params.on.error); - if (params.on && params.on.error) self.do(params.on.error); - } - } else { - self.log('firebase get ERROR'); - //if (params.on && params.on.error) self.do(params.on.error, result); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - // alert errore di connessione. alert riprova - } - }); - } else if (params.do == 'new' && params.value) { - var newKey = self.getKey(params.path); - self.firebaseSet(params.path + '/' + newKey, params.value, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } else if (params.do == 'remove' && params.path) { - self.firebaseRemove(params.path, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - //if (params.on && params.on.success) self.do(params.on.success, result); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - // alert errore di connessione. alert riprova - } - }); - } else if (params.do == 'addListener') { - self.firebaseAddListener(params); - } else if (params.do == 'removeListener') { - self.firebaseRemoveListener(params); - } else if (params.do == 'update') { - if (params.value) { // 'set' is the default action with 'value' param - self.firebaseUpdate(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase update SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success, result); - } else { - self.log('firebase update ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } else { - self.log('data update requires value param'); - } - } else if (params.do == 'push') { - if (params.value) { // 'set' is the default action with 'value' param - self.firebasePush(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase push SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success,result); - } else { - self.log('firebase push ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } else { - self.log('data push requires value param'); - } - } else { - if (params.value) { // 'set' is the default action with 'value' param - self.firebaseSet(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - //if (params.on && params.on.success) self.do(params.on.success,result); - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - //if (params.on && params.on.error) self.do(params.on.error, result); - // alert errore di connessione. alert riprova - } - }); - } - } - - - } - } - } else { - self.log('"database" function needs to be initialised'); - } - } - }; - - this.ajax = function (params, selectorParams, args) { - /* self.log('ajax'); - // TO DO: selectorParams - self.log('ajax'); - self.log('params'); - self.log(params); - self.log('args'); - self.log(args); */ - if (params.url) { - //var url = self.compile(params.url, args); - var url = self.replaceProperties(params.url, args); - var data; - if (params.data) - data = JSON.stringify(self.replaceProperties(params.data, args)); - //data = JSON.stringify(self.compile(params.data, args)); - /* self.log('data'); - self.log(data); */ - var type = params.type || 'POST'; - var request = new XMLHttpRequest(); - request.open(type, url, true); - //request.setRequestHeader("Accept", "application/json"); - //request.setRequestHeader('Content-Type', 'application/json'); - /* request.onreadystatechange = function () { - if (r.readyState != 4 || r.status != 200) return; - alert("Success: " + r.responseText); - } */ - request.onload = function () { - self.log('onload'); - self.log(this); - if (this.status >= 200 && this.status < 400) { - // Success! - var result = {}; - - //try { - var response = this.response; - response = response.replace(/(\\\")/g, '"'); - try { - response = decodeURI(response); - } catch (error) { - /* console.log('response'); - console.log(response); */ - console.log('decodeURI error'); - console.log(error); - } - result.response = self.parse(response); - result.status = this.status; - result.header = this.getAllResponseHeaders().split('\r\n').reduce((resultHeader, current) => { - let [name, value] = current.split(': '); - resultHeader[name] = value; - return resultHeader; - }, {}); - //} catch (e) { - //} - self.log('result'); - self.log(result); - if (params.success) - self.do(params.success, undefined, result); - //self.do(params.success, result); - //self.do(self.replaceProperty(params.success, 'result', result), result); - } else { - // We reached our target server, but it returned an error - if (params.error) - self.do(params.error, undefined, 'Server error'); - //self.do(params.error, 'Server error'); - } - }; - request.onerror = function (error) { - // There was a connection error of some sort - self.log('error'); - self.log(error); - self.log('this'); - self.log(this); - if (params.error) - self.do(params.error, undefined, 'Server unavailable'); - //self.do(params.error, 'Server unavailable'); - }; - //request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); - if (data) - request.send(data); - - else - request.send(); - } else { - self.log('ajax method requires url parameter'); - } - - - /* $.ajax({ - url: paramsReplaced.url, - type: params.type || 'post', - //dataType: 'json', // questo dovrebbe evitare JSON.parse - //dataType: 'text', // verificare se necessario - data: paramsReplaced.data || {}, - success: function (result) { - self.log('ajax'); - self.log('result'); - self.log(result); - self.do(params.success, result); - //self.do(data); // in .params dovrebbe andare il resto - }, - error: function (error) { - var errorText = error.responseText || error; - self.do(params.error, errorText); - //self.do(data); // in .params dovrebbe andare il resto - } - }); */ - }; - - /* View in fullscreen */ - this.openFullscreen = function (id) { - var element = document.getElementById(id); - - if (screenfull.isEnabled) { - screenfull.request(element); - } - - }; - - /* this.addListener = function(params) { - var selector = self.selector(params); - if (selector) - $(selector).on(params.event, self.do(params.action)); - //event.stopPropagation(); - } */ - /* Close fullscreen */ - this.closeFullscreen = function () { - - //document.exitFullscreen(); - screenfull.off('change'); // callback - }; - - /* this.list = function (params, selectorParams) { - - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - if (selector) { - - if (params.list) params.items = params.list; // retro-compatibilità - - if (params.listAction) $(selector).data('listAction', params.listAction); - if (params.listClass) $(selector).data('listClass', params.listClass); // ul - - if (params.items) { - - $(selector).empty(); - var index = 0; - - //params.items = self.replaceTags({text:params.items, args:selectorParams}); - //params.items = self.replaceResult(params.items, selectorParams); - params.items = self.replaceProperties(params.items, selectorParams); - - for (var itemKey in params.items) { - // da rimuovere id="item'+itemKey+'" href="" - //self.log('PARAMETRI'); - //self.log(itemKey); - //self.log(params.items); - - - $(selector).append('
      • '); - var item = params.items[itemKey]; - //var itemSelector = selector + ' li:eq(' + index + ')'; - var itemSelector = selector + ' li:eq(' + itemKey + ')'; - - // Item action - var itemAction; - if (item.action) - itemAction = item.action; - else if (params.action) - itemAction = params.action; - else if ($(selector).data('listAction')) - itemAction = $(selector).data('listAction'); - item.action = itemAction; - - if (item.action) { - $(itemSelector).addClass('list-group-item-action'); - $(itemSelector).css('cursor', 'pointer'); - } - if (item.color) $(itemSelector).css('color', item.color); - if (item.background) $(itemSelector).css('background', item.background); - - //$(itemSelector).append('
        '); - - var itemFields = params.items[itemKey].fields || params.items[itemKey]; // retro-compatibilità - //self.log('itemFields'); - //self.log(itemFields); - - for (var itemField in itemFields) { - var field = itemFields[itemField]; - //self.log(field); - if (itemField == 'icons') { - - self.icons(field, {container: itemSelector}); - - - } else if ((itemField != 'params') && (itemField != 'action')) { // retro-compatibilità - $(itemSelector).append(''+self.text(itemFields[itemField])+''); - } - } - - // action - if (item.action) { - $(itemSelector).data('onData', item); - $(itemSelector).on(self.touch, function (event) { - event.stopPropagation(); - self.onEvent(this, event); - }); - } - // events - if (item.on) self.on(item.on, {container: selector}); - - index++; - } - } else if (params.append) { - // aggiunge una riga alla fine (calcolare path) - } else if (params.prepend) { - // aggiunge una riga all'inizio (calcolare path) - // sballa tutti i dati presenti in var.functions - // sarebbe meglio mem in data value tutto il json - // azione - } - - // List classes - - //if (params.id) $(selector).attr('id', params.id); - var listClass = $(selector).data('listClass'); - - - if (listClass) { - var ulClass = listClass.ul || ''; - var liClass = listClass.li || ''; - - $(selector).addClass(ulClass); - $(selector + ' > li').addClass(liClass); - - var index = 0; - for (var field in listClass.fields) { - var fieldClass = listClass.fields[field] || ''; - $(selector + ' > li > span[data-field='+field+']').addClass(fieldClass); - index++; - } - } - } - } */ - this.scroll = function (params) { - // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView - // {id, class, value} - var selector = self.selector(params.selector || params.container); - var block = document.querySelector(selector); - //var offset = elem.dataset.offset ? parseInt(elem.dataset.offset) : 0; - if (block) { - var bodyOffset = document.body.getBoundingClientRect().top; - window.scrollTo({ - top: block.getBoundingClientRect().top - bodyOffset, // + offset, - behavior: 'smooth' - }); - } else { - self.log('scroll to unknown element: ' + selector); - } - }; - - /* this.scroll = function (params) { - // var selector = self.selector(params); - //var obj = $(selector).get(0); - - var selector = "g."+params.class+".myLabelStyle."+params.value; - - - //var parent = $(selector).parent().get(0); - - //document.querySelector(selector).scrollIntoView(); - //self.resizeEvent(); // bug workaround - //$(selector).parent().scrollTop($(selector).position().top); - $(selector).parent().animate({ - //scrollTop: $(selector).position().top - //scrollTop: $(selector).position().top, - transform: 'translate(0,-'+$(selector).position().top+'), scale(1)' - }); - } - */ - //------------------------ - /* this.do = function (data, args) { - if (data) { - if (typeof data == 'string' && self.json.actions[data]) { - self.do(self.json.actions[data], args); - } else { - if (!data.index) data.index = 0; - if (!data.tasks) { - if (Array.isArray(data)) { - - if (data.index < data.length) { - self.do(data[data.index]); - data.index = data.index +1; - self.do(data); - } else { - delete data.index; - } - } else { - self.do(data); - } - //} else if (data.tasks.length > 0) { - } else { - if (data.index < data.tasks.length) { - var currentTask = data.tasks[data.index]; - //var currentTask = data.tasks.shift(); - if (currentTask.params == undefined) {currentTask.params = {}} - if (data.params == undefined) {data.params = {}} - if (currentTask.if == undefined) {currentTask.if = true} - var taskParams = currentTask.params; // parametri specifici del task - taskParams.params = data.params; - taskParams.index = data.index+1; - //for (var param in data.params) {taskParams[param] = data.params[param]; } // merge - taskParams.tasks = data.tasks; - var taskIf = (typeof currentTask.if == "function") ? currentTask.if() : currentTask.if; - - if (taskIf) { - if (currentTask.delay !== undefined) { - setTimeout(function () { - self.do(currentTask.task, taskParams); - - }, currentTask.delay); - } else if (currentTask.interval !== undefined) { - self.createTaskInterval(currentTask); - } else { - self.do(currentTask.task,taskParams); - - } - } else { - self.do(taskParams); - } - } - } - } - } - } */ - /* this.playTaskInterval = function (taskFunction) { - self.log('playTaskInterval'); - var taskName = taskFunction.name; - if (tasksIntervals[taskName]) { - clearInterval(tasksIntervals[taskName].id); - tasksIntervals[taskName].id = setInterval(function () { - tasksIntervals[taskName].task(tasksIntervals[taskName].params); - }, tasksIntervals[taskName].interval); - } else { - self.log('taskName: '+taskName); - } - } - - this.stopTaskInterval = function (taskFunction) { - self.log('stopTaskInterval'); - var taskName = taskFunction.name; - if (tasksIntervals[taskFunction.name]) { - clearInterval(tasksIntervals[taskFunction.name].id); - } else { - self.log('taskName: '+taskName); - } - } - - this.createTaskInterval = function (myTask) { - tasksIntervals[myTask.task.name] = {}; - tasksIntervals[myTask.task.name].task = myTask.task; - tasksIntervals[myTask.task.name].params = myTask.params; - tasksIntervals[myTask.task.name].interval = myTask.interval; - self.playTaskInterval(myTask.task.name); - } - - this.addTimedTask = function (data) { - self.log('addTimedTask'); - if (data.frequence && data.task) { - if (!data.active) {data.active = true;} - if (!timedTasks[data.frequence]) {timedTasks[data.frequence] = {}} - timedTasks[data.frequence][data.task] = {active:data.active, params:{}}; - if (data.params) { - timedTasks[data.frequence][id].params = data.params; - } - } - } - - this.removeTimedTask = function (data) { - self.log('removeTimedTask'); - if (data.frequence && data.task) { - delete timedTasks[data.frequence][data.task]; - } - } - - this.doTimedTask = function (data) { - self.log('doTimedTask'); - self.log(data); - for (var task in timedTasks[data.frequence]) { - var taskObj = timedTasks[data.frequence][task]; - if (taskObj.active) { - self.do(task, taskObj.params); - } - } - } */ - //------------------------ - // CSS METHODS - //------------------------ - /* // SELETTORI - var previewPanel = '.appPanel[data-value="pnlPreview"]'; - var toolsPanel = '.appPanel[data-value="pnlTools"]'; - - var stagePanel = '.framePanel[data-value="pnlStage"]'; - var devicePanel = '.framePanel[data-value="pnlDevice"]'; - - this.closePanel = function(value) { - self.log(value); - - switch (value) { - case 'closePanelTools': - $(toolsPanel).fadeOut(); - $(previewPanel).fadeIn(); - case 'closePanelFrame': - $(devicePanel).fadeOut(); - $(stagePanel).fadeIn(); - } - } - */ - //------------------------ - // CSS METHODS - //------------------------ - /* this.cssProp = function (propPar) { - var cssObj = {transform: ''}; - if ((propPar.x) && (propPar.y)) {cssObj.transform += ' translate('+propPar.x+'px,'+propPar.y+'px)'; } - if (propPar.rotateY) {cssObj.transform += ' rotateY('+propPar.rotateY+'deg)'; } - if (propPar.rotateX) {cssObj.transform += ' rotateX('+propPar.rotateX+'deg)'; } - if (propPar.scale) {cssObj.transform += ' scale('+propPar.scale+','+propPar.scale+')'; } - if (propPar.deg) {cssObj.transform += ' rotate('+propPar.deg+'deg)'; } - if (propPar.opacity) {cssObj.opacity = propPar.opacity;} - return cssObj; - } */ - /* this.getCSS = function (data) { - var $inspector = $("
        ").css('display', 'none').addClass(data.class); - $("body").append($inspector); // add to DOM, in order to read the CSS property - try { - var props = []; - for (i=0; i { - /* self.log('animate'); - self.log('params'); - self.log(params); - - self.log('selectorParams'); - self.log(selectorParams); */ - - /* selectorParams.container = (params.container) ? params.container : selectorParams.container; - selectorParams.id = (params.id) ? params.id : selectorParams.id ; - selectorParams.class = (params.class) ? params.class : selectorParams.class; - selectorParams.value = (params.value) ? params.value : selectorParams.value; */ - const prefix = 'animate__'; - //var selector = self.selector(self.extend({}, params, selectorParams), undefined, true); // selectAll - let selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - //var selector = self.selector(params.selector || params.container, selectorParams, true); // selectAll - /* self.log('animate'); - self.log('selector'); - self.log(selector); */ - var transition = params.transition || params; - transition = self.replaceProperties(transition, args); - - const duration = params.duration || '0.5s'; - - const animationName = `${prefix}${transition}`; - - if (!selector) { - self.log('animate function without selector'); - self.log(params); - self.log(selectorParams); - } else { - - var elements = self.queryAll(selector); - /* console.log('elements'); - console.log(elements); */ - //var elements = document.querySelectorAll(selector); - if (elements) - elements.forEach(function (element, index) { - if (element) { - //element.classList.add(`${prefix}animated`, animationName); - //console.log(element.classList); - element.classList.add('animate__animated', animationName); - element.style.setProperty('--animate-duration', duration); - } else { - console.log('element'); - console.log(element); - } - }); - - - if (params.on && params.on.start) - self.do(params.on.start, { selector: selector }); - //self.do(params.on.start, undefined, {selector: selector}); - if (params.style) self.css(params, selectorParams); // TO DO: deprecated / to be removed - - - - - - //if (params.infinite) - // node.style.setProperty('--animate-infinite', 'infinite'); - // When the animation ends, we clean the classes and resolve the Promise - function handleAnimationEnd(event) { - if (params.on && params.on.end) { - self.do(params.on.end, { selector: selector }); - //self.do(params.on.end, undefined, {selector: selector}); - /* self.log('handleAnimationEnd'); - self.log('params.on.end'); - self.log(params.on.end); */ - } - - - event.stopPropagation(); - - if (elements) - elements.forEach(function (element, index) { - if (element) - element.classList.remove('animate__animated', animationName); - }); - resolve('Animation ended'); - } - - if (elements) - elements.forEach(function (element, index) { - if (element) - element.addEventListener('animationend', handleAnimationEnd, { once: true }); - }); - } - }); - }; - - /* - this.animation = function (data) { // deprecated - - if (data.animation != undefined) { - if (data.animation == 'show') { - $(data.object).css({'display':'block', opacity:1}); - } else if (data.animation == 'hide') { - $(data.object).css({'display':'none'}); - } else { - //if (data.autoDisplay == undefined) {data.autoDisplay = true}; - //var animationObject = self.cloneObject(animations[data.animation]); - var animationObject = jQuery.extend({}, animations[data.animation]); - //if (data.autoDisplay) - // if (data.animation == 'fadeIn') $(data.object).css({'display':'block'}); - if (data.reverse) {animationObject.name += 'Reverse'} - if (data.duration !== undefined) {animationObject.duration = data.duration} - - animationObject.complete = function () { - if (data.autoDisplay) { - if ((data.animation == 'fadeOut') || (data.animation == 'hide')) { - $('data.object').css({'display':'none'}); - } - } - if (data.onComplete !== undefined) { - self.do(data.onComplete); - } - } - self.log('animationObject.name'); - self.log(animationObject.name); - self.log('animationObject'); - self.log(animationObject); - - // playKeyframe va aggiornato con - // animate({from, to, ease, type, stiffness, dumping, mass, velocity, duration}) - // https://popmotion.io/#quick-start-animation-animate-keyframes-options - //var obj = popmotion.styler($(data.object)); - //popmotion.animate(animationObject).start(obj.set); // $(data.object).css - - $(data.object).playKeyframe(animationObject); - } - } else { - $(data.object).resetKeyframe(); - $(data.object).css({'opacity':1,'display':'block'}); - self.log('ANIMATION UNDEFINED'); - self.log(data); - } - } - - this.move = function (data) { // deprecated - var targetPos = {x:0,y:0}; - if (data.target != 'center') { targetPos = {x:384,y:384}; } - else if (data.target !== undefined) {targetPos = self.getTransform(data.target);} - else {self.log(data);} - if (data.move == 'toTarget') { - TweenMax.to(data.object, self.TweenMaxDuration(data.duration), { x: targetPos.x, y: targetPos.y}); - } else if (data.move == 'fromTarget') { - TweenMax.from(this, self.TweenMaxDuration(data.duration), { x: targetPos.x, y: targetPos.y}); - } - if (data.animation !== undefined) { - self.animation({object:data.object, animation:data.animation}); - } - } - - this.TweenMaxDuration = function (duration) { - if (duration != undefined) {return Number(duration)/1000} else {return 0.667;} - } - */ - // CSS CLASSES - this.addClassRule = function (ruleName, ruleParams) { - //self.log('addClassRule'); - var ruleProperties = '{'; - for (var property in ruleParams) { - if (typeof ruleParams[property] == 'object') { - self.addClassRule(ruleName + ' ' + property, ruleParams[property]); - } else { - ruleProperties += property + ':' + ruleParams[property] + ';'; - } - } - ruleProperties += '}'; - self.styleObj.sheet.insertRule(ruleName + ' ' + ruleProperties); - }; - - this.addApplyRule = function (ruleName, ruleParams) { - // Use @apply to inline any existing utility classes into your own custom CSS - // https://tailwindcss.com/docs/functions-and-directives#apply - self.styleObj.sheet.insertRule(ruleName + ' {@apply ' + ruleParams + '}'); - }; - - this.findPlugin = function (name) { - if (self.json.plugins) { - for (var plugin of self.json.plugins) { - if (plugin.name == name) return plugin; - } - } else { - return false; - } - }; - - this.defineCss = function (cssObj) { - self.log('defineCss'); - - self.styleObj = document.createElement("style"); - - document.head.appendChild(self.styleObj); - self.styleObj.appendChild(document.createTextNode("")); - - /* self.styleObj.sheet.insertRule('@tailwind base;'); - self.styleObj.sheet.insertRule('@tailwind components;'); - self.styleObj.sheet.insertRule('@tailwind utilities;'); */ - // shortcuts (must be improved / can't be extended) - /* if (self.json.shortcuts && self.json.shortcuts.class) - shortcuts = self.json.shortcuts.class; */ - if (cssObj) { - if (Array.isArray(cssObj)) { - for (var cssElement of cssObj) { - //console.log(cssElement); - for (var elementName in cssElement) { - //console.log(elementName); - let valueWithData = self.replaceProperties(cssElement[elementName]); - self.addClassRule(elementName, valueWithData); - } - } - } else { - for (var elementName in cssObj) { - let valueWithData = self.replaceProperties(cssObj[elementName]); - self.addClassRule(elementName, valueWithData); - } - } - } - - if (self.pluginsLoaded.tailwindcss) { - var plugin = self.findPlugin('tailwindcss'); - //var config = (plugin) ? plugin.config : {preflight: false}; - var config = (self.json.setup.config.tailwindcss) ? self.json.setup.config.tailwindcss : { preflight: false }; - //if (self.json.style.theme) setup.theme = self.json.style.theme; - //loadPlugin(undefined, 'tailwind-config', undefined, undefined, JSON.stringify(config)) // version 2.2.0 - if (tailwind) - tailwind.config = config; - - else - console.log('tailwind object is undefined'); - } - - /* // OBSOLETE - if (self.pluginsLoaded.twind && window.twind) { - var plugin = self.findPlugin('twind'); - var config = (plugin) ? plugin.config : {preflight: false, mode:'silent'}; - //if (self.json.setup.target) setup.target = self.query(self.json.setup.target); - //if (self.json.style.theme) setup.theme = self.json.style.theme; - - window.twind.setup(config); - - - } */ - /* if (self.pluginsLoaded.windicss && window.windicssRuntimeOptions) { - - var config = self.json.style.windi || { - // enabled preflight - preflight: false, - // scan the entire dom tree to infer the classnames on page loaded - extractInitial: false, - // generate mock classes for browser to do the auto-completeion - mockClasses: false, - // the windi config you are used to put in `windi.setup.js` - setup: {}, - theme: {extend: {}} - }; - if (self.json.style.theme) setup.theme.extend = self.json.style.theme; - window.windicssRuntimeOptions = config; - } */ - /* if (self.pluginsLoaded.unocss) { - - var config = self.json.style.unocss || { // -> self.json.plugins[].setup - rules: [ - // custom rules... - ], - presets: [ - // custom presets... - ], - // ... - }; - if (self.json.style.theme) setup.theme = self.json.style.theme; - if (self.json.shortcuts) setup.shortcuts = self.json.shortcuts; - - window.__unocss = config; - //alert(JSON.stringify(config)); - } */ - //self.do(data); - }; - - /* this.createLoader = function (data) { - // !--
        Loading...
        --> - - if (self.json.loader) $('.preloader img').attr('src', self.json.loader); - self.do(data); - } */ - /* this.preloadIcons = function (data) { - self.log('preloadIcons'); - // to do: check for duplicated ids - - if (self.json.icons) { - if (!data.icons && self.json.icons) data.icons = self.cloneObject(self.json.icons); - if (data.icons) { - var iconSet = Object.keys(data.icons)[0]; - var icons = data.icons[iconSet]; - delete data.icons[iconSet]; - if (icons.preload) { - - - var ajax = new XMLHttpRequest(); - ajax.open("GET", icons.src, true); - ajax.onload = function(e) { - - if (this.status >= 200 && this.status < 400) { - - self.log('Icon set loaded ' + iconSet); - - var result = this.response; // responseText - //self.log(result); - var div = document.createElement("div"); - //var iconsHtml = new XMLSerializer().serializeToString(result); - var iconsHtml = result; - iconsHtml = self.replaceAll(iconsHtml, 'id="', 'id="' + iconSet + '_'); - div.innerHTML = iconsHtml; - div.setAttribute("style", "display: none"); - //div.setAttribute("aria-hidden", "true"); - //document.getElementbyId('preloadIcons').appendChild(element); - document.body.insertBefore(div, null); - if (Object.keys(data.icons).length > 0) - self.preloadIcons(data); - else - self.do(data); - } - } - ajax.send(); - - } else { - if (Object.keys(data.icons).length > 0) - self.preloadIcons(data); - else - self.do(data); - } - } else - self.do(data); - } else { - self.do(data); - } - } */ - /* this.initApp = function (data) { - self.log('initApp'); - - self.defineCss(); - - window.addEventListener('resize', self.resizeEvent); - - if (self.json) { // can be self.json.init - //if (self.json.on.init) - if (self.json.on) - self.on(self.json.on); - - //else - // self.log('no on init functions'); - } - //self.do(data); - } - */ - /* this.createUI = function (data) { - jsonic.do({ - tasks:[ - {task: self.firebaseInit}, - { - task: self.firebaseVerifyUser, - params: { - code: self.params.oobCode - } - }, - {task: self.getDevices, if: jsonic.userIn}, - {task: self.defineCss}, - {task: self.defineAnimations}, // animazioni css predefinite - {task: self.createHeader}, - {task: self.createMenu, params: { - container: '#menu', - id: data.params.mode || 'guest' - }}, - {task: jsonic.createPages} - ] - }); - } */ - /* this.openPageFromUrl = function(data){ - jsonic.log('openPageFromUrl'); - jsonic.log('self.params'); - jsonic.log(self.params); - - var pageId = ''; - - //if (localStorage.getItem('scanning')) { - // self.hashopenTask({id:localStorage.getItem('scanningFile')}); - //} else { - - //self.disableFileIcons(); - - //var noDevices = (jsonic.userIn() && (!var.db.devices || Object.keys(var.db.devices).length == 0)); - //if (noDevices && !self.params.d && !self.params.m) { - // jsonic.gotoPage('devices'); - //} else { - - if (window.location.hash && window.location.hash !== '') { - //pageId = window.location.hash.substr(1); - self.hash(); - } else { - if (self.params.p) // retro-compatibilità - pageId = self.params.p; - else - pageId = self.homePage(); - self.gotoPage(pageId); - } - - //} - self.do(data); - } -*/ - /* - // Load a script from given `url` - var loadPlugin = function(url) { - return new Promise(function(resolve, reject) { - const script = document.createElement('script'); - script.src = url; - - script.addEventListener('load', function() { - // The script is loaded completely - resolve(true); - }); - - document.head.appendChild(script); - }); - }; - - // Perform all promises in the order - var waterfall = function(promises) { - return promises.reduce( - function(p, c) { - // Waiting for `p` completed - return p.then(function() { - // and then `c` - return c().then(function(result) { - return true; - }); - }); - }, - // The initial value passed to the reduce method - Promise.resolve([]) - ); - }; - - // Load an array of scripts in order - var loadScriptsInOrder = function(arrayOfJs) { - self.log('loadScriptsInOrder'); - self.log(arrayOfJs); - const promises = arrayOfJs.map(function(url) { - self.log(url); - return loadScript(url); - }); - return waterfall(promises); - }; - */ - this.hash = function (path, args) { - self.log('hash'); - var path = self.replaceProperties(path, args); - self.log(path); - window.location.hash = path; - }; - - this.page = function (path, args) { - self.log('page'); - var path = self.replaceProperties(path, args); - self.log(path); - if (path.startsWith('#')) - window.location.hash = path; - - else - window.location.href = path; - //window.location.hash = path; - }; - - this.hashChangeEvent = function () { - self.log('hashChangeEvent'); - self.log(window.location.hash); - - - /* if (window.location.hash && window.location.hash !== '') { - var hashParams = window.location.hash.substr(1).split('/'); - self.gotoPage(hashParams[0], hashParams[1]); - } else { - //pageId = self.homePage(); - if (self.json.setup && self.json.setup.wordpress && self.json.setup.wordpress.slug) - self.gotoPage(self.json.setup.wordpress.slug); - else - self.gotoPage(self.homePage()); - } - - if (json && json.app && json.app.on && json.app.on.page) { // page event - self.do(json.app.on.page); - } - - if (json && json.actions && json.actions.init) { // obsolete - self.do(json.actions.init); - } */ - }; - - /* this.addPageListeners = function (data) { - self.log('addPageListeners'); - - // Resize event - window.addEventListener('resize', self.resizeEvent); - - // Location hash (url) event - window.addEventListener('hashchange', self.hashChangeEvent); - //$(window).on('hashchange', self.hashChangeEvent); - - self.hashChangeEvent(); - - self.do(data); - - } */ - /* // testing - let findValues = function(obj, key, found) { - for (let localKey in obj) { - if (obj.hasOwnProperty(localKey)) { - let val = obj[localKey]; - //self.log(localKey) - if (localKey === key) { - found.add(val) - } else { - if (typeof val === 'object') { - findValues(val, key, found) - } - } - } - } - } - function uniqueValue(obj, key, value) { - let found = new Set() - findValues(object, key, found) - return found.size === 1 && found.has(value); - } */ - this.lookup = function (obj, k) { - for (var key in obj) { - var value = obj[key]; - - if (k == key) { - return [k, value]; - } - - if (typeof (value) === "object" && !Array.isArray(value)) { - var y = lookup(value, k); - if (y && y[0] == k) return y; - } - if (Array.isArray(value)) { - // for..in doesn't work the way you want on arrays in some browsers - // - for (var i = 0; i < value.length; ++i) { - var x = lookup(value[i], k); - if (x && x[0] == k) return x; - } - } - } - - return null; - }; - - this.findValues = function (obj, key) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - let matrix = [...JSON.stringify(obj).matchAll(new RegExp('\"?' + key + '\"?\:\s*\"([^,\"]+)', 'gi'))]; - var results = []; - for (var element of matrix) - results.push(element[1]); - return results; - //return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + key + '\"?\:\s+\"' + value + '\"'))) // JSON5 compatible - }; - - // testing - function findKey(obj, key) { - for ([k, v] of Object.entries(obj)) { - if (k == key) return v; - if (typeof v === 'object' && v !== null) { - let found = findKey(v, key); - if (found) return found; - } - } - } - - - // lookup in json - this.keyInJson = function (obj, string) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + string + '\"?\:'))); // JSON5 compatible - }; - - // lookup in json - this.valueInJson = function (obj, string) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + string + '\"?'))); // JSON5 compatible - }; - - /* this.keyInFiles = function (string) { - var found = self.keyInJson(self.options, string); // in main app options: jsonic = jsonicApp(options) - for (fileName in self.modules) { - if (fileName !== 'resources' && self.keyInJson(self.modules[fileName], string)) - found = true; - } - return found; - } */ - /* this.openPageFromUrl = function (data) { - self.log('openPageFromUrl'); - self.hashChangeEvent(); - self.do(data); - }; */ - /* this.addEventListeners = function (data) { - self.log('addEventListeners'); - - // Resize event - window.addEventListener('resize', self.resizeEvent); - - // Location hash (url) event - window.addEventListener('hashchange', self.hashChangeEvent); - $(window).on('hashchange', self.hashChangeEvent); - - self.hashChangeEvent(); // add here on.hashchange - - // Fullscreen event - if (screenfull && screenfull.isEnabled) { - screenfull.on('change', () => { - self.log('Am I fullscreen?', screenfull.isFullscreen ? 'Yes' : 'No'); - if (screenfull.isFullscreen) { - var.fullscreen = true; - if (var.onFullScreenOpen) self.do(var.onFullScreenOpen); - } else { - var.fullscreen = false; - if (var.onFullScreenClose) self.do(var.onFullScreenClose); - } - }); - } - - if (json && json.app && json.app.on) { - - if (json.app.on.thunkable && json.app.on.thunkable.receiveMessage) - window.receiveMessage(function (message) { - //document.querySelector('#message').value = message; - jsonic.functions(json.app.on.thunkable.receiveMessage, message, undefined); - }); - - var container = json.app.container || 'body'; - self.on(json.app.on, {container: container}); - self.do(data); - } else { - self.do(data); - } - } */ - /* this.loadIconset = function (data) { - self.log('loadIconset'); - - - if (self.json.iconset) { - if (!self.pluginsLoaded['iconify']) { - let plugin = self.json.resources.pluginsFunctions['iconify']; - self.pluginsLoader([plugin], self.loadIconset, [data]); - } else { - var iconset; - - if (!self.json.iconset[0]) - iconset = [self.json.iconset]; - else - iconset = self.json.iconset; - - for (var index in iconset) { - - if (Iconify.addCollection(iconset[index])) - self.log('added iconset '+ iconset[index].prefix); - else - self.log('can\t add iconset '+ iconset[index].prefix); - //alert(x); - } - self.do(data); - - } - - } else { - self.do(data); - } - - } */ - // Si potrebbe creare una nuova istanza di jsonicApp - this.start = function () { - - self.log('start'); - - //if (params.onFullScreenOpen) var.onFullScreenOpen = params.onFullScreenOpen; - //if (params.onFullScreenClose) var.onFullScreenClose = params.onFullScreenClose; - // PWA - /* if ('serviceWorker' in navigator) { - // Register a service worker hosted at the root of the - // site using the default scope. - navigator.serviceWorker.register('/app/assets/pwa/sw.js').then(function(registration) { - self.log('Service worker registration succeeded:', registration); - }, function(error) { - self.log('Service worker registration failed:', error); - }); - } else { - self.log('Service workers are not supported.'); - } */ - let deferredPrompt; - - window.addEventListener('beforeinstallprompt', (e) => { - // Prevent Chrome 67 and earlier from automatically showing the prompt - e.preventDefault(); - // Stash the event so it can be triggered later. - deferredPrompt = e; - }); - - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - self.json.setup.darkMode = e.matches ? "dark" : false; - }); - - // DEFINE ICONSET (iconify) - if (self.json.iconset) { - if (!self.pluginsLoaded['iconify']) { - let plugin = self.json.resources.pluginsFunctions['iconify']; - self.pluginsLoader([plugin], self.start); - return false; - } else { - var iconset; - - if (!self.json.iconset[0]) - iconset = [self.json.iconset]; - - else - iconset = self.json.iconset; - - for (var index in iconset) { - - if (Iconify.addCollection(iconset[index])) - self.log('added iconset ' + iconset[index].prefix); - - else - self.log('can\t add iconset ' + iconset[index].prefix); - //alert(x); - } - - } - - } - - // DEFINE CSS - //self.defineCss(); // TO DO: only additional css (do it on load module success) - // ADD RESIZE LISTENER (for dynamic styles) TO DO: check it - window.addEventListener('resize', self.resizeEvent); - - // PAGE - if (!self.json.setup.page) self.json.setup.page = {}; - self.json.setup.page.hash = window.location.hash.substr(1); - - // DO / ON - /* if (self.json) { - if (self.json.do) - self.do(self.json.do, undefined, self.json.container); - - if (self.json.on) - self.on(self.json.on, self.json.container); - } */ - var selector = self.json.selector || self.json.container; - - /* if (self.json.do) - self.do(self.json.do, undefined, selector); */ - // should go action/run - if (self.json.on) - self.on(self.json.on, selector); - - }; - - this.extendJson = function (jsonBase, jsonExtension) { - // TO DO: should be renamed in extendApp (or executeModule) because extend self.json and add CSS style - if (jsonExtension.css) self.defineCss(jsonExtension.css); - if (jsonExtension.functions) self.extendFunctions(jsonExtension.functions); - - for (var key in jsonExtension) { - // AGGIUNGERE ALL'ARRAY DELLE AZIONI ON.INIT... - if (key == 'on') { - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') { - //jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - if (!jsonBase[key][subKey]) jsonBase[key][subKey] = []; - jsonBase[key][subKey].push(jsonExtension[key][subKey]); - } else { - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } - } - } else if (key == 'parts' || key == 'shortcuts') { // combine subelements - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } - /* } else if (key == 'css') { - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } */ - /* } else if (key == 'app') { // to do: obsolete - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } */ - } else if (key == 'iconset' || key == 'plugins') { // combine arrays - if (!jsonBase[key]) jsonBase[key] = []; - jsonBase[key] = jsonBase[key].concat(jsonExtension[key]); - } else { - if (key == 'css') { - } else { - jsonBase[key] = self.extend({}, jsonBase[key], jsonExtension[key]); - } - } - } - return jsonBase; - }; - - this.loadModuleFromDb = function (data) { - self.log('loadModuleFromDb'); - self.firebaseGet('jsonic', function (result) { - if (result.success) { - self.log('firebase get SUCCESS'); - for (codeKey in result.data) - if (result.data[codeKey].code) - self.extendJson(json, result.data[codeKey].code); - //self.log('json'); - //self.log(json); - //if (params.success) self.do(params.success,result.data); - } else { - self.log('firebase get ERROR'); - //if (params.error) self.do(params.error, result.error); - // alert errore di connessione. alert riprova - } - self.do(data); - //self.do(data); - }); - }; - - this.modules = {}; - this.modulesLoading = {}; - - this.fileType = function (fileName) { - return /(?:\.([^.]+))?$/.exec(fileName)[1]; - }; - - this.jsoncToJson = function (jsoncText) { - return jsoncText.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1').replace(/\r/, "\n").replace(/\n[\n]+/, "\n"); - // https://stackoverflow.com/questions/244777/can-comments-be-used-in-json/24545329 - }; - //var json = jsoncToJson('https://fantacards.com/app/data.jsonc'); - //console.log(json); - this.loadModule = function (mod) { - /* self.log('loadModule'); - self.log(mod); */ - // params: {files, onComplete} - // self.cloneObject(params.json) to avoid to remove from initial params - //if (typeof setup.modules == 'string') setup.modules = [setup.modules]; - if (!self.modulesLoading[mod.name] && !self.modules[mod.name]) { - self.modulesLoading[mod.name] = true; - - return new Promise(function (resolve, reject) { - //mod = self.replaceProperties(mod); - //self.log(mod); - - const getAPIData = new XMLHttpRequest(); - getAPIData.open("GET", mod.url); - getAPIData.onload = function () { - self.modulesLoading[mod.name] = false; - //console.log(getAPIData); - let responseText = getAPIData.responseText; - if (self.fileType(getAPIData.responseURL) == 'jsonc') - responseText = self.jsoncToJson(responseText); - // try - const result = JSON.parse(responseText); - // error self.log('Wrong JSON in module '+ mod.name); - if (self.isJson(result)) { - self.modules[mod.name] = result; - self.extendJson(self.json, result); - self.log('Loaded module ' + mod.name, 'grey'); - } else { - self.log('Wrong JSON in module ' + mod.name, 'red'); - } - resolve(); - }; - getAPIData.onerror = function () { - self.modulesLoading[mod.name] = false; - }; - getAPIData.send(); - }); - - } else { - self.log('Module ' + mod.name + ' already loaded', 'orange'); - } - - - }; - - /* var loadPlugin = function (url) { - //self.log('loading ' + url); - - return new Promise(function(resolve, reject) { - var type = 'script'; - if (url.endsWith('.css')) type = 'link'; - - let obj = document.createElement(type); - - // obj.src = url; - obj.async = false; - obj.onload = function() { - resolve(url); - }; - obj.onerror = function() { - self.log('error loading: '+url); - reject(url); - }; - - if (type === 'script') { - if (url) obj.src = url; - //if (code) obj.text = code; - obj.location = document.body; - document.body.appendChild(obj); - } else { - obj.href = url; - obj.rel = 'stylesheet'; - obj.type = 'text/css'; - obj.location = document.head; - document.head.appendChild(obj); - } - - //self.log('obj'); - //self.log(obj); - }); - } */ - var loadPlugin = function (params) { - //self.log('loading ' + url); - - return new Promise(function (resolve, reject) { - var tag = 'script', type = 'text/javascript'; - if (params.type == 'script') { tag = 'script'; type = 'text/javascript'; } - else if (params.type == 'module') { tag = 'script'; type = 'module'; } - else if (params.type == 'tailwind-config') { tag = 'script'; type = 'tailwind-config'; } - else if (params.type == 'link') { tag = 'link'; type = 'text/css'; } - else if (params.type == 'font') { tag = 'link'; type = undefined; } - //if (!tag) - // tag = (url.endsWith('.js')) ? 'script' : 'link'; - let obj = document.createElement(tag); - if (params.content) - obj.appendChild(document.createTextNode(params.content)); - - obj.async = false; - obj.onload = function () { - self.pluginsLoaded[params.name] = { version: "1.0.0" }; - self.log('Loaded plugin ' + params.name, 'grey'); - resolve(params.url); - }; - obj.onerror = function () { - self.log('Error loading plugin ' + params.url, 'red'); - reject(params.url); - }; - - if (tag === 'script') { - if (params.url) obj.src = params.url; - //if (code) obj.text = code; - obj.location = document.body; - obj.type = type || 'text/javascript'; - /* if (type == 'tailwind-config') { - self.log('obj'); - self.log(obj); - } */ - document.body.appendChild(obj); - } else if (tag === 'link') { - obj.rel = params.rel || 'stylesheet'; - obj.location = document.head; - if (params.url) obj.href = params.url; - if (type) obj.type = type; - if (params.as) obj.as = params.as; - document.head.appendChild(obj); - } - }); - }; - - - /* var loadPlugin = function (url, tag, rel, as) { - //self.log('loading ' + url); - - //alert(url); - - return new Promise(function(resolve, reject) { - if (tag == 'js') tag = 'script'; - if (tag == 'css') tag = 'link'; - if (!tag) - tag = (url.endsWith('.js')) ? 'script' : 'link'; - - let obj = document.createElement(tag); - - obj.async = false; - obj.onload = function() { - self.log('loaded plugin: '+url); - resolve(url); - }; - obj.onerror = function() { - self.log('error loading: '+url); - reject(url); - }; - - if (tag === 'script') { - if (url) obj.src = url; - //if (code) obj.text = code; - obj.location = document.body; - document.body.appendChild(obj); - } else { - obj.href = url; - obj.rel = rel || 'stylesheet'; - if (obj.rel == 'stylesheet') - obj.type = 'text/css'; - if (as) - obj.as = as; - obj.location = document.head; - document.head.appendChild(obj); - } - }); - } - */ - this.uiLoaded = {}; - this.pluginsLoaded = {}; - - //The Firebase Realtime Database lets you store and query user data, and makes it available between users in realtime - this.findUrl = function (array, url) { - for (var item of array) { - if (item.url == url) - return true; - } - }; - - /* this.export = function (params) { - // {name, data} - if (params && params.name && params.data) { - let element = document.createElement('a'); - element.style.display = 'none'; - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(params.data))); - element.setAttribute('download', params.name); - document.body.appendChild(element); - element.click(); - document.body.removeChild(element); - } else { - self.log('"export" requires name and data attributes'); - } - } */ - /* this.exportData = function (path) { - // data - const fileName = self.replaceAll(path, ' ', '.') + '.json'; - const jsonData = self.element({path: path, root: params.root}); - self.export({name: fileName, data: jsonData}); - } - */ - this.loadPlugins = function () { - //self.log('loadPlugins'); - //var setup = json.setup; - // TEMPORAL API - // https://cdn.jsdelivr.net/npm/@cogitatio/tc39-temporal@0.0.12-alpha.2/index.js - // https://cdn.jsdelivr.net/npm/cogitatio-tc39-temporal@1.0.2/index.js - /* */ - var filesToLoad = []; - - // plugins - if (self.json.plugins) { - for (var index in self.json.plugins) { - - var plugin = self.json.plugins[index]; - - //self.log('loading ' + plugin.name + '...'); - var version = plugin.version || ''; - - if (!plugin.ondemand) { // V. >= 1.0.2 - - if (plugin.url) { // directly loaded - // plugin.name and version are needed? - if (!self.findUrl(filesToLoad, plugin.url)) { // not included yet - filesToLoad.push({ name: plugin.name, url: plugin.url, type: plugin.type }); - } - - } else { // from resources (TO DO: remove) - - var pluginsFiles = plugin.files || self.json.resources.pluginsFiles[plugin.name]; - - // moved in loadPlugin = ... onload - /* self.pluginsLoaded[plugin.name] = { - version: version - }; */ - if (!Array.isArray(pluginsFiles)) - pluginsFiles = [pluginsFiles]; - - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (plugin.params) url += '?' + plugin.params; - let pluginName = plugin.name || item.name; - if (!url || !self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({ name: pluginName, url: url, type: item.type, content: item.content }); - } - - } - } - } - } - - // ui - /* for (var index in config.ui) { - - var configUI = config.ui[index]; - - //self.log('loading ' + configUI.name + '...'); - - var version = configUI.version || ''; - var uiFiles = self.json.resources.uiFiles[configUI.name]; - - if (!Array.isArray(uiFiles)) - uiFiles = [uiFiles]; - - for (item of uiFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({url: url, type: item.type, content: item.content}); - } - } */ - // Auto load Google Fonts - // TO DO: comment - for (fontName of self.findValues(self.json, 'font-family')) { - if (self.json.resources.googleFonts.indexOf(fontName) >= 0) { - //alert(fontName); - fontName = self.replaceAll(fontName, ' ', '+'); - //filesToLoad.push({type: 'font', url:'https://fonts.googleapis.com/css2?family='+fontName+'&display=swap', rel:'preload', as:'font'}); - filesToLoad.push({ type: 'link', url: 'https://fonts.googleapis.com/css2?family=' + fontName }); - // +'&display=swap' // https://css-tricks.com/almanac/properties/f/font-display/ - } - } - - // Auto load plugins (firebase only) - /* if (config.plugins && config.plugins.autoload) { - self.log('plugins autoload'); - //for (var index in self.json.resources.pluginsFunctions) { - var pluginFunctions = self.json.resources.pluginsFirebase; // pluginFunctions - for (var index in self.json.resources.pluginsFirebase) { - //self.log(index + ':' + self.keyInFiles(index)); - if (self.keyInFiles(index)) { - if (pluginFunctions[index]) { - - var plugins = []; - if (Array.isArray(pluginFunctions[index])) - plugins = pluginFunctions[index]; - else - plugins = [pluginFunctions[index]]; - - for (plugin of plugins) { - - self.log('loading ' + plugin.name + '...'); - self.pluginsLoaded[plugin.name] = version; - - var version = plugin.version || ''; - var pluginsFiles = self.json.resources.pluginsFiles[plugin.name]; - - if (!Array.isArray(pluginsFiles)) - pluginsFiles = [pluginsFiles]; - - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({url: url, type: item.type, content: item.content}); - } - } - } - } - } - } */ - // load multiple scripts in sequence - // https://bit.ly/3nT5Ky1 - // one after another - // https://medium.com/@asimmittal/sequential-script-loading-in-javascript-a0b77ca9467c - // load multi js and css - // https://sphacks.io/load-multiple-js-scripts-dynamically-without-jquery/ - // save all Promises as array - let promises = []; - - //promises.push(loadPlugin("https://fonts.googleapis.com", 'link', 'preconnect')); - //promises.push(loadPlugin("https://fonts.gstatic.com", 'link', 'preconnect')); - filesToLoad.forEach(function (item) { - if (item.url) - promises.push(loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content })); - - else - loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content }); - //promises.push(loadPlugin(url)); - }); - - - //self.log(filesToLoad); - Promise.all(promises).then(function () { - - self.start(); - - }).catch(function (script) { - self.log('Failed to load'); - self.log(script); - }); - - }; - - this.modulesList = function (modulesObj) { - /* self.log('modulesList'); - self.log('modulesObj'); - self.log(modulesObj); - */ - var modulesList = []; - if (modulesObj) { - for (key in modulesObj) { - var mod = self.replaceProperties(modulesObj[key]); - modulesList = modulesList.concat(mod); - } - } - return self.replaceProperties(modulesObj); - }; - - this.loadModules = function () { - //self.log('loadModules'); - if (self.json.setup.modules) { - var modules = self.replaceProperties(self.json.setup.modules); // replace {page:id} - - - /* self.log('modules'); - self.log(modules); */ - var promises = []; - modules.forEach(function (item) { - if (!self.modulesLoading[item.name] && !self.modules[item.name]) { - promises.push(self.loadModule(item)); - } - }); - - Promise.all(promises).then(function () { - - self.loadPlugins(); - - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - }); - - } else { - self.loadPlugins(); - } - - }; - - this.moduleExecuted = {}; - - this.addModule = function (params) { - - if (!self.modules[params.name]) { - - var promises = []; - //var ideModule = {name: 'ide', url: 'https://jsonic.io/app/modules/ide.json'}; - promises.push(self.loadModule(params)); - - Promise.all(promises).then(function () { - - if (!self.moduleExecuted[params.name]) { - //self.log('all modules loaded'); - var module = self.modules[params.name]; - - if (module.html) { - self.moduleExecuted[params.name] = true; - self.html(module.html); - // TO DO: add also on, funcions ... - } - } - if (params.success) - self.do(params.success); - //self.do(params.success); - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - if (params.error) - self.do(params.error); - //self.do(params.error); - }); - } else { - if (params.success) - self.do(params.success); - //self.do(params.success); - } - }; - - this.loadModuleGlobal = function () { - self.log('loadModuleGlobal'); - - var promises = []; - - var modules = []; // we need it to keep the order of the modules given in the config - for (let key in self.json.setup.modules) { - var mod = self.replaceProperties(self.json.setup.modules[key]); - modules = modules.concat(self.cloneObject(mod)); - } - /* self.log('modules'); - self.log(modules); */ - for (let mod of modules) - promises.push(self.loadModule(mod)); - //var pageModule = {name: 'global', url: '/app/modules/global.json'}; - //var ideModule = {name: 'ide', url: '/app/modules/ide.json'}; - //promises.push(self.loadModule(ideModule)); // if admin - Promise.all(promises).then(function () { - //self.log('page module loaded'); - //if (self.json.modules) { - //self.json.setup.modules = self.cloneObject(self.json.modules); // required modules - //self.json.setup.modules.app.push(pageModule); // page module - //self.json.setup.modules.app.push(ideModule); // ide module if admin - self.loadModules(); - //} - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - }); - }; - - /* this.extendJsonFromModules = function () { - self.log('extendJsonFromModules'); - for (var mod in self.modules) { - //self.extendJsonFromElement(self.modules[mod.name]); - self.extendJson(json, self.modules[mod]); - } - } */ - /* DA SISTEMARE - TEMPORANEO */ - this.code = function (params, selectorParams) { - /* self.log("params"); - self.log(params); - self.log("selectorParams"); - self.log(selectorParams); */ - - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - //var container = self.selector(params) || self.selector(selectorParams); - self.log("this.code"); - self.log("container"); - self.log(container); - - var editorContainer = container.slice(1); - //if (editorContainer.startsWith('#')) {editorContainer.slice(1);} // remove # - var editor = ace.edit(editorContainer); - - var value = params.value; // else value = params; - if (!params.do || (params.do == 'set')) { - - //var langTools = ace.require('ace/ext/language_tools'); - if (params.theme) editor.setTheme(params.theme); // "ace/theme/monokai" - var editorMode = params.mode || "ace/mode/json"; - editor.getSession().setMode(editorMode); - - var editorStyle = self.extend({ - background: "rgba(255,255,255,0)" - }, params.style); - - //$(container).css(editorStyle); //editor.container.style - /* self.css({ - style: editorStyle - }, { - container: container - }); */ // Eventualmente - var codeOptions = self.extend({ - fontSize: "11pt", - selectionStyle: "line", - highlightActiveLine: false, - wrap: true, - showLineNumbers: false, - showGutter: false, - fixedWidthGutter: false, - readOnly: true, - //enableBasicAutocompletion: false, - //enableSnippets: false, - //enableLiveAutocompletion: false, - }, params.options); - - // https://github.com/ajaxorg/ace/wiki/Configuring-Ace - editor.setOptions(codeOptions); - - var codeString; - if (typeof value == 'string') - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(JSON.parse(value), null, '\t'); // json formatting - - else - codeString = value; - else { - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(value, null, '\t'); - else { - var functionObj = self.docElement(value.function); - var functionParams = value.params; - codeString = functionObj(functionParams); - } - } - - var codeRows = codeString.split(/\r\n|\r|\n/).length; - // $(container).css({ - // height: Number(21 * codeRows) + 'px' - // }); - /* self.css({ - style: { - height: Number(21*codeRows)+"px" - } - }, { - container: container - }); */ // Eventualmente - editor.setValue(codeString, -1); - } else if (params.do == 'get') { - return editor.getValue(); - } else { - self.log('"code" function requires value param'); - } - - }; - - this.init = function (appString, modulesString) { - console.log('init'); - // app(String: app url) (Object = json app) - // modules(String): modules "ui,daisyui,svg" - /* json = { // the jsonic app tree - blocks: {}, - parts: {}, - css: {}, - do: {}, - on: {}, - texts: {}, - data: {}, - var: {} - }; */ - //self.app = self.getParams(); // from url - if (typeof appString == 'string') { - - let modules = [{ "name": "app", "url": appString }]; - let modulesNames = (modulesString) ? modulesString.split(",") : []; - for (let modName of modulesNames) { - modules.push({ "name": modName, "url": "jsonic/modules/" + modName + ".json" }); - } - - self.json.setup = { "modules": modules }; - - } else { - - if (appString) self.extendJson(self.json, appString); - - /* // TO DO: remove the requirement of resources.json - if (!self.json.setup || !self.json.setup.modules) { - self.json.setup = { - "modules": [ - { - "name": "resources", - "url": "https://jsonic.io/app/modules/lib/resources.json" - } - ] - } - } */ - if (appString.css) self.defineCss(appString.css); // can be removed? - - } - - self.loadModuleGlobal(); - }; - - function toJsonNode(xml) { - let obj = {}; - if (xml.nodeType == 1) { - if (xml.attributes.length > 0) { - obj["attr"] = {}; - for (let j = 0; j < xml.attributes.length; j++) { - let attribute = xml.attributes.item(j); - obj["attr"][attribute.nodeName] = attribute.nodeValue; - } - } - } - if (xml.hasChildNodes()) { - for (let i = 0; i < xml.childNodes.length; i++) { - let item = xml.childNodes.item(i); - let nodeName = item.nodeName; - if (item.nodeType == 3 && nodeName == "#text") { - if (/^\s+$/.test(item.nodeValue)) { - } else obj.text = item.nodeValue; - } else { - if (typeof obj[nodeName] == "undefined") { - obj[nodeName] = toJsonNode(item); - } else { - if (!Array.isArray(obj[nodeName])) - obj[nodeName] = [obj[nodeName]]; - obj[nodeName].push(toJsonNode(item)); - } - } - } - } - return obj; - } - - this.htmlToJson = function (text) { - let xmlDoc = new DOMParser().parseFromString(text, "text/xml"); - return JSON.stringify(toJsonNode(xmlDoc), null, "\t"); - }; - - this.elementToJson = function (selector) { - let el = document.querySelector(selector); - return self.htmlToJson(el.getHTML()); - }; - - function clearSelection() { - if (window.getSelection) { window.getSelection().removeAllRanges(); } - else if (document.selection) { document.selection.empty(); } - } - - this.importHtml = function (htmlText) { - // use modal and monaco js - if (!htmlText) - htmlText = prompt("html/xml"); - if (htmlText) { - let jsonDoc = self.htmlToJson(htmlText); - let textarea = document.createElement("textarea"); - textarea.value = jsonDoc; - textarea.style = "position: absolute; z-index: 999999; background: white; width:100vw; height:100vh"; - //document.body.innerHTML = ''; - document.body.appendChild(textarea); - //document.execCommand("copy"); - textarea.addEventListener('click', function () { - textarea.remove(); - navigator.clipboard.writeText(textarea.value).then(() => console.log('copied!')); - }); - //console.log(JSON.parse(jsonDoc)); - } - }; - - // https://github.com/ktskts/html2json/blob/master/src/html2json.js - /* - var Util = { - div : null, - attrs: "id,name,style,class,value,src,href,width,height,title,type".split(","), - getJson: function(childNodes, attrs, length) { - var result = []; - for ( var i = 0, len = childNodes.length; i < len; i++) { - var item = childNodes[i]; - if (item.nodeType == 3) { // textual content in an element or attribute - result.push({ - text : item.nodeValue - }) - } else if (item.nodeType == 1) { // element - var obj = { - //tag : item.nodeName.toLowerCase(), - attr : {} - }; - var flag = false; - //for ie6 - if (attrs) { - for (var j = 0; j < length; j++){ - if (attrs[j] == 'style'){ - var sStyle = item.getAttribute('style').cssText; - if(sStyle){ - obj.attr["style"] = sStyle; - flag = true; - } - } else { - var attrNode = item.attributes[attrs[j]]; - if(attrNode && attrNode.nodeType === 2){ - var value = attrNode.value; - if(value && value != 'null'){ - obj.attr[attrs[j]] = value; - flag = true; - } - } - } - } - } else { - if (item.attributes.length) { - for ( var n = 0, l = item.attributes.length; n < l; n++) { - var value = item.attributes[n].value; - if(value){ - flag = true; - obj.attr[item.attributes[n].name] = value; - } - } - } - } - - let nodeOut = {}; - let nodeTag = item.nodeName.toLowerCase(); - let nodeChild = Util.getJson(item.childNodes, attrs, length); - nodeOut[nodeTag] = {}; - - - self.log( 'item.childNodes'); - self.log( item.childNodes); - self.log( 'nodeChild'); - self.log( nodeChild); - //self.log( item.textContent); - - - nodeOut[nodeTag].html = nodeChild; - if (flag) nodeOut[nodeTag].attr = obj.attr; - result.push(nodeOut); - - } else { - // do nothing - } - } - if (result.length == 1) return result[0] - else if (result.length > 1) return result; - } - } - - this.html2json = function(text) { - if (!Util.div) Util.div = document.createElement('div'); - Util.div.innerHTML = text; - return {html: Util.getJson(Util.div.childNodes)}; - }; - */ - /* var jsonicOptions = self.extend({ - }, options); */ - if (typeof options == 'object') { - } else if (options) - self.init(arguments[0], arguments[1]); - - -} // of jsonicObject - -//var jsonicApp = jsonApp; -var jsonApp = new jsonAppObj(); -var js = jsonApp; -var jsonic = jsonApp; - -//window.jsonic = new jsonicObject(); - -/* var receiveMessage = function (process) { - if (ThunkableWebviewerExtension) - ThunkableWebviewerExtension.receiveMessage(process); -} - -var postMessage = function (message) { - if (ThunkableWebviewerExtension) - ThunkableWebviewerExtension.postMessage(message); -} */ - -/* "on": { - "init": [ - { - "thunkable": { - "postMessage": "Hi Rick!" - } - }, - { - "thunkable": { - "receiveMessage": { - "alert": "message: {result}" - } - } - } - ] -} - */ diff --git a/jsonic/js/jsonic.1.0.14.js b/jsonic/js/jsonic.1.0.14.js deleted file mode 100644 index a1b639d..0000000 --- a/jsonic/js/jsonic.1.0.14.js +++ /dev/null @@ -1,10711 +0,0 @@ - - - -/* - Method: jsonAppObj -Description: Functionality for jsonAppObj. -@param {any} options - Description for options -@returns {any} - Result of the operation - */ -var jsonAppObj = function (options) { - - var self = this; - console.log(); - - this.json = { - setup: {}, - blocks: {}, - parts: {}, - - functions: {}, - do: {}, - on: {}, - shortcuts: {}, - texts: {}, - data: {}, - var: {} - }; - this.app = this.json; - - var alertObj = {}; - var alertValues = {}; - this.params = {}; - - this.javascriptReservedWord = ['abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield', 'Array', 'Date', 'eval', 'function', 'hasOwnProperty', 'Infinity', 'isFinite', 'isNaN', 'isPrototypeOf', 'length', 'Math', 'NaN', 'name', 'Number', 'Object', 'prototype', 'String', 'toString', 'undefined', 'valueOf', 'getClass', 'java', 'JavaArray', 'javaClass', 'JavaObject', 'JavaPackage', 'alert', 'all', 'anchor', 'anchors', 'area', 'assign', 'blur', 'button', 'checkbox', 'clearInterval', 'clearTimeout', 'clientInformation', 'close', 'closed', 'confirm', 'constructor', 'crypto', 'decodeURI', 'decodeURIComponent', 'defaultStatus', 'document', 'element', 'elements', 'embed', 'embeds', 'encodeURI', 'encodeURIComponent', 'escape', 'event', 'fileUpload', 'focus', 'form', 'forms', 'frame', 'innerHeight', 'innerWidth', 'layer', 'layers', 'link', 'location', 'mimeTypes', 'navigate', 'navigator', 'frames', 'frameRate', 'hidden', 'history', 'image', 'images', 'offscreenBuffering', 'open', 'opener', 'option', 'outerHeight', 'outerWidth', 'packages', 'pageXOffset', 'pageYOffset', 'parent', 'parseFloat', 'parseInt', 'password', 'pkcs11', 'plugin', 'prompt', 'propertyIsEnum', 'radio', 'reset', 'screenX', 'screenY', 'scroll', 'secure', 'select', 'self', 'setInterval', 'setTimeout', 'status', 'submit', 'taint', 'text', 'textarea', 'top', 'unescape', 'untaint', 'window', 'onblur', 'onclick', 'onerror', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onmouseover', 'onload', 'onmouseup', 'onmousedown', 'onsubmit']; - - var nodes = { - - extend: ['setup', 'blocks', 'parts', 'css', 'actions', 'texts', 'data', 'functions'], - params: ['style', 'on', 'matchMedia', 'action', 'code', 'roles', 'plugins', 'css'], - exclude: ['setup', 'container', 'selector', 'info', 'note', 'comment', 'lang', 'tag', 'plugins', 'template'] - }; - - const FORMAT_REGEX = { - email: /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/, - url: /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, - ip: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, - - date: /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/, - - color: /^#(?:[0-9a-fA-F]{3}){1,2}$|#(?:[0-9a-fA-F]{3,4}){1,2}$/, - }; - - -/* - Method: jsonToSchema -Description: Functionality for jsonToSchema. -@param {any} json - Description for json -@param {any} options = {} - Description for options = {} -@returns {any} - Result of the operation - */ -this.jsonToSchema = function (json, options = {}) { - - if (typeof json === 'function') { - throw new TypeError('Can not convert a function'); - } - - if (json === undefined) { - return {}; - } - - if (typeof json === 'string') { - - if (FORMAT_REGEX.url.test(json)) return { type: 'string', format: 'url' }; - else if (FORMAT_REGEX.email.test(json)) return { type: 'string', format: 'email' }; - else if (FORMAT_REGEX.ip.test(json)) return { type: 'string', format: 'ip' }; - else if (FORMAT_REGEX.date.test(json)) return { type: 'string', format: 'date' }; - else if (FORMAT_REGEX.color.test(json)) return { type: 'string', format: 'color' }; - else return { type: 'string' }; - } - - else if (typeof json === 'boolean') return { type: 'boolean' }; - - else if (typeof json === 'number') { - if (Number.isInteger(json)) { - return { type: 'integer' }; - } else { - return { type: 'number' }; - } - } - - else if (Array.isArray(json)) { - let schema = { type: 'array' }; - - if (!json.length) { - schema.items = {}; - return schema; - } - - let schemas = json.map(self.jsonToSchema); - - if (schemas.every(s => self.isEqual(s, schemas[0]))) { - schema.items = schemas[0]; - - } else { - schema.items = { oneOf: unique(schemas) }; - } - - return schema; - } - - if (json === null) { - return { type: 'null' }; - } - - let schema = { type: 'object' }; - - if (!Object.keys(json).length) { - return schema; - } - - schema.properties = Object.keys(json).reduce((properties, key) => { - properties[key] = self.jsonToSchema(json[key]); - return properties; - }, {}); - - return schema; - }; - - -/* - Method: isEqual -Description: Functionality for isEqual. -@param {any} a - Description for a -@param {any} b - Description for b -@returns {any} - Result of the operation - */ -this.isEqual = function (a, b) { - return (JSON.stringify(a) == JSON.stringify(b)); - }; - - this.dataStorage = { - _storage: new WeakMap(), - set: function (element, key, obj) { - if (!this._storage.has(element)) { - this._storage.set(element, new Map()); - } - this._storage.get(element).set(key, obj); - }, - get: function (element, key) { - return this._storage.get(element).get(key); - }, - has: function (element, key) { - return this._storage.has(element) && this._storage.get(element).has(key); - }, - remove: function (element, key) { - var ret = this._storage.get(element).delete(key); - if (!this._storage.get(element).size === 0) { - this._storage.delete(element); - } - return ret; - } - }; - - -/* - Method: extend -Description: Functionality for extend. -@param {any} out - Description for out -@returns {any} - Result of the operation - */ -this.extend = function (out) { - - if (typeof arguments[0] == 'boolean' && arguments[0] == true) - return deepExtend(out); - else { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - if (!arguments[i]) - continue; - - for (var key in arguments[i]) { - if (arguments[i].hasOwnProperty(key)) - out[key] = arguments[i][key]; - } - } - return out; - } - }; - - -/* - Method: deepExtend -Description: Functionality for deepExtend. -@param {any} out - Description for out -@returns {any} - Result of the operation - */ -var deepExtend = function (out) { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - var obj = arguments[i]; - - if (!obj) continue; - - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - if (typeof obj[key] === "object" && obj[key] !== null) { - if (obj[key] instanceof Array) out[key] = obj[key].slice(0); - else out[key] = deepExtend(out[key], obj[key]); - } else out[key] = obj[key]; - } - } - } - - return out; - }; - - -/* - Method: var -Description: Functionality for var. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.var = function (params, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.var(params[index], args); - } else { - - var name; - var value; - var varValue; - - if (params.path && !params.name) - name = self.path(params.path, args, '.'); - - if (typeof params == 'string') { - - name = self.replaceProperties(params, args); - - varValue = self.docElement('self.json.var.' + name); - - } else { - - var paramsReplaced = self.replaceProperties(params, args); - - name = paramsReplaced.name; - value = paramsReplaced.value; - var operator = paramsReplaced.operator; - var type = paramsReplaced.type; - - if (name) { - var pathString = 'self.json.var.' + name; - var pathLast = pathString.substr(pathString.lastIndexOf(".") + 1); - var pathBase = pathString.substr(0, pathString.lastIndexOf(".")); - var varObj = self.docElement(pathBase); - - if (value !== undefined) { - - value = self.actionResult(value, args); - - switch (type) { - case 'string': value = String(value); break; - case 'number': value = Number(value); break; - case 'boolean': value = Boolean(value); break; - case 'array': value = JSON.parse(value); break; - case 'object': value = JSON.parse(value); break; - } - - if (varObj && pathLast) { - switch (operator) { - case '+=': varObj[pathLast] += value; break; - case '-=': varObj[pathLast] -= value; break; - case '/=': varObj[pathLast] /= value; break; - case '*=': varObj[pathLast] *= value; break; - default: varObj[pathLast] = value; break; - } - - varValue = varObj[pathLast]; - } else { - - self.docElement(pathString, value); - - } - - } else if (paramsReplaced.push) { - if (varObj && pathLast && varObj[pathLast]) { - varObj[pathLast] = varObj[pathLast].push(paramsReplaced.push); - varValue = varObj[pathLast]; - } - } else if (paramsReplaced.extend) { - if (varObj && pathLast && varObj[pathLast]) { - varObj[pathLast] = self.extend({}, varObj[pathLast], paramsReplaced.extend); - varValue = varObj[pathLast]; - } - } else { - - varValue = varObj[pathLast]; - - } - - } else { - self.log('var name undefined'); - self.log(params); - varValue = undefined; - } - - if (params.do && params.do.length > 0) { - self.log('this.var params.do'); - self.log(params.do); - - self.do(params.do, undefined, args); - } - - } - - return varValue; - - } - }; - - -/* - Method: find -Description: Functionality for find. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.find = function (params, args) { - if (params.in) { - var list = self.replaceProperties(params.in, args); - return list.filter(function (item) { - if (params.value) { - if (typeof params.value == 'string') { - if (JSON.stringify(item).indexOf(params.value) >= 0) - return item; - } else { - for (var key in params.value) { - if (params.value[key] == item[key]) - return item; - } - } - } - }); - } - }; - - -/* - Method: array -Description: Functionality for array. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.array = function (params, args) { - - if (args) - params = self.replacePropertyWithPrefix(params, 'result', args); - - for (var par in params) { - var paramReplaced = self.replaceProperties(params[par], args); - - params[par] = paramReplaced; - } - - var value = self.element({ path: params.name }) || []; - - if (params.push) { - if (Array.isArray(params.push)) - value.push(...params.push); - - else - value.push(params.push); - - } - if (params.unshift) value.unshift(...params.unshift); - if (params.pop) return value.pop(params.pop); - if (params.shift) return value.shift(params.shift); - - self.element({ path: params.name, value: value }); - - }; - - -/* - Method: replace -Description: Functionality for replace. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.replace = function (params, args) { - - params = self.replacePropertyWithPrefix(params, 'result', args); - - var value = self.element({ path: params.path }) || []; - var to = params.to || ''; - - var type = typeof value; - - if (type !== "string") value = JSON.stringify(value); - - if (params.from) value = self.replaceAll(value, params.from, to); - - switch (type) { - case "number": - value = Number(value); - break; - case "boolean": - value = Boolean(value); - break; - case "object": - value = JSON.parse(value); - break; - } - - return self.element({ path: params.path, value: value }); - - }; - - -/* - Method: unshift -Description: Functionality for unshift. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.unshift = function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.unshift(value); - self.element({ path: path, value: obj }); - } - } - }; - - -/* - Method: set -Description: Functionality for set. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.set = function (params, args) { - - if (Array.isArray(params)) { - for (var obj of params) - self.set(obj, args); - } else { - for (var param in params) { - - var value = params[param]; - - if (value) value = self.replaceProperties(value, args, false); - if (value && args) value = self.replacePropertyWithPrefix(value, 'result', args); - - self.element({ path: param, value: value }); - } - } - - }; - - -/* - Method: get -Description: Functionality for get. -@param {any} element - Description for element -@returns {any} - Result of the operation - */ -this.get = function (element) { - - if (element.startsWith('\'')) - return String(element.match(/\'([^\']*)\'/)[1]); // stringa racchiusa tra apici (serve?) - else if (element.startsWith('Boolean')) - return Boolean(element.match(/Boolean\(([^\)]*)\)/)[0]); // Boolean(x) - else if (element.startsWith('Number')) - return Number(element.match(/Number\(([^\)]*)\)/)[0]); // Number(x) - else if (element.startsWith('String')) - return String(element.match(/String\(([^\)]*)\)/)[0]); // String(x) - - else - return (self.docElement(element)); // ora le tipizzazioni sono già in docElement grazie a eval - }; - - -/* - Method: getJSON -Description: Functionality for getJSON. -@param {any} url - Description for url -@param {any} callback - Description for callback -@returns {any} - Result of the operation - */ -this.getJSON = function (url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'json'; - xhr.onload = function () { - var status = xhr.status; - if (status === 200) { - callback(null, xhr.response); - } else { - callback(status, xhr.response); - } - }; - xhr.send(); - }; - - /*--------------------- - var - ---------------------*/ - var database, auth, storage; - this.listeners = {}; - this.resizeActions = {}; - - /* var iconsFile; - - this.device = false; // touch device - this.touch = 'mousedown'; if (this.device) {this.touch = 'touchstart';} - - var animations = {}; - var tweenLoading; - - var tasksIntervals = {}; - var timedTasks = {'yearly':{},'monthly':{},'daily':{},'hourly':{}, '10mins':{}, '5mins':{}, '30mins':{}, '1min':{}, '30sec': {}, '10sec': {}, '1sec': {}}; */ - /* this.dateSelection; // = {day:0, month:0, year:0}; - this.timeSelection = {hour:0, min:0, sec:0, ampm:'AM', allday:true}; - this.timeSelectionCallback = null; */ - /*-------------------- - FIREBASE - --------------------*/ - //var firebaseInitialized = false; - -/* - Method: firebaseVerifyUser -Description: Functionality for firebaseVerifyUser. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.firebaseVerifyUser = function (data) { - self.log('firebaseVerifyUser'); - //self.log(data); - //self.log(data.code); - if (self.params.oobCode) { - var oobCode = self.params.oobCode; - - auth.applyActionCode(oobCode).then(function (resp) { - // self.log('resp'); - // self.log(resp); - self.alert({ - //toast: true, - icon: "success", - title: "titVerifyEmail", - html: "msgVerifyEmail", - confirmButtonText: "btnOk", - //showCancelButton: false, - confirm: function () { - //self.reload(); - // self.do(data); - window.location.href = "/app/index.html"; - } - }); - }).catch(function (error) { - self.log('error'); - self.alert({ - icon: "error", - title: "titWarning", - html: error.code + " - " + error.message, - confirmButtonText: "btnOk", - //showCancelButton: false, - confirm: function () { - // self.reload(); - // self.do(data); - window.location.href = "/app/index.html"; - } - }); - }); - // verifica su auth - } - //data.code / data.params.code - //self.do(data); - self.do(data); - }; - - /* -/* - Method: firebaseInit -Description: Functionality for firebaseInit. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.firebaseInit = function (data) { - self.log("firebaseInit"); - - if (json.setup && json.setup.firebase) { - //var.databaseURL = json.setup.firebase.databaseURL; - - firebase.initializeApp(json.setup.firebase); - database = firebase.database(); - auth = firebase.auth(); - // if (self.json.plugins['firebase-storage'].active) OR find in self.json.plugins name: 'firebase-storage' - //storage = firebase.storage(); - - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - // No user logged in - self.log('onAuthStateChanged:GUEST\n'); - // non bisognerebbe chiedere sempre di fare login - } else { - // User logged in - self.log('onAuthStateChanged:USER\n'); - self.log('name: '+self.user('displayName') + '\nemail: '+user.email + '\nuid: '+ user.uid); - } - //self.log('firebaseInitialized'); - //self.log(firebaseInitialized); - if (!firebaseInitialized) { - firebaseInitialized = true; - self.do(data); - } - }); - } else { - self.do(data); - } - } */ - -/* - Method: sendMail -Description: Functionality for sendMail. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.sendMail = function (data) { - self.log('sendMail'); - - var emailParams = { - Host: "smtp.mailgun.com", - Username: "vito@nuvolaria.com", - Password: "bee02191be84c784a665fa98c61e03ce-915161b7-d32cb9d0", - From: data.from, - To: data.to, - Subject: data.subject, - Body: data.html - }; - - Email.send(emailParams).then( - message => self.alert({ - icon: 'success', - title: 'titEmailSuccess', - confirmButtonText: 'btnClose' - }) - ); - - /* - "from": "gianfrancoguglielmi@gmail.com", - "to": "vito.minchilli@gmail.com", - "subject": "Prova oggetto", - "html": "Prova testo", - "text": "Prova testo" -*/ - /* - var SERVER_NODEJS_BASEURL='https: - - var params = { - rom: data.from, - to: data.to, - subject: data.subject, - html: data.html, - text: data.text - }; - - $.ajax({ - type: "POST", - 'beforeSend': function(xhr) { - xhr.setRequestHeader('Accept', 'application/json'); - xhr.setRequestHeader('Content-Type', 'application/json'); - }, - data: JSON.stringify(params), - url: SERVER_NODEJS_BASEURL + '/sendMail', - success: function(data) { - self.log('sendMail SUCCESS'); - self.log(data); - self.do(data); - }, - error: function(error) { - self.log('sendMail ERROR'); - self.log(error); - self.do(data); - } - }); - */ - }; - - var x = [{ if: 3 }, function () { }, 3, []]; - - -/* - Method: firebaseAddListener -Description: Functionality for firebaseAddListener. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.firebaseAddListener = function (params) { - - if (database) { - - if (params.action) { - if (!self.listeners[params.path]) self.listeners[params.path] = []; - - self.listeners[params.path].push(params.action); - } - - var dbRef = database.ref(params.path); - dbRef.off(); - if (params.orderByChild) dbRef = dbRef.orderByChild(params.orderByChild); - if (params.orderByKey) dbRef = dbRef.orderByKey(params.orderByKey); - if (params.orderByValue) dbRef = dbRef.orderByValue(params.orderByValue); - if (params.equalTo) dbRef = dbRef.equalTo(params.equalTo); - if (params.startAt) dbRef = dbRef.startAt(params.startAt); - if (params.startAfter) dbRef = dbRef.startAfter(params.startAfter); - if (params.endAt) dbRef = dbRef.endAt(params.endAt); - if (params.endBefore) dbRef = dbRef.endBefore(params.endBefore); - if (params.limitToFirst) dbRef = dbRef.limitToFirst(params.limitToFirst); - if (params.limitToLast) dbRef = dbRef.limitToLast(params.limitToLast); - if (params.where) dbRef = dbRef.where(params.where[0], params.where[1], params.where[2]); - - var feedback = dbRef.on('value', firebaseEvent); - - } else { - self.log('database undefined'); - - } - }; - - -/* - Method: firebaseEvent -Description: Functionality for firebaseEvent. -@param {any} snapshot - Description for snapshot -@returns {any} - Result of the operation - */ -var firebaseEvent = function (snapshot) { - console.log(snapshot.val()); - var ref = snapshot.ref; - if (snapshot.val() !== undefined) { - var dbVal = snapshot.val(); - var path = snapshot.ref.toString(); - - var pathArr = path.split(/\.\w+\ - var dbPath = pathArr[1]; - self.log('firebaseEvent: ' + dbPath); - - if (dbVal) - self.localDbUpdate(dbVal, dbPath); - else { - var dbObj = self.element({ path: 'self.json.var.db.' + self.replaceAll(dbPath, '/', '.') }); - if (dbObj) - dbObj = null; - - } - - } - }; - - -/* - Method: localDbUpdate -Description: Functionality for localDbUpdate. -@param {any} newObj - Description for newObj -@param {any} dbPath - Description for dbPath -@returns {any} - Result of the operation - */ -this.localDbUpdate = function (newObj, dbPath) { - - newObj = Object.fromEntries(Object.entries(newObj).reverse()); - - self.element({ path: 'self.json.var.db.' + self.replaceAll(dbPath, '/', '.'), value: newObj }); - if (self.listeners[dbPath] !== undefined && self.listeners[dbPath] !== null && self.listeners[dbPath].length > 0) { - newObj.path = dbPath; - if (self.listeners[dbPath]) { - self.methods.firebaseEvent.action(newObj); - - self.do(self.listeners[dbPath], undefined, newObj); - } - } - - }; - - -/* - Method: firebaseRemoveListener -Description: Functionality for firebaseRemoveListener. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.firebaseRemoveListener = function (params) { - - self.log('firebaseRemoveListener'); - if (self.listeners[params.path]) { - delete self.listeners[params.path]; - var dbRef = database.ref(params.path); - dbRef.off(); - } - }; - - -/* - Method: firebaseRemove -Description: Functionality for firebaseRemove. -@param {any} path - Description for path -@param {any} callback - Description for callback -@returns {any} - Result of the operation - */ -this.firebaseRemove = function (path, callback) { - self.log('firebaseRemove'); - self.log(path); - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.remove(function (error) { - - if (error == null) { - self.log('set SUCCESS'); - result = { success: true }; - } else { - self.log('set ERROR'); - - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - -/* - Method: firebaseSet -Description: Functionality for firebaseSet. -@param {any} path - Description for path -@param {any} value - Description for value -@param {any} callback - Description for callback -@returns {any} - Result of the operation - */ -this.firebaseSet = function (path, value, callback) { - - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.set(value, function (error) { - - if (error == null) { - self.log('set SUCCESS'); - result = { success: true }; - } else { - self.log('set ERROR'); - - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - -/* - Method: firebaseUpdate -Description: Functionality for firebaseUpdate. -@param {any} path - Description for path -@param {any} value - Description for value -@param {any} callback - Description for callback -@returns {any} - Result of the operation - */ -this.firebaseUpdate = function (path, value, callback) { - self.log('firebaseUpdate'); - self.log('path'); - self.log(path); - self.log('value'); - self.log(value); - - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.update(value, function (error) { - - if (error == null) { - self.log('update SUCCESS'); - result = { success: true }; - } else { - self.log('update ERROR'); - - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - -/* - Method: firebasePush -Description: Functionality for firebasePush. -@param {any} path - Description for path -@param {any} value - Description for value -@param {any} callback - Description for callback -@returns {any} - Result of the operation - */ -this.firebasePush = function (path, value, callback) { - self.log('firebasePush'); - self.log(path); - - if (database) { - var result, dbRef; - if (path) { - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - return dbRef.push(value, function (error) { - - if (error == null) { - self.log('push SUCCESS'); - result = { success: true }; - } else { - self.log('push ERROR'); - - result = { success: false, error: error }; - } - if (callback) callback(result); - }); - } else { - self.log('database not initialized'); - } - }; - - -/* - Method: firebaseGetPart -Description: Functionality for firebaseGetPart. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.firebaseGetPart = function (params) { - self.log('firebaseGetPart'); - let remotePath = self.replaceAll(params.localPath, '.', '/'); - - self.log('localPath:' + params.localPath); - - if (self.partContainers[params.localPath]) { - self.partContainers[params.localPath].push(params); - } else { - self.partContainers[params.localPath] = []; - self.partContainers[params.localPath].push(params); - - dbRef = database.ref().child(remotePath); - - return dbRef.once('value').then(function (object) { - - if (object) { - self.log('firebaseGetPart SUCCESS'); - self.log(object); - - if (object.val() !== undefined) { - window.dbVal = object.val(); - var dbVal = object.val(); - self.log('dbVal'); - self.log(dbVal); - if (dbVal !== null) { - let fullPath = object.ref.toString(); - let pathArr = fullPath.split(/\.\w+\ - let dbPath = pathArr[1]; - let localPath = self.replaceAll(dbPath, '/', '.'); - - self.log('dbPath: ' + dbPath); - self.log('localPath: ' + localPath); - - self.element({ path: localPath, value: dbVal }); - for (partObj of self.partContainers[localPath]) { - - let part = self.replacePropertyWithPrefix(dbVal, 'setup', partObj.setup); - part = self.replacePropertyWithPrefix(part, 'arg', partObj.arg); - self.extendJsonFromElement(part); - - self.html(part, partObj.container); - - } - } - } - } else { - self.log('firebaseGetPart ERROR'); - result = { success: false, error: 8 }; - } - - }); - } - }; - - -/* - Method: firebaseIncrease -Description: Functionality for firebaseIncrease. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.firebaseIncrease = function (params) { - console.log('firebaseIncrease'); - self.firebaseGet(params.path, function (result) { - console.log(result); - if (result.success) { - if (result.data === null || result.data === undefined || typeof result.data == 'number') { - var counter = Number(result.data) + 1; - console.log('counter:' + counter); - self.firebaseSet(params.path, counter, function (result) { - if (result.success) { - self.log('firebaseIncrease SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - }); - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - } else { - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - } - }); - }; - - -/* - Method: firebaseGet -Description: Functionality for firebaseGet. -@param {any} path - Description for path -@param {any} callback - Description for callback -@returns {any} - Result of the operation - */ -this.firebaseGet = function (path, callback) { - self.log('firebaseGet:' + path); - var result = { success: false, error: 7 }; - if (path) { - - dbRef = database.ref().child(path); - } else { - dbRef = database.ref(); - } - - return dbRef.once('value').then(function (object) { - - if (object) { - self.log('get SUCCESS'); - result = { success: true, error: null, data: object.val() }; - - if (object.val() !== undefined) { - var dbVal = object.val(); - var path = object.ref.toString(); - if (!dbVal) dbVal = {}; - var pathArr = path.split(/\.\w+\ - var dbPath = pathArr[1]; - - self.log('dbPath: ' + dbPath); - self.localDbUpdate(dbVal, dbPath); - } - } else { - self.log('get ERROR'); - - result = { success: false, error: 8 }; - } - - callback(result); - }); - - }; - - -/* - Method: stringToKey -Description: Functionality for stringToKey. -@param {any} str - Description for str -@returns {any} - Result of the operation - */ -this.stringToKey = function (str) { - return str.replace(/\./g, '%2E'); - }; - - -/* - Method: keyToString -Description: Functionality for keyToString. -@param {any} key - Description for key -@returns {any} - Result of the operation - */ -this.keyToString = function (key) { - return key.replace(/%2E/g, '.'); - }; - - this.firebaseKey = -/* - Method: getKey -Description: Functionality for getKey. -@param {any} path - Description for path -@returns {any} - Result of the operation - */ -this.getKey = function (path) { - var dbRef = database.ref(path); - return dbRef.child(path).push().getKey(); - }; - - -/* - Method: exist -Description: Functionality for exist. -@param {any} selector - Description for selector -@returns {any} - Result of the operation - */ -this.exist = function (selector) { - console.log('selector'); - console.log(selector); - console.log(Boolean(self.query(selector))); - return Boolean(self.query(selector)); - }; - - -/* - Method: count -Description: Functionality for count. -@param {any} selector - Description for selector -@returns {any} - Result of the operation - */ -this.count = function (selector) { - - return self.queryAll(selector).length; - - }; - - -/* - Method: log -Description: Functionality for log. -@param {any} id - Description for id -@param {any} value - Description for value -@returns {any} - Result of the operation - */ -var log = function (id, value) { - self.log(id); - self.log(value); - }; - - -/* - Method: classSelector -Description: Functionality for classSelector. -@param {any} selClass - Description for selClass -@returns {any} - Result of the operation - */ -this.classSelector = function (selClass) { - if (selClass.indexOf('.') == 0) { selClass = String(selClass).substr(1); } - let classes = selClass.split(' '); - selClass = classes[0]; - - var regex = new RegExp('[\-][\[]'); - if (selClass && selClass.match(regex)) selClass = classes[1]; - if (selClass && selClass.match(regex)) selClass = classes[2]; - return selClass; - }; - - -/* - Method: selector -Description: Functionality for selector. -@param {any} params - Description for params -@param {any} containerParams - Description for containerParams -@param {any} selectAll - Description for selectAll -@returns {any} - Result of the operation - */ -this.selector = function (params, containerParams, selectAll) { - - var selector; - - if (params) { - - if (typeof params == 'string') { - - return params; - } else if (Array.isArray(params)) { - return params; - } else { - var selContainer; - - if (params.selector || params.container) - selContainer = params.selector || params.container; - - else if (containerParams) - selContainer = containerParams.selector || containerParams.container; - - var attr = (params.attr) ? params.attr : {}; - var selId = (attr.id) ? attr.id : params.id; - var selClass = (attr.class) ? attr.class : params.class; - var selValue = (attr.value) ? attr.value : params.value; - var selDataValue = (attr['data-value']) ? attr['data-value'] : params['data-value']; - selValue = selDataValue || selValue; - if (selId) selId = self.replaceProperties(selId); - if (selValue) selValue = self.replaceProperties(selValue); - if (selClass) selClass = self.replaceProperties(selClass); - - if (selClass) - selClass = self.classSelector(selClass); - - if (selId) { - selector = '#' + selId; - } else if (selValue && selClass) { - selector = '.' + selClass + '[data-value="' + selValue + '"]'; - } else if (selValue && params.tag) { - selector = params.tag + '[data-value="' + selValue + '"]'; - } else if (selClass && selectAll) { - selector = '.' + selClass; - - } else if (params.tag) { - - selector = params.tag; - if (selContainer) { - selector = selContainer + ' > ' + params.tag; - if (!selectAll) { - - selector += ':eq(' + self.count(selector) + ')'; - - } - } else { - if (!selectAll) { - selector += ':eq(' + self.count(selector) + ')'; - - } - } - } else { - selector = selContainer; - }; - - } - return selector; - } - }; - - -/* - Method: stringify -Description: Functionality for stringify. -@param {any} obj - Description for obj -@returns {any} - Result of the operation - */ -this.stringify = function (obj) { - if (typeof obj == 'object') - try { - return JSON.stringify(obj); - } catch (error) { - return obj; - } - - else - return obj; - - }; - - -/* - Method: parse -Description: Functionality for parse. -@param {any} str - Description for str -@returns {any} - Result of the operation - */ -this.parse = function (str) { - if (typeof str == 'string') - try { - return JSON.parse(str); - } catch (error) { - return str; - } - - else - return str; - }; - - self.setupId = 0; - - -/* - Method: replacePropertyWithPrefix -Description: Functionality for replacePropertyWithPrefix. -@param {any} params - Description for params -@param {any} prefix - Description for prefix -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.replacePropertyWithPrefix = function (params, prefix, args) { - - var paramsString; - - if (typeof params == 'object') - paramsString = self.stringify(params); - - else - paramsString = String(params); - - if (paramsString && paramsString.indexOf('{' + prefix) >= 0) { - paramsString = paramsString.replace(new RegExp('"{' + prefix + '[:\\s]?([\\w\\d\\s\\.\\|]*)}"', 'g'), function (match, path) { - if (path) { - let value = self.replaceUndefined({ match: match, path: path, root: args, removeUndefined: true }); - - if (value === undefined) { - return '""'; - } else if (typeof value == 'object') - return JSON.stringify(value); - else if (typeof value == 'string') - return '"' + value + '"'; - - else - return value; - } else { - if (typeof args == 'object') - return JSON.stringify(args); - else if (typeof args == 'string') - return '"' + args + '"'; - - else - return args; - } - }); - - paramsString = paramsString.replace(new RegExp('{' + prefix + '[:\\s]?([\\w\\d\\s\\.]*)}', 'g'), function (match, path) { - if (path) { - let value = self.replaceUndefined({ match: match, path: path, root: args, removeUndefined: true }); - - if (value === undefined) - return ''; - else if (typeof value == 'object') - return JSON.stringify(value); - - else - return value; - } else { - if (typeof args == 'object') - return JSON.stringify(args); - - else - return args; - } - }); - - if (self.isJsonString(paramsString)) { - var paramsObj = self.parse(paramsString); - return paramsObj; - } else { - return paramsString; - } - } else { - return params; - } - - }; - - -/* - Method: replaceResult -Description: Functionality for replaceResult. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.replaceResult = function (params, args) { - - var paramOn, paramSuccess, paramError; - - if (typeof params == 'object') { - var paramsObj = self.cloneObject(params); - if (paramsObj && paramsObj.on) { - paramOn = self.cloneObject(paramsObj.on); - delete paramsObj.on; - } - if (paramsObj && paramsObj.success) { - paramSuccess = self.cloneObject(paramsObj.success); - delete paramsObj.success; - } - - params = self.stringify(params); - } - - if (typeof args !== 'string') { - params = self.replaceAll(params, '"{result}"', JSON.stringify(args)); - } else { - params = self.replaceAll(params, '{result}', args); - } - - if (self.isJson(params)) { - var paramsObj = self.parse(params); - if (paramOn) paramsObj.on = paramOn; - if (paramSuccess) paramsObj.success = paramSuccess; - if (paramError) paramsObj.error = paramError; - return paramsObj; - } else { - - return params; - } - - }; - - -/* - Method: langText -Description: Functionality for langText. -@param {any} textId - Description for textId -@returns {any} - Result of the operation - */ -this.langText = function (textId) { - - if (textId) { - var textValue = textId; - if (typeof textId == 'string') { - if (self.json.texts[textId]) { - textValue = self.json.texts[textId]; - if (typeof textValue == 'object') - textValue = textValue[self.json.setup.language] || textValue['en'] || textValue[Object.keys[0]]; - } - else - textValue = textId; - } else if (typeof textId == 'object') { - textValue = textId[self.json.setup.language] || textId['en'] || textId[Object.keys[0]]; - - } - return textValue; - } else { - return textId; - } - - }; - - -/* - Method: lang -Description: Functionality for lang. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.lang = function (params, args) { - if (args) { - var value = self.replaceProperties(params, args); - self.json.setup.language = value; - - self.log('lang'); - self.log(value); - - document.querySelectorAll('[data-text]').forEach(function (element, index) { - - var dataParams = self.dataStorage.get(element, 'params'); - var selector = self.dataStorage.get(element, 'selector'); - - self.html(dataParams, { selector: selector }); - - }); - - } else { - return self.json.setup.language; - } - }; - - -/* - Method: isClipboardWritingAllowed -Description: Functionality for isClipboardWritingAllowed. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -var isClipboardWritingAllowed = function () { - return new Promise(function (resolve, reject) { - try { - navigator.permissions.query({ name: "clipboard-write" }).then(function (status) { - - self.log(status); - - resolve((status.state == "granted")); - }); - } catch (error) { - - reject(error); - } - }); - }; - - -/* - Method: codeSearch -Description: Functionality for codeSearch. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.codeSearch = function (params) { - let selector = params.selector || params.container; - - if (selector && params.word) { - var element = self.query(selector); - var editor = ace.edit(element); - - var range = editor.find(params.word, { - wrap: true, - caseSensitive: true, - wholeWord: true, - regExp: false, - preventScroll: false - }); - editor.session.selection.clearSelection(); - editor.setOption("highlightActiveLine", true); - - } - }; - - -/* - Method: ace -Description: Functionality for ace. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@returns {any} - Result of the operation - */ -this.ace = function (params, selectorParams) { - - var selector = params.selector || params.container; - var container = selector || self.selector(selectorParams); - - var value = params.value; - - if (params.blocks && self.json.blocks) - if (self.json.blocks[params.blocks]) - value = self.json.blocks[params.blocks]; - - else - self.log('"code" method can\'t find in "blocks" the element ' + params.blocks); - - if (params.module) { - let moduleName = self.replaceProperties(params.module); - if (moduleName && self.modules[moduleName] !== undefined) { - value = self.modules[moduleName]; - - } - else - self.log('"code" method can\'t find the file ' + params.file); - } - if (params.var) - if (self.json.var) - value = self.var(params.var); - - else - self.log('"code" method can\'t find the variable ' + params.blocks); - - var element = self.query(container); - - if (element) { - - var editor = ace.edit(element); - - if (!params.do || (params.do == 'set')) { - - if (params.theme) - editor.setTheme(params.theme); - var editorMode = params.mode || "ace/mode/json"; - editor.getSession().setMode(editorMode); - - if (params.options) - editor.setOptions(params.options); - - var editorStyle = self.extend({ - - }, params.style); - - self.css({ - style: editorStyle - }, { - selector: container - }); - - var codeString; - if (typeof value == 'string') - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(JSON.parse(value), null, '\t'); - - else - codeString = value; - else { - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(value, null, '\t'); - else { - var functionObj = self.docElement(value.function); - var functionParams = value.params; - codeString = functionObj(functionParams); - } - } - - if (codeString) { - var codeRows = codeString.split(/\r\n|\r|\n/).length; - - element.style.height = Number(21 * codeRows) + 'px'; - - editor.setValue(codeString, -1); - - self.uiUpdate(); - - } - - if (params.on) { - - var containerId = self.attribute(element, 'id'); - self.codeChangeFunctions[containerId] = params.on; - - if (params.on.change) { - editor.on('change', function (event, obj) { - - if (self.isJson(obj.getValue())) { - var code = JSON.parse(obj.getValue()); - var action = self.codeChangeFunctions[obj.container.id].change; - - var methods = self.replaceResult(action, code); - - self.do(methods); - - } else { - - } - - }); - } - - } - - } else if (params.do == 'get') { - return JSON.parse(editor.getValue()); - - } else if (params.do == 'update') { - - self.uiUpdate(); - - } else if (params.do == 'search') { - if (params.word) { - var range = editor.find(params.word, { - wrap: true, - caseSensitive: true, - wholeWord: true, - regExp: false, - preventScroll: false - }); - editor.session.selection.clearSelection(); - editor.setOption("highlightActiveLine", true); - - } - } else if (params.do == 'find') { - - editor.execCommand('find'); - - } else if (params.do == 'copy') { - - editor.selectAll(); - - let copyText = editor.getCopyText(); - - isClipboardWritingAllowed().then(function (allowed) { - - if (allowed) { - navigator.clipboard.writeText(copyText).then(function () { - editor.getSession().selection.clearSelection(); - - }); - } - }).catch(function (err) { - self.log("Cannot copy to clipboard", err); - }); - } else { - self.log('"code" function requires value param'); - } - } else { - self.log('"code" method can\'t select the container'); - self.log('container'); - self.log(container); - self.log('element'); - self.log(element); - } - - }; - - this.codeChangeFunctions = {}; - this.editorChangeFunctions = {}; - this.quillElements = {}; - - -/* - Method: text -Description: Functionality for text. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.text = function (params, selectorParams, args) { - - var textKey; - var textCase; - var textArgs; - var textLang; - var langId; - var selector, element; - - if (typeof params == 'object') { - - if (selectorParams && selectorParams.isConnected) { - element = selectorParams; - - selector = self.elementToSelector(element); - } else { - selector = self.selector(self.extend({}, params, selectorParams)); - element = self.query(selector); - } - - textCase = params.case; - textArgs = params.args; - - if (typeof params == 'object') { - - textKey = params.key || params.string || params; - - } else { - textKey = params; - } - - } else if (typeof params == 'string') { - textKey = params; - - if (selectorParams) { - if (selectorParams.isConnected) { - element = selectorParams; - selector = self.dataStorage.get(element, 'selector'); - } else { - selector = self.selector(selectorParams); - element = self.query(selector); - } - } else { - - } - } - - if (typeof textKey == 'string') { - - textKey = self.replaceProperties(textKey, textArgs); - - } - - if (params && params.lang) { - - textLang = self.langText(params.lang); - - textLang = self.replaceProperties(textLang, textArgs); - - if (textCase) textLang = self.textCase(textLang, textCase); - - if (element) { - element.textContent = textLang; - self.attribute(element, 'data-text', true); - self.dataStorage.set(element, 'params', params); - - } - - } else { - - if (textKey) { - - if (textKey.lang) - textLang = self.langText(textKey.lang); - - else - textLang = textKey; - - textLang = self.replaceProperties(textLang, textArgs); - if (textCase) textLang = self.textCase(textLang, textCase); - - if (element) { - - if (self.json.texts[textKey]) { - - self.attribute(element, 'data-text', true); - self.dataStorage.set(element, 'params', params); - } - - if (params.style) - self.css({ - style: params.style - }, { - selector: selector - }); - - element.textContent = textLang; - - } else { - return textLang; - } - - } else { - - return params; - } - - } - - }; - - -/* - Method: caseUp -Description: Functionality for caseUp. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -var caseUp = function (string) { - return string.toUpperCase(); - }; - - -/* - Method: caseDown -Description: Functionality for caseDown. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -var caseDown = function (string) { - return string.toLowerCase(); - }; - - -/* - Method: capitalize -Description: Functionality for capitalize. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -var capitalize = function (string) { - return self.capitalize(string); - }; - - -/* - Method: textCase -Description: Functionality for textCase. -@param {any} textParam - Description for textParam -@param {any} caseParam - Description for caseParam -@returns {any} - Result of the operation - */ -this.textCase = function (textParam, caseParam) { - if (textParam) { - var text = textParam; - switch (caseParam) { - case 'up': - text = text.toUpperCase(); - break; - - case 'down': - text = text.toLowerCase(); - break; - - case 'capitalize': - text = self.capitalize(text); - break; - } - return text; - } else { - self.log('textParam undefined in textCase'); - } - }; - - -/* - Method: replaceUndefined -Description: Functionality for replaceUndefined. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.replaceUndefined = function (params) { - let value, defaultValue; - - if (typeof params.path !== undefined) { - if (params.path.indexOf('|') > 0) - [params.path, defaultValue] = params.path.split('|'); - value = self.element({ path: params.path, root: params.root }); - } - if (value == undefined || value == null) { - if (typeof defaultValue !== undefined) - value = defaultValue; - else { - if (params.removeUndefined) { - value = ''; - } else { - value = params.match; - self.log(value + ' not found', 'yellow'); - } - } - } else { - - } - return value; - }; - - -/* - Method: replaceProperties -Description: Functionality for replaceProperties. -@param {any} params - Description for params -@param {any} args - Description for args -@param {any} removeUndefined - Description for removeUndefined -@returns {any} - Result of the operation - */ -this.replaceProperties = function (params, args, removeUndefined) { - - var paramsString; - var paramOn, paramDo, paramSuccess, paramError, paramEvents, paramConfirm; - if (typeof params == 'string') { - paramsString = params; - } else { - - var paramsObj = self.cloneObject(params); - if (paramsObj) { - if (paramsObj.on) { paramOn = paramsObj.on; delete paramsObj.on; } - if (paramsObj.success) { paramSuccess = paramsObj.success; delete paramsObj.success; } - if (paramsObj.error) { paramError = paramsObj.error; delete paramsObj.error; } - if (paramsObj.events) { paramEvents = paramsObj.events; delete paramsObj.events; } - if (paramsObj.confirm) { paramConfirm = paramsObj.confirm; delete paramsObj.confirm; } - if (paramsObj.do) { paramDo = paramsObj.do; delete paramsObj.do; } - } - paramsString = JSON.stringify(paramsObj); - } - - if (paramsString && paramsString.indexOf('{') >= 0) { - - paramsString = paramsString.replace(/\"\{([\w\s\.]+)\}\"/g, function (match, p1, offset, string) { - var value; - if (p1) { - //self.log('p1:' + p1); - //value = self.element({path: p1}); // || match; - value = self.replaceUndefined({ match: '{' + match + '}', path: p1, removeUndefined: removeUndefined }); - if (value) { - if (value.isConnected) return self.elementToSelector(value); // DOM element to CSS selector - if (typeof value !== 'string') - return self.stringify(value); // object or array to string (TO DO: check numbers) - else { - //console.warn('we are here'); - return '"' + value + '"'; - } - } - else - return '""'; - } else { - return '""'; - } - }); - - paramsString = paramsString.replace(/\{(\w+\:)?([\w\s\->|\/=\.:#&;,\[\]\']+)\}/g, function (match, p1, p2, offset, string) { - /* - Firebase references may contain any unicode characters except: - . (period) - $ (dollar sign) - [ (left square bracket) - ] (right square bracket) - # (hash or pound sign) - / (forward slash) - */ - - /* self.log("paramstring"); - self.log(match, p1, p2); */ - // self.log(match, p1, p2); - var value; - if (p1) { - if (p1.endsWith(':')) { - p1 = p1.slice(0, -1); // remove the final ":" - - // check if is a -/* - Method: name -Description: Functionality for name. -@param {any} in this.json.functions - Description for in this.json.functions -@returns {any} - Result of the operation - */ -function name (in this.json.functions) - if (self.functions[p1]) { - //value = self.functions[p1](JSON.parse(p2)); - let funcArgs = p2.split('|'); - /* console.warn('p2'); - console.warn(p2); - console.warn('funcArgs'); - console.warn(funcArgs); */ - // if Number(funcArgs[i]) == funcArgs[i] -> funcArgs[i] = Number(funcArgs[i]); - value = self.function({ name: p1, arguments: [funcArgs] }); - } else { - switch (p1) { - - /* case 'hasClass': - var element = document.querySelector(p2); - if (p3) - value = self.hasClass(el,p3); - else - value = false; el:selector.class (esiste l'elemento selector.class o l'elemento selector ha la classe class) - break; */ - // 'isVisible', 'isHidden', 'isDisplay', 'inViewport', 'outViewport', 'notClass', 'hasClass' - // hasClass da aggiungere come funzione css - // html markups - // 'b:string' 'i:string' 'u:string' 'a:STRING|URL' - /* case 'i': case 'b': case 'u': case 'strong': case 'em': case 'mark': case 'del': case 'ins': case 'sub': case 'sup': - value = '<'+p1+'>'+p2+''; - break; - - case 'a': - // example: "{a:text|href:....|target:_blank}" - let props = p2.split('|'); // or indexOf(':') prima occorrenza - let string = props.shift(); - var propsString = ''; - for (var prop of props) { - //let propArr = prop.split(':'), propName = propArr[0], propValue = propArr[1]; - propsString += ' ' + prop; - } - if (propsString == '') propsString = ' href="'+string+'"'; - value = ''+string+''; - - // https://stackoverflow.com/questions/1547899/which-characters-make-a-url-invalid - // https://www.w3schools.com/tags/tag_a.asp - break; - */ - // DOM properties - case 'visible': - var element = document.querySelector(p2); // self.query(p2); - value = (element && self.isVisible(element)); - //value = ($(p2).is(':visible')); - break; - - case 'number': - value = Number(p2); - break; - - case 'string': - value = String(p2); - break; - - case 'js': // deprecated (too much special characters like {}) - try { - value = eval(p2); - } catch (error) { - value = ''; - self.log('javascript error on ' + p2); - self.log(error); - } - break; - - /* case 'item': - if (fieldsObj) { - //self.log('fieldsObj['+p2+']:'+fieldsObj[p2]); - value = fieldsObj[p2] || ''; //|| p2+'=NULL'; - } else { - //self.log('p2:'+p2); - //self.log('fieldsObj == undefined'); - value = '{'+p1+':'+p2+'}'; - } - break; */ - /* case 'item': - case 'items': - value = self.docElement('self.json.items.'+p2); - break; */ - /* case 'frame': - var element = self.query(p2); - element.contentWindow - break; */ - /* case 'field': - if (fieldsObj) { - //self.log('fieldsObj['+p2+']:'+fieldsObj[p2]); - value = fieldsObj[p2] || ''; // || p2+'=NULL'; - } else { - //self.log('p2:'+p2); - //self.log('fieldsObj == undefined'); - value = ''; - } - break; */ - /* case 'setup': - value = self.docElement('self.json.setup.'+p2) || match; - break; */ - /* - case 'setup': - if (args) { - self.partSetup = args; - value = self.docElement('self.partSetup.'+p2); - delete self)Setup; - } else { - value = ''; - } - break; */ - case 'wp': - case 'wordpress': - // TO DO: should get/set data with jsonic.get/setWordpressData - // setWordpressData can be done automatically in the init - value = self.docElement('self.json.setup.wordpress.' + p2) ?? match; - //alert(value); - //if (value.indexOf('"') >= 0) - // value = self.replaceAll(value, '"', '\\"'); - // the first should replace only " and not \" but it doesn't works - - break; - - case 'plugins': - value = self.json.resources.pluginsFunctions[p2]; - if (value && !Array.isArray(value)) value = [value]; - else value = []; - - break; - - case 'database': - case 'db': - value = self.docElement('self.json.var.db.' + self.replaceProperties(p2, args)); - break; - - case 'media': - if (self.json.setup && self.json.data.media) - value = self.docElement('self.json.data.media.' + p2) || match; - - else - value = match; - break; - - case 'color': - if (self.json.data && self.json.data.colors) - value = self.docElement('self.json.data.colors.' + p2) || match; - - else - value = match; - break; - - case 'class': - if (self.json.data && self.json.data.class) - value = self.docElement('self.json.data.class.' + p2) || match; - - else - value = match; - break; - - case 'text': - value = self.langText(p2); - break; - - case 'param': - value = self.params[p2] || ''; - break; - - case 'height': - - var element = document.querySelector(p2); - if (element) - - value = element.offsetHeight + 'px'; - - else - value = '0px'; - break; - - case 'offsetWidth': - var element = document.querySelector(p2); - if (element) - - value = element.offsetWidth; - - else - value = '0'; - break; - - case 'width': - var element = document.querySelector(p2); - if (element) - - value = element.offsetWidth + 'px'; - - else - value = '0px'; - break; - - case 'local': - value = self.methods.local.get(p2); - - break; - - case 'ace': - var element = document.querySelector(p2); - if (element) { - var editor = ace.edit(element); - value = JSON.parse(editor.getValue()); - } - - break; - - case 'shuffle': - value = self.element({ path: p2 }); - value = self.methods.shuffle(value); - break; - - case 'select': - case 'input': - case 'value': - - var element = document.querySelector(p2); - value = (element) ? String(element.value || '') : ''; - - break; - - case 'user': - if (p2 == 'in') { - value = self.userIn(); - } else if (p2 == 'out') - value = self.userOut(); - - else - value = self.user(p2) || match; - break; - - case 'length': - var varObj = self.element({ path: p2 }); - - if (varObj) - if (typeof varObj == 'object') - value = Object.keys(varObj).length; - - else - value = varObj.length; - - else - self.log('' + p2 + ' is undefined'); - break; - - case 'Date': - case 'time': - if (p2 == 'timeZone') value = new Intl.DateTimeFormat().resolvedOptions().timeZone; - else if (p2 == 'weekday') value = self.weekday(); - else if (p2 == 'stamp') value = self.getTimestamp(); - else if (p2 == 'timestamp') value = self.getTimestamp(); - else if (p2 == 'getTimestamp') value = self.getTimestamp(); - else if (p2 == 'getDay') value = new Date().getDay(); - else if (p2 == 'getDate') value = new Date().getDate(); - else if (p2 == 'getMonth') value = new Date().getMonth(); - else if (p2 == 'getFullYear') value = new Date().getFullYear(); - else if (p2 == 'getTime') value = new Date().getTime(); - else if (p2 == 'getSeconds') value = new Date().getSeconds(); - else if (p2 == 'getMinutes') value = new Date().getMinutes(); - else if (p2 == 'getHours') value = new Date().getHours(); - - else value = p2 + '=NULL'; - break; - - case 'now': - - break; - - case 'month': - var month = (p2 == 'today' || p2 == undefined) ? new Date().getMonth() : Number(p2); - value = self.month(month); - break; - - case 'weekday': - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'long' }); - break; - - case 'weekdayNarrow': - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'narrow' }); - break; - - case 'weekdayShort': - var day = (p2 == 'today' || p2 == undefined) ? new Date().getDay() : Number(p2); - value = self.calendar({ index: Number(day), unit: 'weekday', format: 'short' }); - break; - - case 'moment': - var timeFormat = (p2) ? p2 : ''; - value = moment().format(timeFormat); - break; - - case 'dayjs': - var timeFormat = (p2) ? p2 : ''; - value = dayjs().format(timeFormat); - break; - - case 'Math': - value = self.Math(p2); - break; - - case 'action': - case 'do': - self.log('do'); - self.log('p2'); - self.log(p2); - - value = self.do(p2); - - break; - - case 'method': - var method = self.element({ path: p2, root: self.methods }); - if (method) { - value = method(args); - } else { - value = match; - } - break; - - case 'function': - var func = self.element({ path: p2, root: self.functions }); - if (func) { - value = func(args); - } else { - value = match; - } - break; - - case 'on': - - if (args) { - self.onResult = args; - value = self.docElement('self.onResult.' + p2); - - delete self.onResult; - } else { - - value = match; - } - - break; - - case 'ajax': - if (args) { - self.ajaxResult = args; - - value = self.docElement('self.ajaxResult.' + p2); - - delete self.ajaxResult; - } else { - - value = match; - } - - break; - - case 'if': - p2 = self.replaceProperties(p2); - var ifArr = p2.split('|'); - if (self.js(ifArr[0])) value = true; - if (ifArr.length > 1 && value) value = ifArr[1]; - if (ifArr.length > 2 && !value) value = ifArr[2]; - break; - case 'random': - - value = String(Math.floor(Number(p2) * Math.random())); - - break; - - case 'getKey': - case 'firebaseKey': - value = self.firebaseKey(p2); - - break; - - case 'window': - - value = self.docElement(p2) || match; - break; - - default: - - break; - - } - } - } - } else if (p2) { - - let keyPrefix = p2.split(' ')[0]; - if (self.functions[keyPrefix]) { - value = self.function({ name: keyPrefix }); - value = self.element({ path: p2, root: value }); - console.log(keyPrefix); - console.log(value); - } - else - value = self.replaceUndefined({ match: match, path: p2, removeUndefined: removeUndefined }); - - } - - if (value && value.isConnected) value = self.elementToSelector(value); - - if (!value) { - - if (removeUndefined) - value = ''; - else { - if (typeof value == undefined) - self.log(match + ' is undefined', 'yellow'); - } - } - if (typeof value !== 'string') value = self.stringify(value); - - return value; - }); - - if (paramsString.startsWith('{js:') && paramsString.endsWith('}')) - paramsString = self.js(paramsString.substr(4, paramsString.length - 1 - 4)); - - if (self.isJsonString(paramsString)) { - var paramsObj = self.parse(paramsString); - - if (paramOn) paramsObj.on = paramOn; - if (paramDo) paramsObj.do = paramDo; - if (paramConfirm) paramsObj.confirm = paramConfirm; - if (paramSuccess) paramsObj.success = paramSuccess; - if (paramError) paramsObj.success = paramError; - if (paramEvents) paramsObj.events = paramEvents; - return paramsObj; - } else { - - return paramsString; - } - } else { - - if (paramOn) params.on = paramOn; - if (paramDo) params.do = paramDo; - if (paramConfirm) params.confirm = paramConfirm; - if (paramSuccess) params.success = paramSuccess; - if (paramError) params.error = paramError; - if (paramEvents) params.events = paramEvents; - return params; - } - - }; - - -/* - Method: isJsonString -Description: Functionality for isJsonString. -@param {any} str - Description for str -@returns {any} - Result of the operation - */ -this.isJsonString = function (str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; - }; - - -/* - Method: isJson -Description: Functionality for isJson. -@param {any} item - Description for item -@returns {any} - Result of the operation - */ -this.isJson = function (item) { - item = typeof item !== "string" ? JSON.stringify(item) : item; - try { - item = JSON.parse(item); - } catch (e) { - return false; - } - - if (typeof item === "object" && item !== null) { - return true; - } - - return false; - }; - - -/* - Method: replaceStringInObject -Description: Functionality for replaceStringInObject. -@param {any} obj - Description for obj -@param {any} stringToReplace - Description for stringToReplace -@param {any} value - Description for value -@returns {any} - Result of the operation - */ -this.replaceStringInObject = function (obj, stringToReplace, value) { - var paramsString, valueString; - if (typeof obj == 'string') paramsString = obj; else paramsString = JSON.stringify(obj); - if (typeof value == 'string') valueString = value; else valueString = JSON.stringify(value); - paramsString = self.replaceAll(paramsString, stringToReplace, valueString); - if (self.isJson(paramsString)) - return self.parse(paramsString); - - else - return paramsString; - }; - - -/* - Method: replaceItems -Description: Functionality for replaceItems. -@param {any} params - Description for params -@param {any} item - Description for item -@param {any} name - Description for name -@returns {any} - Result of the operation - */ -this.replaceItems = function (params, item, name) { - - var paramsString; - var specialPattern; - var itemName = name || 'item'; - - if (typeof params == 'string') paramsString = params; else paramsString = JSON.stringify(params); - - if (typeof item == 'object' || Array.isArray(item)) { - paramsString = self.replaceAll(paramsString, '"{' + itemName + '}"', JSON.stringify(item)); - for (let key in item) { - if (typeof item[key] == 'object') - paramsString = self.replaceAll(paramsString, '"{' + itemName + ':' + key + '}"', JSON.stringify(item[key])); - - else - paramsString = self.replaceAll(paramsString, '{' + itemName + ':' + key + '}', item[key]); - } - } else { - paramsString = self.replaceAll(paramsString, '{' + itemName + '}', String(item)); - } - - paramsString = paramsString.replace(/(\"\s*)\{item\:(\w+)\}(\s*\")/g, function (match, p1, p2, p3, offset, string) { - - var value; - - if (item) - value = item[p2] || ''; - - else - value = ''; - - if (typeof value == 'object') - value = self.stringify(value); - else if (Array.isArray(value)) - value = value; - - else - value = p1 + value + p3; // p1 and p3 are the " matched by (\"\s*) and (\s*\") - - return value; - }); - - /* - specialPattern = new RegExp('\{'+itemName+'\:([^\}]*)\}', 'g'); - paramsString = paramsString.replace(specialPattern, function(match, p2, offset, string) { - //paramsString = paramsString.replace(/\{item\:([^\}]*)\}/g, function(match, p2, offset, string) { - - var value; - - if (item) - value = item[p2] || ''; - else - value = ''; - - if (typeof value == 'object') - value = self.stringify(value); - - return value; - }); */ - if (self.isJson(paramsString)) - return self.parse(paramsString); - - else - return paramsString; - //if (typeof params == 'object') return self.parse(paramsString); else return paramsString; - }; - - /* -/* - Method: replaceItems -Description: Functionality for replaceItems. -@param {any} objWithNames - Description for objWithNames -@param {any} name - Description for name -@returns {any} - Result of the operation - */ -this.replaceItems = function (objWithNames, name) { - //self.log('replaceItems'); - var paramString = self.stringify(objWithNames); - //self.log(paramString); - if (!name) name = ''; - paramString = self.replaceAll(paramString, '{item}', name); - //self.log(paramString); - //paramString = self.replaceTags({text:paramString}); - //self.log(paramString); - //paramString = self.replaceProperties(paramString); - //self.log(paramString); - if (typeof objWithNames == 'object') return self.parse(paramString); else return paramString; - } */ - -/* - Method: color -Description: Functionality for color. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.color = function (params, args) { - var paramsReplaced = self.replaceProperties(params, args); - //if (self.json.styles.colors) - // return self.json.styles.colors[paramsReplaced]; - if (self.json.data && self.json.data.colors) - return self.json.data.colors[paramsReplaced]; - }; - - // ---------------------------- - // ELEMENT METHODS - // ---------------------------- - -/* - Method: empty -Description: Functionality for empty. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.empty = function (params) { - /* self.log('empty'); - self.log(params); */ - var el = self.query(params); - if (el) { - while (el.firstChild) - el.removeChild(el.firstChild); - } else { - self.log('"empty" is unable to select element'); - self.log(params); - } - }; - - -/* - Method: isArray -Description: Functionality for isArray. -@param {any} value - Description for value -@returns {any} - Result of the operation - */ -this.isArray = function (value) { - return Array.isArray(self.js(value)); - }; - - -/* - Method: isVisible -Description: Functionality for isVisible. -@param {any} el - Description for el -@returns {any} - Result of the operation - */ -this.isVisible = function (el) { - return (el.style.display !== 'none' && !self.hasClass(el, 'd-none')); - }; - - -/* - Method: isHidden -Description: Functionality for isHidden. -@param {any} el - Description for el -@returns {any} - Result of the operation - */ -this.isHidden = function (el) { - return (el.offsetParent === null); - }; - - -/* - Method: isDisplay -Description: Functionality for isDisplay. -@param {any} el - Description for el -@param {any} displayValue - Description for displayValue -@returns {any} - Result of the operation - */ -this.isDisplay = function (el, displayValue) { - //var style = window.getComputedStyle(el); - /* self.log('isDisplay'); - self.log('el.style'); - self.log(el.style); - self.log('displayValue'); - self.log(displayValue); */ - return (el.style.display === displayValue); - }; - - -/* - Method: inViewport -Description: Functionality for inViewport. -@param {any} el - Description for el -@returns {any} - Result of the operation - */ -this.inViewport = function (el) { - const rect = el.getBoundingClientRect(); - return ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - rect.right <= (window.innerWidth || document.documentElement.clientWidth) - - ); - }; - - -/* - Method: outViewport -Description: Functionality for outViewport. -@param {any} el - Description for el -@returns {any} - Result of the operation - */ -this.outViewport = function (el) { - return !self.outViewport(el); - }; - - -/* - Method: notClass -Description: Functionality for notClass. -@param {any} el - Description for el -@param {any} className - Description for className -@returns {any} - Result of the operation - */ -this.notClass = function (el, className) { - return !self.hasClass(el, className); - }; - - -/* - Method: hasClass -Description: Functionality for hasClass. -@param {any} el - Description for el -@param {any} className - Description for className -@returns {any} - Result of the operation - */ -this.hasClass = function (el, className) { - if (el.classList) - return el.classList.contains(className); - - else - return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')); - }; - - -/* - Method: addClass -Description: Functionality for addClass. -@param {any} el - Description for el -@param {any} className - Description for className -@returns {any} - Result of the operation - */ -this.addClass = function (el, className) { - if (el.classList) - el.classList.add(className); - else if (!self.hasClass(el, className)) el.className += " " + className; - }; - - -/* - Method: removeClass -Description: Functionality for removeClass. -@param {any} el - Description for el -@param {any} className - Description for className -@returns {any} - Result of the operation - */ -this.removeClass = function (el, className) { - if (el.classList) - el.classList.remove(className); - else if (self.hasClass(el, className)) { - var reg = new RegExp('(\\s|^)' + className + '(\\s|$)'); - el.className = el.className.replace(reg, ' '); - } - }; - - -/* - Method: toggleClass -Description: Functionality for toggleClass. -@param {any} el - Description for el -@param {any} className - Description for className -@returns {any} - Result of the operation - */ -this.toggleClass = function (el, className) { - if (self.hasClass(el, className)) - self.removeClass(el, className); - - else - self.addClass(el, className); - }; - - this.choose = -/* - Method: select -Description: Functionality for select. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.select = function (params, selectorParams, args) { - // "choose OR options / "select" is deprecated because select is an html tag - - if (Array.isArray(params)) { - for (var obj of params) - self.choose(obj, args); - } else { - - var selId, selClass, selValue; - - selValue = params['data-value']; - if (params.id) selId = self.replaceProperties(params.id, args); - if (params.class) selClass = self.replaceProperties(params.class, args); - if (selValue) selValue = self.replaceProperties(selValue, args); - - if (params.selection) { - - var selectionClass = params.selection; - - var selector = self.selector({ class: selClass }); - var elements = document.querySelectorAll('.' + selClass); - elements.forEach(function (element, index) { - self.removeClass(element, selectionClass); - }); - - if (selId || selValue) { - var selector = self.selector({ id: selId, class: selClass, 'data-value': selValue }); - - var elements = document.querySelectorAll(selector); - elements.forEach(function (element, index) { - self.addClass(element, selectionClass); - }); - } - } else { - - self.hide({ - "selector": { - "class": selClass - } - }); - self.show({ - "selector": { - "id": selId, - "class": selClass, - "data-value": selValue - } - }); - - } - - self.uiUpdate(); - - } - - }; - - -/* - Method: toggle -Description: Functionality for toggle. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.toggle = function (params, selectorParams, args) { - self.log('toggle'); - self.log(params); - if (Array.isArray(params)) { - for (var index in params) - self.toggle(params[index], selectorParams, args); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var element = self.query(selector); - - if (self.isVisible(element)) - - self.out(params, selectorParams, args); - - else - - self.in(params, selectorParams, args); - - } - }; - - -/* - Method: in -Description: Functionality for in. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.in = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.in(params[index], selectorParams, args); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - - var transition = params.transition || 'fadeIn'; - var duration = params.duration || '500ms'; - - var start = [{ - "show": { - "selector": selector, - } - }]; - var end = [ - { - "do": self.resizeEvent - } - ]; - if (params.on && params.on.start) - start.push(params.on.start); - if (params.on && params.on.end) - end.push(params.on.end); - - var animation = { - "animate": { - "selector": selector, - "transition": transition, - "duration": duration, - "on": { - "start": start, - "end": end - } - } - }; - - self.do(animation, undefined, args); - - } - - }; - - -/* - Method: out -Description: Functionality for out. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.out = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.out(params[index], selectorParams); - } else { - - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - - var transition = params.transition || 'fadeOut'; - var duration = params.duration || '500ms'; - - var start = []; - var end = [ - { - "hide": { - "selector": selector, - } - }, - { - "do": self.resizeEvent - } - ]; - if (params.on && params.on.start) - start.push(params.on.start); - if (params.on && params.on.end) - end.push(params.on.end); - - var animation = { - "animate": { - "selector": selector, - "transition": transition, - "duration": duration, - "on": { - "start": start, - "end": end - } - } - }; - - self.do(animation, undefined, args); - } - }; - - -/* - Method: show -Description: Functionality for show. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.show = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.show(params[index], selectorParams); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - elements.forEach(function (element, index) { - self.removeClass(element, 'hidden'); - self.removeClass(element, 'opacity-0'); - self.removeClass(element, 'invisible'); - self.removeClass(element, 'd-none'); - - element.style.visibility = 'visible'; - - }); - } - }; - - -/* - Method: hide -Description: Functionality for hide. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.hide = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.hide(params[index], selectorParams); - } else { - var selector; - if (typeof params == 'string') - selector = params; - - else - selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - elements.forEach(function (element, index) { - self.addClass(element, 'hidden'); - - }); - } - }; - - -/* - Method: matchMedia -Description: Functionality for matchMedia. -@param {any} mediaAction - Description for mediaAction -@param {any} mediaEvent - Description for mediaEvent -@returns {any} - Result of the operation - */ -this.matchMedia = function (mediaAction, mediaEvent) { - const mediaQuery = window.matchMedia(mediaEvent); - mediaQuery.addListener(function (e) { - - if (e.matches) { - self.do(mediaAction); - - } - }); - - }; - - -/* - Method: addFirebaseTag -Description: Functionality for addFirebaseTag. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.addFirebaseTag = function (params) { - - var dataObj = params.database; - - if (dataObj) { - - dataObj = self.replaceProperties(dataObj); - - var path, success; - if (typeof dataObj == 'string') { - path = dataObj; - } else { - path = dataObj.path; - success = dataObj.success; - } - - if (path) { - var selector = self.selector(params, undefined, false); - - var elements = self.queryAll(selector); - - if (elements) - elements.forEach(function (element, index) { - - var listenerObj = { - path: path - - }; - - var elementsDataPath = document.querySelectorAll('[data-firebase="' + path + '"]'); - - if (elementsDataPath.length == 0) { - listenerObj.action = [ - - ]; - - if (dataObj.success) - listenerObj.action.push(dataObj.success); - - } - - if (element) { - element.setAttribute('data-firebase', path); - self.dataStorage.set(element, 'data-template', params); - } else { - self.log('!element selector:' + selector + ' / firebase path:' + path); - self.log('params'); - self.log(params); - } - - if (dataObj.orderByChild !== undefined) listenerObj.orderByChild = dataObj.orderByChild; - if (dataObj.equalTo !== undefined) listenerObj.equalTo = dataObj.equalTo; - - self.firebaseAddListener(listenerObj); - }); - - } else { - self.log('data object requires path parameter'); - self.log(params); - } - } - }; - - -/* - Method: dbObject -Description: Functionality for dbObject. -@param {any} path - Description for path -@returns {any} - Result of the operation - */ -this.dbObject = function (path) { - var pathString = 'self.json.var.db.' + self.replaceAll(path, '/', '.'); - return self.docElement(pathString); - }; - - -/* - Method: only -Description: Functionality for only. -@param {any} permissions - Description for permissions -@param {any} user - Description for user -@returns {any} - Result of the operation - */ -this.only = function (permissions, user) { - - if (user) { - return (user == self.user('uid')); - } else { - var permission = (permissions) ? String(permissions).split(',') : false; - return (!permission || (permissions.indexOf(self.userRole()) >= 0)); - } - }; - - -/* - Method: extendJsonFromElement -Description: Functionality for extendJsonFromElement. -@param {any} p - Description for p -@returns {any} - Result of the operation - */ -this.extendJsonFromElement = function (p) { - - var params = self.cloneObject(p); - - if (params.resources) self.extendJson(self.json, { "resources": params.resources }); - if (params.plugins) self.extendJson(self.json, { "plugins": params.plugins }); - if (params.parts) self.extendJson(self.json, { "parts": params.parts }); - if (params.blocks) self.extendJson(self.json, { "blocks": params.parts }); - if (params.shortcuts) self.extendJson(self.json, { "shortcuts": params.shortcuts }); - if (params.css) self.extendJson(self.json, { "css": params.css }); - if (params.setup) self.extendJson(self.json, { "setup": params.setup }); - if (params.data) self.extendJson(self.json, { "data": params.data }); - if (params.var) self.extendJson(self.json, { "var": params.var }); - if (params.texts) self.extendJson(self.json, { "texts": params.texts }); - - }; - - -/* - Method: query -Description: Functionality for query. -@param {any} selector - Description for selector -@param {any} element - Description for element -@returns {any} - Result of the operation - */ -this.query = function (selector, element) { - - if (selector) { - if (typeof selector == 'object') - selector = self.selector(selector, undefined, true); - - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - - if (element && element[0]) element = element[0]; - - if (element && element.isConnected) { - - var route = routes[index]; - - var routeParts = route.match(/(.*):eq\((\d*)\)/); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - - if (routeElement.startsWith('.')) - routeElement = '.' + self.classSelector(routeElement); - - element = element.querySelectorAll(routeElement)[routeIndex]; - - } else { - - if (route.startsWith('.')) - route = '.' + self.classSelector(route); - element = element.querySelectorAll(route)[0]; - } - } else { - element = undefined; - } - } - - if (!element) - self.log('can\'t find the element "' + selector + '" ("query" function)'); - - return element; - } else { - - } - }; - - -/* - Method: queryAll -Description: Functionality for queryAll. -@param {any} selector - Description for selector -@param {any} element - Description for element -@returns {any} - Result of the operation - */ -this.queryAll = function (selector, element) { - - if (selector) { - - if (Array.isArray(selector)) { - let elements = self.queryAll(selector[0]); - selector.shift(); - for (let str of selector) { - elements = Array.prototype.slice.call(elements).concat(Array.prototype.slice.call(self.queryAll(str))); - - } - - return elements; - - } else { - - var routes = selector.split(/[ >]+/); - if (!element) element = document; - - for (var index in routes) { - - if (element && element[0]) element = element[0]; - - if (element && element.isConnected) { - - var route = routes[index]; - - var routeParts = route.match(/([^:]*):eq\((\d*)\)/); - - if (routeParts) { - var routeElement = String(routeParts[1]); - var routeIndex = Number(routeParts[2]); - - if (routeElement.startsWith('.')) - routeElement = '.' + self.classSelector(routeElement); - - element = element.querySelectorAll(routeElement)[routeIndex]; - - if (index == (routes.length - 1) && element) { - - element = [element]; - } - - } else { - - if (route.startsWith('.')) - routeElement = '.' + self.classSelector(route); - - element = element.querySelectorAll(route); - } - } else { - - element = []; - } - } - - if (!element) - self.log('No element selected by ' + selector); - - return element; - } - } else { - console.log('%cDOM queryAll requires selector argument', 'color: orange'); - - } - }; - - -/* - Method: jitcss -Description: Functionality for jitcss. -@param {any} classes - Description for classes -@returns {any} - Result of the operation - */ -this.jitcss = function (classes) { - - if (classes.indexOf('-[') > -1) { - let classesArr = classes.split(' '); - - self.log('jitcss'); - - for (cl of classesArr) { - self.log(cl); - let par = [...cl.matchAll(new RegExp('([^-]+)[\-][\[](.+)\]', 'g'))]; - self.log('jitcss'); - self.log(par); - } - } - - }; - - -/* - Method: compileClasses -Description: Functionality for compileClasses. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -this.compileClasses = function (string) { - - var classesString = string; - - if (self.json.shortcuts && self.json.shortcuts.class) { - for (shortcut in self.json.shortcuts.class) { - if (string.indexOf(shortcut) > -1) { - classesString = self.replaceAll(string, shortcut, self.json.shortcuts.class[shortcut]); - } - } - } - - if (string.indexOf('(') >= 0) { - - classesString = ''; - let classesArr = string.split(' '); - for (cl of classesArr) { - - if (cl.indexOf('(') >= 0 && cl.endsWith(')')) { - let classArr = cl.split('('); - classArr[1] = classArr[1].slice(0, -1); - - if (Boolean(self.js(classArr[1]))) { - if (classesString !== '') classesString += ' '; - classesString += classArr[0]; - } - - } else { - if (classesString !== '') classesString += ' '; - classesString += cl; - } - } - - if (string == classesString) { - self.log('wrong dynamic class syntax'); - self.log(string); - } - - } - - return classesString; - - }; - - -/* - Method: createElement -Description: Functionality for createElement. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@returns {any} - Result of the operation - */ -this.createElement = function (params, selectorParams) { - - let selector = params.selector || params.container; - var container = selector || self.selector(selectorParams); - var containerElement = self.query(container); - var newSelector = self.selector(params, selectorParams); - - var newElements = []; - - if (containerElement) { - - if (!params) params = {}; - - var element = document.createElement(params.tag); - - containerElement.appendChild(element); - - if (params.attr) { - - if (params.attr.class) { - - params.attr.class = self.compileClasses(params.attr.class); - } - } - - self.dataStorage.set(element, 'code', params); - self.dataStorage.set(element, 'key', params.key); - - newElements.push(element); - - if (params.attr) self.setAttributes(newElements, params.attr); - if (params.style) self.css(params, newSelector); - - } - - return newElements; - - }; - - this.do = this.action = -/* - Method: execute -Description: Functionality for execute. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.execute = function (params, selectorParams, args) { - - if (params !== undefined && params !== null) { - - if (typeof params == 'string') - params = self.replaceProperties(params, args); - - let pluginsRequired = self.pluginsRequired(params); - - if (pluginsRequired.length > 0) - - self.pluginsLoader(pluginsRequired, self.do, [params, selectorParams, args]); - else { - - if (Array.isArray(params)) - for (var obj of params) - self.do(obj, selectorParams, args); - else if (typeof params == 'object') { - - if (params.if == undefined || self.if(params.if)) { - - if (self.only(params.roles, params.user)) { - - if (params.tag) { - - var selector = self.selector(params, selectorParams); - - self.extendJsonFromElement(params); - - var newElements = self.createElement(params, selectorParams); - - if (params.matchMedia) { - for (var mediaEvent in params.matchMedia) { - self.matchMedia(params.matchMedia[mediaEvent], mediaEvent); - } - } - - if (params.html) { - - self.html(params.html, selector, args); - - } else { - - for (var par in params) - if ((nodes.exclude.indexOf(par) < 0) && (nodes.params.indexOf(par) < 0)) - self.nested({ key: par, obj: params[par], selector: { selector: selector }, args: args }); - - } - - self.on(params.on, { selector: selector }); - - } else { - - var selector = self.selector(params, selectorParams); - - for (var par in params) - if ((nodes.exclude.indexOf(par) < 0) && (nodes.params.indexOf(par) < 0)) - self.nested({ key: par, obj: params[par], selector: selector, args: args }); - - if (params.on) - self.on(params.on, { selector: selector }); - - } - - } - - } - - } else if (typeof params == 'function') - return params(selectorParams); - - else - self.log('can\'t execute: ' + params); - } - - } - }; - - -/* - Method: callback -Description: Functionality for callback. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.callback = function (params) { - - if (params) { - var path = params.to; - if (params.var) path = 'var ' + params.var; - let selector; - let element = params.element; - if (element && element.isConnected) params.value = self.elementToSelector(element); - if (path) { - var context = self.context(path); - self.element({ path: path, value: params.value, root: context }); - } - if (params.do) - self.do(params.do, selector); - } - }; - - -/* - Method: nested -Description: Functionality for nested. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.nested = function (params) { - - let pluginsRequired = self.pluginsRequired(params.key); - if (pluginsRequired.length > 0) { - self.pluginsLoader(pluginsRequired, self.nested, [params]); - } else { - - if (params.key.startsWith('set ')) { - self.setData({ key: params.key.substr(4), value: params.obj }); - } else if (params.key.startsWith('var ') || params.key.startsWith('data ') || params.key.startsWith('set ')) { - - console.log('%cdeprecated key: "' + params.key + '". Use "set key": "value"}', 'color:orange'); - - self.setData({ key: params.key, value: params.obj }); - - } else { - - var method = self.element({ path: params.key, root: self.methods }); - - if (method) { - self.log('METHOD: ' + params.key, 'grey'); - var methodArgs = params.obj; - - method(methodArgs, params.selector, params.args); - - } else { - - let nested; - let part; - - var jsonicPart = false; - if (self.json.parts) { - part = self.element({ path: self.replaceAll(params.key, ':', '.'), root: self.json.parts }); - - } - - if (part) { - self.log('PART: ' + params.key, 'grey'); - - var partObj = params.obj; - - partObj = self.replaceProperties(partObj); - - partObj.selector = partObj.selector || params.selector; - - if (partObj.setup) partObj = partObj.setup; - - nested = self.replacePropertyWithPrefix(part, 'setup', partObj); - nested = self.replacePropertyWithPrefix(nested, 'arguments', partObj); - - self.extendJsonFromElement(nested); - - self.do(nested, params.selector, partObj); - - } else { - - if (self.json && self.json.functions && params.key && self.json.functions[params.key]) { - - self.log('FUNCTION: ' + params.key, 'grey'); - - let args = self.replaceProperties(params.obj, undefined, true); - - if (!args || !Array.isArray(args)) args = [args]; - - if (self.json.functions[params.key].requires) { - let pluginsRequired = []; - for (let plugin of self.json.functions[params.key].requires) { - if (!self.pluginsLoaded[plugin]) - pluginsRequired.push({ "name": plugin, version: "" }); - } - - if (pluginsRequired.length > 0) - - self.pluginsLoader(pluginsRequired, self.function, [{ name: params.key, arguments: args }]); - else { - self.log('Plugins already loaded: ' + params.key, 'grey'); - self.function({ name: params.key, arguments: args }); - - } - } else { - - self.log('Function without plugin required: ' + params.key, 'grey'); - self.function({ name: params.key, arguments: args }); - - } - - } else { - var windowFunction = self.element({ path: params.key, root: window }); - if (typeof windowFunction === 'function') { - self.log('WINDOW function: ' + params.key, 'grey'); - windowFunction(self.replaceProperties(params.obj, undefined, true)); - - } else if (windowFunction !== undefined) { - self.log('window.' + params.key + ' is not a function', 'red'); - - } else { - - if (params.selector) { - self.log('TAG: ' + params.key, 'grey'); - - let pluginsRequired = self.pluginsRequiredByTag(params.obj, params.key); - if (pluginsRequired.length > 0) { - let htmlTagParams = [params.obj, params.selector, params.key]; - self.pluginsLoader(pluginsRequired, self.htmlTag, htmlTagParams); - } else { - self.htmlTag(params.obj, params.selector, params.key); - - } - } else { - self.log(params.key + ' not found', 'red'); - } - } - } - } - } - } - - } - }; - - -/* - Method: setData -Description: Functionality for setData. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.setData = function (params) { - - let setObj = {}; - setObj[params.key] = params.value; - self.set(setObj); - - }; - - this.partContainers = {}; - - -/* - Method: pluginsRequiredByTag -Description: Functionality for pluginsRequiredByTag. -@param {any} params - Description for params -@param {any} tagKey - Description for tagKey -@returns {any} - Result of the operation - */ -this.pluginsRequiredByTag = function (params, tagKey) { - - if (self.json.resources) { - - const pluginsTags = self.json.resources.pluginsTags; - const pluginsAttr = self.json.resources.pluginsAttr; - var pluginsRequired = []; - - if (pluginsTags[tagKey] && !self.pluginsLoaded[pluginsTags[tagKey].name]) - pluginsRequired.push(pluginsTags[tagKey]); - - if (typeof params == 'string') { - - } else if (typeof params == 'object') { - - var objArray; - if (Array.isArray(params)) objArray = params; else objArray = [params]; - - for (var obj of objArray) { - if (obj.attr) { - var attr = 'data-icon'; - if (obj.attr[attr]) { - if (pluginsAttr[attr] && !self.pluginsLoaded[pluginsAttr[attr].name]) - pluginsRequired.push(pluginsAttr[attr]); - } - } - } - } - return pluginsRequired; - } else { - - return false; - } - }; - - -/* - Method: calendar -Description: Functionality for calendar. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.calendar = function (params, args) { - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-US'; - let calendarArr, todayIndex; - - if (params.unit) { - switch (params.unit) { - case 'month': - const monthFormat = params.format || 'long'; - var format = new Intl.DateTimeFormat(localeName, { month: monthFormat }).format; - calendarArr = [...Array(12).keys()].map((m) => format(new Date(Date.UTC(2021, m)))); - todayIndex = new Date().getMonth(); - break; - case 'weekday': - const weekdayFormat = params.format || 'long'; - var format = new Intl.DateTimeFormat(localeName, { weekday: weekdayFormat }).format; - calendarArr = [...Array(7).keys()].map((day) => format(new Date(Date.UTC(2021, 5, day)))); - todayIndex = self.weekday(); - break; - default: - self.log('"calendar" function can\'t recognize "unit" parameter'); - self.log(params.unit); - break; - } - - if (calendarArr) { - if (params.index !== undefined) { - params.index = self.js(params.index); - let index = Number(self.replaceProperties(params.index, args)); - return calendarArr[index]; - } else { - return calendarArr[todayIndex]; - } - } else { - self.log('"calendar" function can\'t recognize "unit" or "format" parameters'); - } - - } else { - self.log('"calendar" function requires "unit" parameter'); - } - - }; - - -/* - Method: month -Description: Functionality for month. -@param {any} params - Description for params -@param {any} monthFormat = 'long' - Description for monthFormat = 'long' -@returns {any} - Result of the operation - */ -this.month = function (params, monthFormat = 'long') { - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-GB'; - const format = new Intl.DateTimeFormat(localeName, { month: monthFormat }).format; - const weekdayArr = [...Array(12).keys()].map((m) => format(new Date(Date.UTC(2021, m)))); - if (params !== undefined) { - var index = Number(self.replaceProperties(params)); - return weekdayArr[index]; - } - else - return weekdayArr; - }; - - -/* - Method: weekday -Description: Functionality for weekday. -@param {any} params - Description for params -@param {any} weekdayFormat - Description for weekdayFormat -@returns {any} - Result of the operation - */ -this.weekday = function (params, weekdayFormat) { - - const localeName = (self.json.setup.language !== 'en') ? self.json.setup.language : 'en-GB'; - const format = new Intl.DateTimeFormat(localeName, { weekday: weekdayFormat }).format; - const weekdayArr = [...Array(7).keys()].map((day) => format(new Date(Date.UTC(2021, 5, day)))); - var result; - if (params !== undefined) { - var index = Number(self.replaceProperties(params)); - result = weekdayArr[index]; - } - else - result = weekdayArr; - - return result; - - }; - - -/* - Method: method -Description: Functionality for method. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.method = function (params, args) { - - var value; - - if (typeof params == 'string') { - return self.docElement(params); - } else { - - if ((params.if == undefined) || self.if(params.if, undefined, args)) { - - if (self.notEmptyObject(params)) { - var actionKey = Object.keys(params)[0]; - var actionFunction = self.docElement(actionKey); - var actionValue = params[actionKey]; - - if (!Array.isArray(actionValue)) - actionValue = [actionValue]; - if (actionFunction) { - if (typeof actionFunction == 'function') - return actionFunction(...actionValue); - - else - return actionFunction; - } else { - self.log('unknown function'); - self.log(params); - return params; - } - } else { - - return undefined; - } - } - } - - }; - - -/* - Method: Number -Description: Functionality for Number. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.Number = function (params, args) { - self.log('Number'); - return self.method({ "Number": params }, args); - }; - - -/* - Method: String -Description: Functionality for String. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.String = function (params, args) { - self.log('String'); - return self.method({ "String": params }, args); - - }; - - -/* - Method: Math -Description: Functionality for Math. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.Math = function (params, args) { - return self.method(params, args, 'Math'); - - }; - - -/* - Method: dayjs -Description: Functionality for dayjs. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.dayjs = function (params, args) { - - return self.method(params, args, 'dayjs'); - - }; - - -/* - Method: moment -Description: Functionality for moment. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.moment = function (params, args) { - - return self.method(params, args, 'moment'); - - }; - - -/* - Method: dynamicCss -Description: Functionality for dynamicCss. -@param {any} selector - Description for selector -@param {any} property - Description for property -@param {any} value - Description for value -@returns {any} - Result of the operation - */ -this.dynamicCss = function (selector, property, value) { - if (value.indexOf('{') >= 0) { - var resizeData = self.dataStorage.get(element, "resize"); - - if (!resizeData) resizeData = {}; - resizeData[property] = value; - var resizeData = self.dataStorage.set(element, "resize", resizeData); - - if (!self.resizeActions[selector]) self.resizeActions[selector] = {}; - self.resizeActions[selector][property] = value; - var result = self.replaceProperties(value) || ''; - - } else { - var style = {}; - style[property] = value; - self.css({ - style: style - }); - - } - }; - - -/* - Method: li -Description: Functionality for li. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@returns {any} - Result of the operation - */ -this.li = function (params, selectorParams) { - if (Array.isArray(params)) { - for (var index in params) - self.li(params[index], selectorParams); - } else { - if (params.items) { - var itemsArray = (typeof params.items == 'string') ? self.json.items[params.items] : params.items; - - delete params.items; - for (var index in itemsArray) { - if (self.only(itemsArray[index].roles)) - self.li(self.replaceItems(params, itemsArray[index]), selectorParams); - } - } else { - if (typeof params == 'string') { params = { html: params }; }; - params.tag = 'li'; - - self.do(params, selectorParams); - } - } - }; - - -/* - Method: remove -Description: Functionality for remove. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.remove = function (params, selectorParams, args) { - var selector = self.selector(params.selector || self.selector(selectorParams)); - if (selector) { - var elements = self.queryAll(selector); - if (elements) { - elements.forEach(function (element, index) { - element.remove(); - }); - } - } - }; - - -/* - Method: dispatchEvent -Description: Functionality for dispatchEvent. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.dispatchEvent = function (params, selectorParams, args) { - var selector = self.selector(params.selector || self.selector(selectorParams)); - if (selector) { - var elements = self.queryAll(selector); - if (elements) { - elements.forEach(function (element, index) { - element.dispatchEvent(new Event(params.name)); - }); - } - } - }; - - -/* - Method: html -Description: Functionality for html. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.html = function (params, selectorParams, args) { - - if (params) { - - if (Array.isArray(params)) { - - for (var obj of params) - self.html(obj, selectorParams, args); - } else { - - var container = self.selector(params.selector || params.container) || self.selector(selectorParams); - - if (container) { - var element = self.query(container); - - if (element) { - - if (typeof params == 'string') { - - var paramsCompiled = self.replaceProperties(params, args); - - if (paramsCompiled) { - if (typeof paramsCompiled == 'object') { - - self.do(paramsCompiled, { selector: container }, args); - - } else if (typeof paramsCompiled == 'string') { - element.innerHTML += paramsCompiled; - } - } - - } else { - - if (params.empty || params.do == 'empty') { - element.innerHTML = ''; - delete params.empty; - } - - if (params.tag) { - self.do(params, container, args); - - } - else if (params.html) { - - var htmlCompiled = self.replaceProperties(params.html, args); - - self.html(htmlCompiled, { selector: container }); - } else if (params.lang) { - - var textLang = params.lang[self.json.setup.language] || params.lang['en'] || params.lang[Object.keys[0]]; - if (Array.isArray(textLang)) { - var paragraphs = []; - for (var paragraph of textLang) - paragraphs.push({ p: paragraph }); - self.html(paragraphs, selectorParams, args); - } - else - element.innerHTML = self.replaceProperties(textLang, args); - - if (element) { - self.attribute(element, 'data-text', true); - self.dataStorage.set(element, 'params', params); - } - - } else if (params.text) { - - element.textContent = self.replaceProperties(params.text, args); - - } else if (params.append) { - - element.innerHTML += self.replaceProperties(params.append, args); - - } else if (params.prepend) { - - element.innerHTML = self.replaceProperties(params.prepend, args) + element.innerHTML; - - } else if (params.blocks) { - self.blocks(params.blocks, { selector: container }, args); - } else { - - let nestedParams = self.cloneObject(params); - if (nestedParams.style) delete nestedParams.style; - if (nestedParams.attr) delete nestedParams.attr; - - console.warn('UNKNOWN TAG'); - console.warn(params); - - self.do(nestedParams, { selector: container }, args); - - if (element.isConnected) { - - if (params.attr) self.setAttributes(element, params.attr, args); - if (params.style) self.css(params, selectorParams, args); - - } - - } - - } - } else { - } - } else { - self.log('"html" object requires selector property', 'red'); - self.log(params); - - } - - } - } else { - self.log('"html" object without params'); - } - - }; - - -/* - Method: setAttributes -Description: Functionality for setAttributes. -@param {any} elements - Description for elements -@param {any} attrs - Description for attrs -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.setAttributes = function (elements, attrs, args) { - for (var attribute in attrs) - if (attrs[attribute]) - self.attribute(elements, attribute, self.replaceResult(attrs[attribute], args)); - else - self.attribute(elements, attribute, ""); - - }; - - -/* - Method: attribute -Description: Functionality for attribute. -@param {any} elements - Description for elements -@param {any} attrId - Description for attrId -@param {any} attrValue - Description for attrValue -@returns {any} - Result of the operation - */ -this.attribute = function (elements, attrId, attrValue) { - if (typeof attrValue !== undefined) { - if (!Array.isArray(elements)) elements = [elements]; - elements.forEach(function (element, index) { - if (typeof attrValue == 'boolean' && attrValue) { - element.setAttribute(attrId, ""); - } else { - element.setAttribute(attrId, self.replaceProperties(attrValue)); - } - }); - } else { - if (!Array.isArray(elements)) - return elements.getAttribute(attrId); - - else - return elements[0].getAttribute(attrId); - } - }; - - -/* - Method: attr -Description: Functionality for attr. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.attr = function (params, selectorParams, args) { - - self.css(self.replaceProperties(params), selectorParams, args); - }; - - -/* - Method: styleElement -Description: Functionality for styleElement. -@param {any} params - Description for params -@param {any} element - Description for element -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.styleElement = function (params, element, args) { - for (var styleName in params) { - if (styleName.startsWith('--')) - element.style.setProperty(styleName, self.replaceProperties(params[styleName], args)); - - else - element.style[styleName] = self.replaceProperties(params[styleName], args); - } - }; - - -/* - Method: css -Description: Functionality for css. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.css = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var obj of params) - self.css(obj, selectorParams, args); - - } else { - - var selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - var elements = self.queryAll(selector); - - if (elements) { - elements.forEach(function (element, index) { - - if (element) { - - if (typeof params.style == 'object') { - self.styleElement(params.style, element, args); - } - - if (params.addClass) - self.addClass(element, params.addClass); - if (params.removeClass) - self.removeClass(element, params.removeClass); - if (params.toggleClass) - self.toggleClass(element, params.toggleClass); - - } else { - self.log('the function "css" can\'t find the selector ' + selector); - self.log(params); - self.log(selectorParams); - } - }); - } else { - self.log('"css" function is unable to select: ' + selector); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } - }; - - -/* - Method: numberToHour -Description: Functionality for numberToHour. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.numberToHour = function (data) { - var fraction = data.value / data.max; - var dayMin = Math.round(24 * 60 * fraction); - var hour = parseInt(dayMin / 60); - var min = dayMin - hour * 60; - var hourString = String(hour < 10 ? '0' : '') + String(hour); - var minString = String(min < 10 ? '0' : '') + String(min); - return hourString + ':' + minString; - }; - - -/* - Method: hourToNumber -Description: Functionality for hourToNumber. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.hourToNumber = function (data) { - var timeArr = data.value.split(':'); - var dayMin = (60 * Number(timeArr[0])) + Number(timeArr[1]); - var fraction = dayMin / (24 * 60); - return Math.round(fraction * data.max); - }; - - -/* - Method: pannellum -Description: Functionality for pannellum. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.pannellum = function (params, selectorParams, args) { - self.log('pannellum'); - var container = params.selector || params.container; - var selector = self.selector(container) || self.selector(selectorParams); - var element = self.query(selector); - pannellum.viewer(element, params); - }; - - -/* - Method: qrcode -Description: Functionality for qrcode. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.qrcode = function (params, selectorParams, args) { - self.log('qrcode'); - var container = params.selector || params.container; - var selector = self.selector(container) || self.selector(selectorParams); - var element = self.query(selector); - - self.log(selector); - self.log('element'); - self.log(element); - - var QRCodeOptions = { - text: self.replaceProperties(params.text, args) || 'jsonic.io', - width: params.size || 128, - height: params.size || 128, - useSVG: true, - colorDark: params.colorDark || '#000000', - colorLight: params.colorLight || '#ffffff', - correctLevel: QRCode.CorrectLevel.H - }; - self.log('QRCodeOptions'); - self.log(QRCodeOptions); - - element.textContent = ''; - var qrcode = new QRCode(element, QRCodeOptions); - self.log('qrcode'); - self.log(qrcode); - return qrcode; - - }; - - -/* - Method: weekdaysShort -Description: Functionality for weekdaysShort. -@param {any} length - Description for length -@param {any} caseFunction - Description for caseFunction -@returns {any} - Result of the operation - */ -this.weekdaysShort = function (length, caseFunction) { - if (!caseFunction) caseFunction = caseUp; - var language = 'en'; - var fixoLang = fixo.getFixoLanguage(); - var userLang = fixo.getUserLanguage(); - if (fixo.device) language = fixoLang; else language = userLang; - var weekDays = self.cloneObject(moment.localeData(language).weekdays()); - - weekDays[7] = weekDays[0]; - weekDays.shift(); - - for (var i = 0; i < 7; i++) { - if (length) weekDays[i] = weekDays[i].substr(0, length); - if (caseFunction) weekDays[i] = caseFunction(weekDays[i]); - } - return weekDays; - }; - - -/* - Method: weekDaysToString -Description: Functionality for weekDaysToString. -@param {any} days - Description for days -@returns {any} - Result of the operation - */ -this.weekDaysToString = function (days) { - var text = ''; - for (var i in days) { - if (days[i]) { - if (text !== '') text += '/'; - text += self.weekdaysShort(3, capitalize)[i]; - } - } - return text; - }; - - var sortField; - - -/* - Method: dynamicSort -Description: Functionality for dynamicSort. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -var dynamicSort = function (data) { - var sortOrder = 1; - if (data.reverse) { sortOrder = -1; } - sortField = data.field; - return function (a, b) { - var result = (a[sortField] < b[sortField]) ? -1 : (a[sortField] > b[sortField]) ? 1 : 0; - return result * sortOrder; - }; - }; - - -/* - Method: sort -Description: Functionality for sort. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.sort = function (data) { - - if (data.object !== undefined) { - if (Array.isArray(data.object)) { - return data.object.sort(dynamicSort({ - field: data.field, - reverse: data.reverse - })); - } else { - var arr = self.objectToArray({ - object: data.object, - add: data.add, - }); - return arr.sort(dynamicSort({ - field: data.field, - reverse: data.reverse - })); - } - } else { - self.log('sort of undefined'); - return []; - } - }; - - -/* - Method: objectToArray -Description: Functionality for objectToArray. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.objectToArray = function (data) { - - var arr = []; - var obj = data.object; - if (obj !== undefined) { - for (var key in obj) { - obj[key].id = key; - if (data.add) obj[key] = Object.assign(obj[key], data.add); - arr.push(obj[key]); - } - } - return arr; - }; - - -/* - Method: equal -Description: Functionality for equal. -@param {any} obj1 - Description for obj1 -@param {any} obj2 - Description for obj2 -@returns {any} - Result of the operation - */ -this.equal = function (obj1, obj2) { - if (obj1 && obj2) { - return (JSON.stringify(obj1).replace('"', '') == JSON.stringify(obj2).replace('"', '')); - } else { - return (obj1 == obj2); - } - }; - - -/* - Method: escapeRegExp -Description: Functionality for escapeRegExp. -@param {any} str - Description for str -@returns {any} - Result of the operation - */ -var escapeRegExp = function (str) { - return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); - }; - -/* - Method: replaceAll -Description: Functionality for replaceAll. -@param {any} str - Description for str -@param {any} find - Description for find -@param {any} replace - Description for replace -@returns {any} - Result of the operation - */ -this.replaceAll = function (str, find, replace) { - - if (str !== undefined) { - let result; - if (typeof str == 'string') result = str; else result = JSON.stringify(str); - - if (str) { - if (find) { - - result = String(str).replace(new RegExp(escapeRegExp(find), 'g'), replace); - - if (typeof str == 'object' && result) return JSON.parse(result); - else - return result; - } else { - - return str; - } - } - } else { - return str; - } - }; - - -/* - Method: capitalize -Description: Functionality for capitalize. -@param {any} str - Description for str -@returns {any} - Result of the operation - */ -this.capitalize = function (str) { - return str.replace(/\b\w/g, l => l.toUpperCase()); - }; - - -/* - Method: getPageName -Description: Functionality for getPageName. -@param {any} url - Description for url -@returns {any} - Result of the operation - */ -this.getPageName = function (url) { - var index = url.lastIndexOf("/") + 1; - var filenameWithExtension = url.substr(index); - var filename = filenameWithExtension.split(".")[0]; - return filename; - }; - - -/* - Method: goToMainUrl -Description: Functionality for goToMainUrl. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.goToMainUrl = function () { - window.location = self.mainUrl; - }; - - -/* - Method: getParameterByName -Description: Functionality for getParameterByName. -@param {any} name - Description for name -@param {any} url - Description for url -@returns {any} - Result of the operation - */ -this.getParameterByName = function (name, url) { - if (!url) url = window.location.href; - name = name.replace(/[\[\]]/g, "\\$&"); - var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url); - if (!results) return null; - if (!results[2]) return ''; - return decodeURIComponent(results[2].replace(/\+/g, " ")); - }; - - -/* - Method: paramsToObject -Description: Functionality for paramsToObject. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -var paramsToObject = function (params) { - params = params.split('#')[0]; - return JSON.parse('{"' + params.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}'); - }; - - -/* - Method: objectToParams -Description: Functionality for objectToParams. -@param {any} object - Description for object -@returns {any} - Result of the operation - */ -var objectToParams = function (object) { - var str = ''; - for (var key in object) str += '&' + key + '=' + object[key]; - if (str) str = str.substr(1); - return encodeURI(str); - }; - - -/* - Method: getParams -Description: Functionality for getParams. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.getParams = function () { - var params = {}; - var url = window.location.href.split('#')[0]; - if (url.indexOf('?') > -1) { - var urlParams = decodeURI(url.split('?')[1]); - self.log(urlParams); - if (urlParams) { - var k = self.getParameterByName('k', url); - //self.log(k); - if (k) { - params = self.atob(k); - } else { - params = paramsToObject(urlParams); - } - } - } - return params; - }; - - -/* - Method: atob -Description: Functionality for atob. -@param {any} k - Description for k -@returns {any} - Result of the operation - */ -this.atob = function (k) { - self.log('atob'); - var params = paramsToObject(atob(k)); // base64 -> query -> object - - // decompress params - if (params.h) // hotel - params.h = String(parseInt(String(params.h), 36)); // base36 - if (params.c) // customer - params.c = String(parseInt(String(params.c), 36)); // base36 - if (params.n) { // phone - params.n = String(parseInt(String(params.n), 36)); // base36 - params.n = '+' + params.n; - } - //if (params.s) params.s = var.services.id[params.s]; - self.log(params); - return params; - }; - - -/* - Method: btoa -Description: Functionality for btoa. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.btoa = function (params) { - self.log('btoa'); - //if (params.s) params.s = var.services.id.indexOf(params.s); - if (params.h) // hotel - params.h = Number(params.h).toString(36); // base36 - if (params.c) // customer - params.c = Number(params.c).toString(36); // base36 - - if (params.n) { // phone - if (params.n.startsWith('+')) params.n = params.n.substr(1); - params.n = params.n.replace(/ /g, ''); - params.n = params.n.replace(/-/g, ''); - params.n = Number(params.n).toString(36); // base36 - } - self.log(params); - return btoa(objectToParams(params)); // query -> base64 - }; - - /* - -/* - Method: encodeNum -Description: Functionality for encodeNum. -@param {any} num - Description for num -@returns {any} - Result of the operation - */ -var encodeNum = function(num) { // 0..1296 es:customer - var hex = c.toString(36); - return c.toString(36); - } - - -/* - Method: decodeNum -Description: Functionality for decodeNum. -@param {any} str - Description for str -@returns {any} - Result of the operation - */ -var decodeNum = function(str) { - return str.parseInt(36); // .length == 1 ? "0" + hex : hex - } - */ - -/* - Method: colorToRgba -Description: Functionality for colorToRgba. -@param {any} hex - Description for hex -@param {any} opacity - Description for opacity -@returns {any} - Result of the operation - */ -this.colorToRgba = function (hex, opacity) { - if (hex == 'white') { hex = '#fff'; } - if (hex == 'black') { hex = '#000'; } - var c; - if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) { - c = hex.substring(1).split(''); - if (c.length == 3) { - c = [c[0], c[0], c[1], c[1], c[2], c[2]]; - } - c = '0x' + c.join(''); - return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ',' + opacity + ')'; - } else { - self.log('Bad Hex:' + hex); - } - }; - -/* - Method: hueToRGB -Description: Functionality for hueToRGB. -@param {any} m1 - Description for m1 -@param {any} m2 - Description for m2 -@param {any} h - Description for h -@returns {any} - Result of the operation - */ -var hueToRGB = function (m1, m2, h) { - h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); - if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; - if (h * 2 < 1) return m2; - if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; - return m1; - }; - - -/* - Method: HSLToRGB -Description: Functionality for HSLToRGB. -@param {any} hsl - Description for hsl -@returns {any} - Result of the operation - */ -var HSLToRGB = function (hsl) { - var m1, m2, r, g, b; - var h = hsl[0], s = hsl[1], l = hsl[2]; - m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s; - m1 = l * 2 - m2; - return [hueToRGB(m1, m2, h + 0.33333), - hueToRGB(m1, m2, h), - hueToRGB(m1, m2, h - 0.33333)]; - }; - - -/* - Method: packRGB -Description: Functionality for packRGB. -@param {any} rgb - Description for rgb -@returns {any} - Result of the operation - */ -var packRGB = function (rgb) { - var r = Math.round(rgb[0] * 255); - var g = Math.round(rgb[1] * 255); - var b = Math.round(rgb[2] * 255); - // '#' + - return (r < 16 ? '0' : '') + r.toString(16) + - (g < 16 ? '0' : '') + g.toString(16) + - (b < 16 ? '0' : '') + b.toString(16); - }; - - -/* - Method: degToRGB -Description: Functionality for degToRGB. -@param {any} deg - Description for deg -@returns {any} - Result of the operation - */ -this.degToRGB = function (deg) { - return packRGB(HSLToRGB([deg / 360, 1, 0.5])); - }; - - -/* - Method: stripHtml -Description: Functionality for stripHtml. -@param {any} html - Description for html -@returns {any} - Result of the operation - */ -this.stripHtml = function (html) { - var tmp = document.createElement("DIV"); - tmp.innerHTML = html; - return tmp.textContent || tmp.innerText || ""; - }; - - //-------------------------- - // TASK MANAGER - //-------------------------- - -/* - Method: log -Description: Functionality for log. -@param {any} value - Description for value -@param {any} color - Description for color -@returns {any} - Result of the operation - */ -this.log = function (value, color) { - if (self.json.setup && self.json.setup.log) { // log enabled - if (typeof value === 'string') - console.log('%c' + value, 'color:' + color); - - else - console.log(value); - } - }; - - -/* - Method: varlog -Description: Functionality for varlog. -@param {any} str - Description for str -@returns {any} - Result of the operation - */ -var varlog = function (str) { - self.log(str); - self.log(window[str]); // 'var' -> var - }; - - -/* - Method: logJson -Description: Functionality for logJson. -@param {any} jsonPar - Description for jsonPar -@returns {any} - Result of the operation - */ -this.logJson = function (jsonPar) { self.log(JSON.stringify(jsonPar)); }; - - -/* - Method: getTimestamp -Description: Functionality for getTimestamp. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.getTimestamp = function () { - // we need also an API to get the time - // like .getTime()? - return Math.floor(Date.now()); - }; - - -/* - Method: cloneObject -Description: Functionality for cloneObject. -@param {any} obj - Description for obj -@returns {any} - Result of the operation - */ -this.cloneObject = function (obj) { - var newObj = JSON.stringify(obj); - return self.parse(newObj); - }; - - /*------------------------ - TEXT - ------------------------*/ - /* -/* - Method: caseUp -Description: Functionality for caseUp. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -var caseUp = function (string) { - if (!string) string = ''; - return string.toUpperCase(); - } - - -/* - Method: caseDown -Description: Functionality for caseDown. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -var caseDown = function (string) { - if (!string) string = ''; - return string.toLowerCase(); - } - - -/* - Method: capitalize -Description: Functionality for capitalize. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -var capitalize = function(string) { - if (!string) string = ''; - return self.capitalize(string); - } - - -/* - Method: text -Description: Functionality for text. -@param {any} key - Description for key -@param {any} caseFunction - Description for caseFunction -@returns {any} - Result of the operation - */ -var text = function (key, caseFunction) { - var t = self.json.text[key] || ''; - if (caseFunction) return caseFunction(t); else return t; - } */ - -/* - Method: setElement -Description: Functionality for setElement. -@param {any} elementString - Description for elementString -@param {any} elementValue - Description for elementValue -@returns {any} - Result of the operation - */ -this.setElement = function (elementString, elementValue) { - var context = window; - var namespaces = elementString.split("."); - var func = namespaces.pop(); - - if (namespaces[0] == 'frame') { - namespaces.shift(); - var frameName = namespaces.shift(); - if (frameName && document.getElementById(frameName) !== null) - context = document.getElementById(frameName).contentWindow; - } else if (namespaces[0] == 'admin') { // fixo - namespaces.shift(); - context = fixoAdmin; - } - - for (var i = 0; i < namespaces.length; i++) { - if (context[namespaces[i]]) { // var - context = context[namespaces[i]]; - } else { - if (elementValue) // scrittura - context[namespaces[i]] = {}; // crea contesto inesistente - } - } - - context[func] = elementValue; - }; - - -/* - Method: context -Description: Functionality for context. -@param {any} path - Description for path -@returns {any} - Result of the operation - */ -this.context = function (path) { - const re = /^(setup|var|data|texts|parts)[\.\s]/; // reserved namespaces - if (re.test(path)) { - /* self.log('MATCHED setup|var|data|parts'); - console.log(params); */ - return self.json; - } else { - return window; - } - }; - - -/* - Method: element -Description: Functionality for element. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.element = function (params) { - // {root, path, value} - // in respect to docElement, it includes replaceProperties for path and value - // but only if value is a string. TO DO: check it - let context; - let path = self.replaceProperties(params.path, params.args); - let value = (params.value && typeof params.value == 'string') ? self.replaceProperties(params.value, params.args) : params.value; - - // NOTE: log error if the params.root is equal to the first element of the path? (window.window works) - if (!params.root) { - context = self.context(path); - } else { - context = params.root; - } - - return self.docElement(path, value, context, params.delete); - - //self.log(value); - /* if (value && typeof value == 'string') { - if (value.startsWith('js:')) value = self.js(value.substr(3)); - else if (value.startsWith('+=')) value = self.element({path: path}) + self.js(value.substr(2)); - else if (value.startsWith('-=')) value = self.element({path: path}) - self.js(value.substr(2)); - else if (value.startsWith('/=')) value = self.element({path: path}) / self.js(value.substr(2)); - else if (value.startsWith('*=')) value = self.element({path: path}) / self.js(value.substr(2)) - } */ - // self.log(value); - /* if (value.startsWith('number:')) value = Number(self.js(value.substr(6))); - alert('dopo number:'+value); - if (value.startsWith('boolean:')) value = Boolean(self.js(value.substr(7))); - if (value.startsWith('string:')) value = String(self.js(value.substr(6))); - if (value.startsWith('+:')) value = self.element({path: path}) + self.js(value.substr(2)); - if (value.startsWith('-:')) value = self.element({path: path}) - self.js(value.substr(2)); - if (value.startsWith('/:')) value = self.element({path: path}) / self.js(value.substr(2)); - if (value.startsWith('*:')) value = self.element({path: path}) / self.js(value.substr(2)); */ - /* // verificare... - if (value.startsWith('push:')) {var obj = self.docElement(path, undefined, root); return obj.push(value.substr(3));} - if (value.startsWith('unshift:')) {var obj = self.docElement(path, undefined, root); return obj.unshift(value.substr(3));} - if (value.startsWith('pop:')) {var obj = self.docElement(path, undefined, root); return obj.pop(value.substr(3));} - if (value.startsWith('shift:')) {var obj = self.docElement(path, undefined, root); return obj.shift(value.substr(3));} */ - }; - - -/* - Method: docElement -Description: Functionality for docElement. -@param {any} elementString - Description for elementString -@param {any} elementValue - Description for elementValue -@param {any} context - Description for context -@param {any} elementDelete - Description for elementDelete -@returns {any} - Result of the operation - */ -this.docElement = function (elementString, elementValue, context, elementDelete) { - - if (!context) context = window; // TO DO: remove - var namespaces = elementString.split(/[.\s]+/); // path nodes separed by dot or spaces - - /* console.log('<-------'); - console.log('context'); - console.log(context); - console.log('path'); - console.log(elementString); - console.log('value'); - console.log(elementValue); - console.log('------>'); -*/ - var lastElement = namespaces.pop(); - - /* if (namespaces[0] == 'self') { - namespaces.shift(); - context = self; - } else if (namespaces[0] == 'frame') { - namespaces.shift(); - var frameName = namespaces.shift(); - if (frameName && document.getElementById(frameName) !== null) - context = document.getElementById(frameName).contentWindow; - } */ - /* console.log('namespaces'); - console.log(namespaces); */ - for (var i = 0; i < namespaces.length; i++) { - if (context[namespaces[i]]) { // var - context = context[namespaces[i]]; - } else { - if (elementValue !== undefined && elementValue !== null) { // wants to assign a value - context[namespaces[i]] = {}; // it create the context context[namespaces[i]] if it doesn't exist - context = context[namespaces[i]]; - /* self.log('crea context inesistente'); - self.log('namespaces[i]: '+namespaces[i]); */ - /* self.log('elementValue'); - self.log(elementValue); - self.log('context[namespaces[i]]'); - self.log(context[namespaces[i]]); */ - } else { - /* self.log(elementString + ' undefined'); - self.log('lastElement:' + lastElement); - self.log(elementValue); */ - } - //break; // perché? rendeva impossibile creare un listener su un nodo secondario (solo su app e non su app/dev) - } - } - - if (elementValue !== undefined) { // write - - //self.log(lastElement+'='+elementValue); - if (typeof elementValue == 'string') elementValue = self.js(elementValue); // 1.0.3 - context[lastElement] = elementValue; - - // elementValue can be a js function - /* self.log('context'); - self.log(context); - self.log('context[lastElement]'); - self.log(context[lastElement]); - self.log('====='); */ - } - - if (elementDelete) delete context[lastElement]; - - /* self.log('context'); - self.log(context); */ - /* console.log('namespaces'); - console.log(namespaces); - self.log('lastElement'); - self.log(lastElement); - self.log('context[lastElement]'); - self.log(context[lastElement]); */ - if (context[lastElement] && context[lastElement].isConnected) - return self.elementToSelector(context[lastElement]); - - else - return context[lastElement]; - }; - - /* -/* - Method: openCloseDropdown -Description: Functionality for openCloseDropdown. -@param {any} key - Description for key -@returns {any} - Result of the operation - */ -this.openCloseDropdown = function(key) { - self.log('openCloseDropdown'); - self.log("key"); - self.log(key); - //$('.dropdown-menu').css('display','none'); - var selector = self.selector({ - "id": "dropdown" +key, - "class": 'points', - "value": key, - }); - self.log("selector"); - self.log(selector); - if ($(selector + ' > .dropdown-menu').css('display') == 'none') { - $(selector + ' > .dropdown-menu').css('display', 'block'); - } else { - $(selector + ' > .dropdown-menu').css('display', 'none'); - } - } */ - -/* - Method: timeToMs -Description: Functionality for timeToMs. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -this.timeToMs = function (string) { - // bug - var timeArray = string.match(/(\d+)(\w+)/); // es: 1s / 100ms - if (timeArray) { - var value = Number(timeArray[0]); - var unit = timeArray[1]; - var unitInMs = { - ms: 1, - s: 1000, - m: 1000 * 60, - h: 1000 * 60 * 60, - d: 1000 * 60 * 60 * 24, - milliseconds: 1, - seconds: 1000, - minutes: 1000 * 60, - hours: 1000 * 60 * 60, - days: 1000 * 60 * 60 * 24 - }; - if (value) - if (unitInMs[unit]) - return value * unitInMs[unit]; - - else - self.log('wrong unit in the time string [value][unit]: ' + string); - - else - self.log('wrong value in the time string [value][unit]: ' + string); - } - else - return Number(string); - }; - - this.intervals = {}; - - -/* - Method: timer -Description: Functionality for timer. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.timer = function (params, args) { - // can go in "browser.json / functions (JS Browser BOM) - - let name = self.replaceProperties(params.name); - if (!name) - name = self.getTimestamp() + Math.random(1000); - - if (params.play !== undefined && params.play == 0) { - if (self.intervals[name]) { - self.clearInterval({ - name: name - }, args); - } - if (self.timeouts[name]) { - self.clearTimeout({ - name: name - }, args); - } - } - else if (params.every !== undefined) { - let every = self.replaceProperties(params.every); - if (every) { - self.setInterval({ - name: name, - duration: every, - do: params.do - }, args); - } - } - else if (params.after !== undefined) { - let after = self.replaceProperties(params.after); - if (after) { - self.setTimeout({ - name: name, - duration: after, - do: params.do - }, args); - } else { - self.do(params.do, null, args); - } - } - }; - - -/* - Method: setInterval -Description: Functionality for setInterval. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.setInterval = function (params, args) { - - if (params.name && params.duration) { - if (self.intervals[params.name]) - clearInterval(self.intervals[params.name]); - - self.do(params.do); - self.intervals[params.name] = setInterval(function () { - - self.do(params.do); - return params.name; - }, Number(params.duration)); - } - else - self.log('"setInterval" function requires "name" and "duration" parameters'); - }; - - -/* - Method: clearInterval -Description: Functionality for clearInterval. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.clearInterval = function (params, args) { - - if (self.intervals[params.name]) { - clearInterval(self.intervals[params.name]); - delete self.intervals[params.name]; - } - - }; - - this.timeouts = {}; - - -/* - Method: setTimeout -Description: Functionality for setTimeout. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.setTimeout = function (params, args) { - - if (params.name && params.duration) { - if (self.timeouts[params.name]) - clearInterval(self.timeouts[params.name]); - - self.timeouts[params.name] = setTimeout(function () { - - self.do(params.do); - return params.name; - }, Number(params.duration)); - } - else - self.log('"setTimeout" function requires "name" and "duration" parameters'); - }; - - -/* - Method: clearTimeout -Description: Functionality for clearTimeout. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.clearTimeout = function (params, args) { - - if (self.timeouts[params.name]) { - clearTimeout(self.timeouts[params.name]); - delete self.timeouts[params.name]; - } - - }; - - -/* - Method: on -Description: Functionality for on. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@returns {any} - Result of the operation - */ -this.on = function (params, selectorParams) { - - var container = (selectorParams) ? self.selector(selectorParams) : params.selector; - - var element; - - if (container) { - element = self.query(container); - if (element) - self.dataStorage.set(element, "onData", { on: params, selector: container }); - else { - self.log('can\'t find the element "' + container + '" ("on" function)'); - self.log('params'); - self.log(params); - self.log('selectorParams'); - self.log(selectorParams); - } - } - - for (var eventId in params) { - - if (eventId == 'init') { - - self.do(params.init, selectorParams); - } else if (eventId == 'hashchange') { - self.onHashChange.push(params.hashchange); - window.addEventListener('hashchange', function () { - self.json.setup.page.hash = window.location.hash.substr(1); - - self.do(self.onHashChange); - self.uiUpdate(); - }); - } else if (eventId == 'scroll') { - self.onScroll.push(params.scroll); - window.addEventListener('scroll', function () { - - self.do(self.onScroll); - }); - } else if (eventId == 'resize') { - self.onResize.push(params.resize); - window.addEventListener('resize', function () { - - self.do(self.onResize); - }); - } else if (eventId == 'in') { - if (container) { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - - if (entry.intersectionRatio == 1) { - var el = entry.target; - if (el.getAttribute('in') !== 'true') { - el.setAttribute('in', 'true'); - self.onEvent(entry.target, { type: 'in' }); - } - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] - }); - - observer.observe(self.query(container)); - } - } else if (eventId == 'inViewport') { - if (container) { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - - if (entry.intersectionRatio > 0) { - self.onEvent(entry.target, { type: 'inViewport' }); - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] - }); - - observer.observe(self.query(container)); - } - } else if (eventId == 'outViewport') { - const observer = new IntersectionObserver((entries, observer) => { - entries.forEach(function (entry) { - - if (entry.intersectionRatio == 0) { - self.onEvent(entry.target, { type: 'outViewport' }); - - } - }); - }, { - rootMargin: '0px', - threshold: [0, 1] - }); - const element = self.query(container); - observer.observe(element); - - } else if (eventId !== 'selector') { - - if (element) { - - element.addEventListener(eventId, function (event) { - - element.setAttribute('listener', 'true'); - - self.onEvent(this, event); - }); - - if (eventId == 'mousedown' || eventId == 'mouseup' || eventId == 'click') - element.style.cursor = 'pointer'; - } - - } - } - - }; - - -/* - Method: money -Description: Functionality for money. -@param {any} value - Description for value -@returns {any} - Result of the operation - */ -this.money = function (value) { - - var rounded = Math.round(Number(value) * 100) / 100; - var string = String(rounded); - if (rounded == Math.floor(rounded)) - string += ',00'; - string = String(string).replace('.', ','); - return string; - }; - - -/* - Method: offcanvas -Description: Functionality for offcanvas. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.offcanvas = function (params) { - self.log('offcanvas'); - self.log('params'); - self.log(params); - - var container = params.selector || params.container; - var selector = self.selector(container); - var element = self.query(selector); - self.log('offcanvas'); - self.log(params); - self.log('selector'); - self.log(selector); - self.log('element'); - self.log(element); - - if (element) { - if (params.do == 'hide') { - self.css({ - removeClass: 'show' - }, params); - - } else { - new bootstrap.Offcanvas(element).show(); - } - } else { - self.log('"offcanvas" method can\'t find the selected element'); - } - }; - - -/* - Method: elementToSelector -Description: Functionality for elementToSelector. -@param {any} element - Description for element -@returns {any} - Result of the operation - */ -this.elementToSelector = function (element) { - - if (element.id) { - return '#' + element.id; - } - - if (element.dataset?.value) { - const sameDataValue = document.querySelectorAll(`[data-value="${element.dataset.value}"]`); - if (sameDataValue.length === 1) { - return `[data-value="${element.dataset.value}"]`; - } - } - - if (element.classList && element.classList.length > 0) { - for (const className of element.classList) { - if (className) { - const sameClass = document.querySelectorAll('.' + className); - if (sameClass.length === 1) { - return '.' + className; - } - } - } - } - - const tagName = element.tagName.toLowerCase(); - const sameTag = document.querySelectorAll(tagName); - if (sameTag.length === 1) { - return tagName; - } - - let path = []; - while (element.parentNode) { - let selector = element.tagName.toLowerCase(); - const index = Array.from(element.parentNode.children).indexOf(element) + 1; - selector += `:nth-child(${index})`; - - path.unshift(selector); - element = element.parentNode; - } - return path.join(' > '); - }; - - -/* - Method: onEvent -Description: Functionality for onEvent. -@param {any} element - Description for element -@param {any} event - Description for event -@returns {any} - Result of the operation - */ -this.onEvent = function (element, event) { - - var item = self.dataStorage.get(element, 'onData'); - var code = self.dataStorage.get(element, 'code') || ''; - - var value = element.getAttribute('data-value'); - - var selector = self.elementToSelector(element); - - var eventType = (event.type && item.on) ? item.on[event.type] : undefined; - - var action, specialKey; - - if (item.on) { - - if (event.button == '2' && event.type == 'mousedown') { - - if (item.on['contextmenu']) - action = item.on['contextmenu']; - - } else if (event.type && item.on[event.type]) { - - var eventAction = item.on[event.type]; - - if (eventAction) { - if (eventAction.shiftKey && event.shiftKey) { - specialKey = 'shiftKey'; - action = eventAction.shiftKey; - } else if (eventAction.altKey && event.altKey) { - specialKey = 'altKey'; - action = eventAction.altKey; - } else if (eventAction.cmdKey && event.cmdKey) { - specialKey = 'cmdKey'; - action = eventAction.cmdKey; - } else if (!eventAction.shiftKey && !eventAction.altKey && !eventAction.cmdKey) { - action = item.on[event.type]; - } - } - } - } - - if (action) { - - if (event.target) { - - var actionString; - var targetId = event.target.id; - var targetClass = event.target.className; - var targetValue = event.target.dataset.value; - var targetSelector = event.target.dataset.selector; - - targetSelector = self.replaceAll(targetSelector, '"', '\''); - action = self.stringify(action); - if (typeof targetId !== 'string') targetId = ''; - if (typeof targetClass !== 'string') targetClass = ''; - - actionString = self.replaceAll(action, '{on:target.id}', targetId); - actionString = self.replaceAll(actionString, '{on:altKey}', event.altKey); - actionString = self.replaceAll(actionString, '{on:target.className}', targetClass); - actionString = self.replaceAll(actionString, '{on:target.data-value}', targetValue); - actionString = self.replaceAll(actionString, '{on:target.dataset.value}', targetValue); - actionString = self.replaceAll(actionString, '{on:target.dataset.selector}', targetSelector); - actionString = self.replaceAll(actionString, '{on:which}', event.which); - actionString = self.replaceAll(actionString, '{on:clientY}', event.clientY); - actionString = self.replaceAll(actionString, '{on:clientX}', event.clientX); - - actionString = self.replaceAll(actionString, '{on:value}', targetValue); - actionString = self.replaceAll(actionString, '{on:dragging}', (event.which > 0)); - - if (this.isJson(actionString)) - action = self.parse(actionString); - - else - action = actionString; - } - - var args = item.args; - - let specialKeyLog = (specialKey) ? ' + ' + specialKey : ''; - - self.do(action, { selector: selector }, args); - } - - }; - - this.pluginsFunctionAvailable = []; - - self.pluginsLoader = function (packs, callback, params) { - - var filesToLoad = []; - - for (pack of packs) { - - if (self.pluginsLoaded[pack.name] == undefined) { - - self.log('require plugin ' + pack.name, 'grey'); - var plugin = self.findPlugin(pack.name); - let version; - var pluginsFiles; - if (plugin) { - pluginsFiles = plugin.files || plugin; - version = plugin.version; - } else { - pluginsFiles = self.json.resources.pluginsFiles[pack.name]; - version = pack.version; - } - - self.pluginsLoaded[pack.name] = version; - - if (!Array.isArray(pluginsFiles)) - pluginsFiles = [pluginsFiles]; - - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) - filesToLoad.push({ name: item.name, url: url, type: item.type }); - } - } - - } - - if (filesToLoad.length > 0) { - - let promises = []; - - filesToLoad.forEach(function (item) { - promises.push(loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content })); - - }); - - Promise.all(promises).then(function (files) { - - callback(...params); - - }).catch(function (script) { - self.log('failed to load error'); - self.log(item); - self.log(script); - }); - } - }; - - -/* - Method: pluginsRequired -Description: Functionality for pluginsRequired. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.pluginsRequired = function (params) { - - if (self.json.resources) { - const pluginsFunctions = self.json.resources.pluginsFunctions; - var pluginsRequired = []; - if (typeof params == 'string') { - - if (pluginsFunctions[params]) { - if (!self.pluginsLoaded[pluginsFunctions[params].name]) - pluginsRequired.push(pluginsFunctions[params]); - } - } else if (typeof params == 'object') { - var objArray; - if (Array.isArray(params)) objArray = params; else objArray = [params]; - - for (var obj of objArray) { - - for (var key in obj) { - var mainFunction = (key.indexOf('.') >= 0) ? key.substr(0, key.indexOf('.')) : key; - - if (pluginsFunctions[mainFunction]) { - if (!self.pluginsLoaded[pluginsFunctions[mainFunction].name]) - pluginsRequired.push(pluginsFunctions[mainFunction]); - } - - } - } - } - return pluginsRequired; - } else { - return []; - } - }; - - -/* - Method: functionName -Description: Functionality for functionName. -@param {any} obj - Description for obj -@returns {any} - Result of the operation - */ -this.functionName = function (obj) { - if (obj == 'object') { - const name = Object.keys(obj)[0]; - const pluginFunctions = ['database', 'ace', 'moment', 'dayjs']; - if (pluginFunctions.indexOf(name) >= 0) - return name; - } - }; - - -/* - Method: for -Description: Functionality for for. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.for = function (params, selectorParams, args) { - - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - - let itemsName = params.id || params.name; - - if (params.of) { - - var itemsArray = self.replaceProperties(params.of, args); - - if (itemsArray) { - - if (params.html) { - if (!params.do) params.do = []; - else if (!Array.isArray(params.do)) params.do = [params.do]; - params.do.push({ html: params.html }); - } - - if (typeof itemsArray == 'object') { - - let indexNum = 0; - - for (var index in itemsArray) { - - var item = itemsArray[index]; - - if (typeof item == 'object') { - item.key = index; - item.index = index; - } - - if (typeof item.output == 'object') { - - for (let key in item.output) { - - var output = item.output[key]; - if (typeof output == 'string') { - output = self.js(output, args); - } else if (typeof output == 'object') { - - output = self.replaceProperties(output, args); - } - - item = self.replaceItems(item, output, key); - - } - } - - if (params.do.length > 0) { - - let objWithIndex = self.cloneObject(params.do); - - if (params.var) { - self.element({ path: params.var, value: item, root: self.json.var }); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, 'index:' + params.var, index); - - } - - if (itemsName) { - - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, 'index:' + itemsName, index); - objWithIndex = self.replacePropertyWithPrefix(objWithIndex, itemsName, item); - - } - - if (params.delay) { - params.delay = self.replaceProperties(params.delay); - - let forId = params.var || itemsName; - self.timer({ - name: 't' + forId + index, - after: indexNum * params.delay, - do: objWithIndex - }); - } else { - self.do(objWithIndex, { selector: container }); - } - } - - indexNum += 1; - - } - } - } - - } else if (params.from !== undefined && params.to !== undefined) { - - var step = self.js(self.replaceProperties(params.step)) || 1; - var from = self.js(self.replaceProperties(params.from)) || 0; - var to = self.js(self.replaceProperties(params.to)); - - if (to !== undefined) { - - for (var index = Number(from); index <= Number(to); index += Number(step)) { - - if (params.var) - self.element({ path: params.var, value: index, root: self.json.var }); - - var item = self.replaceItems(params, String(index), itemsName); - - if (item.output && typeof item.output == 'object') { - - for (let key in item.output) { - - var output = item.output[key]; - if (typeof output == 'string') { - output = self.js(output, args); - } else if (typeof output == 'object') { - - output = self.replaceProperties(output, args); - } - - item = self.replaceItems(item, output, key); - - } - } - - if (item.do) { - params.do = self.replacePropertyWithPrefix(item.do, 'index:' + itemsName, index); - - self.do(item.do, selectorParams, args); - - } - if (item.html) { - - params.html = self.replacePropertyWithPrefix(item.html, 'index:' + itemsName, index); - self.html(item.html, selectorParams); - } - } - } - } else { - self.log('"for" element requires "value" or "from" and "to" parameters'); - self.log(params); - } - - }; - - -/* - Method: htmlTag -Description: Functionality for htmlTag. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} tagParam - Description for tagParam -@param {any} mainParam - Description for mainParam -@returns {any} - Result of the operation - */ -this.htmlTag = function (params, selectorParams, tagParam, mainParam) { - - if (Array.isArray(params)) { - for (var index in params) - self.htmlTag(params[index], selectorParams, tagParam, mainParam); - } else { - - let htmlTagSplitter = tagParam.indexOf(' '); - if (htmlTagSplitter > 0) { - let tagClass = tagParam.substr(htmlTagSplitter + 1); - tagParam = tagParam.slice(0, htmlTagSplitter); - if (tagClass) { - if (typeof params !== 'object') params = { 'text': String(params) }; - if (!params.attr) params.attr = {}; - - let tagArr = tagClass.split(' '); - var attrClass = ''; - for (let tagProp of tagArr) { - let tagAttr = new RegExp("([_a-zA-Z]+[_a-zA-Z0-9-]*)=(.+)"); - if (tagAttr.test(tagProp)) { - - let tagPropArr = tagProp.split('='); - params.attr[tagPropArr[0]] = tagPropArr[1]; - } else { - attrClass += ' ' + tagProp; - } - } - - if (params.attr.class) - params.attr.class = params.attr.class + attrClass; - else { - params.attr.class = attrClass; - } - - } - } - - let htmlTagObj = self.createTagParams(params, tagParam, mainParam); - - self.do(htmlTagObj, selectorParams); - - if (params.database) self.addFirebaseTag(self.extend({}, params, selectorParams)); - - } - }; - - -/* - Method: createTagParams -Description: Functionality for createTagParams. -@param {any} params - Description for params -@param {any} tagParam - Description for tagParam -@param {any} mainParam - Description for mainParam -@returns {any} - Result of the operation - */ -this.createTagParams = function (params, tagParam, mainParam) { - if (!mainParam) { - switch (tagParam) { - case 'header': - case 'main': - case 'footer': - case 'div': - case 'p': - mainParam = 'html'; - break; - case 'img': - mainParam = 'src'; - break; - default: - mainParam = 'text'; - break; - } - } - var paramsObj = {}; - if (typeof params == 'string') paramsObj[mainParam] = params; else paramsObj = params; - paramsObj.tag = tagParam; - return paramsObj; - }; - - this.onResize = []; - this.onHashChange = []; - this.onScroll = []; - - -/* - Method: notEmptyObject -Description: Functionality for notEmptyObject. -@param {any} obj - Description for obj -@returns {any} - Result of the operation - */ -this.notEmptyObject = function (obj) { - return (obj - && Object.keys(obj).length > 0); - - }; - - -/* - Method: run -Description: Functionality for run. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.run = function (params, selectorParams, args) { - - if (Array.isArray(params)) { - for (var index in params) - self.run(params[index], selectorParams, args); - } else { - - var codeToRun; - if (typeof params == 'object') - codeToRun = self.cloneObject(params); - else if (typeof params == 'string') - codeToRun = self.replaceProperties(params); - else if (typeof params == 'function') - return params(args); - - else - return params; - - if (typeof codeToRun == 'object') { - var selector = codeToRun.selector || codeToRun.container; - if (!selector) selector = selectorParams; - if (typeof selector == 'string') selector = { selector: selector }; - - var actions = {}; - for (key in codeToRun) { - - if (nodes.extend.indexOf(key) >= 0) { - var obj = {}; - obj[key] = codeToRun[key]; - self.extendJson(self.json, obj); - } else if (['setup', 'container', 'selector', 'resources', 'on', 'do'].indexOf(key) < 0) - actions[key] = codeToRun[key]; - } - - if (codeToRun.on) { self.on(codeToRun.on, selector); } - if (codeToRun.do) { self.do(codeToRun.do, selector, args); } - - if (self.notEmptyObject(actions)) { - - return self.do(actions, selector, args); - - } - } - } - - }; - - -/* - Method: inputValue -Description: Functionality for inputValue. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.inputValue = function (params) { - var selector = self.selector(params.selector || params.container); - var element = document.querySelector(selector); - return element.value; - }; - - this.part = -/* - Method: block -Description: Functionality for block. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.block = function (params, selectorParams, args) { - - let nested; - let part; - let partArguments; - - if (typeof params.do == 'string' && self.json.parts) { - - self.log('PART: ' + params.do, 'brown'); - - params.do = self.replaceProperties(params.do); - - if (typeof params.do == 'object') - part = params.do; - - else - part = self.element({ path: self.replaceAll(params.do, ':', '.'), root: self.json.parts }); - - } else if (typeof params.do == 'object') - part = params.do; - - if (part) { - - if (params.arguments) - partArguments = self.replaceProperties(params.arguments); - - if (typeof params.arguments == 'object') { - partArguments = (params.arguments.setup) ? params.arguments.setup : params.arguments; - partArguments.selector = partArguments.selector || params.selector; - } - - nested = self.replacePropertyWithPrefix(part, 'setup', partArguments); - nested = self.replacePropertyWithPrefix(nested, 'arguments', partArguments); - - self.extendJsonFromElement(nested); - self.do(nested, params.selector, partArguments); - } - }; - - -/* - Method: blocks -Description: Functionality for blocks. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.blocks = function (params, selectorParams, args) { - if (Array.isArray(params)) { - for (var index in params) - self.blocks(params[index], selectorParams, args); - } else { - - if (typeof params == 'string') { - - var blockName = self.replaceProperties(params, args); - - var libraryObj = self.element({ path: 'self.json.blocks.' + blockName }); - - if (libraryObj) - - self.run(libraryObj, selectorParams, args); - - else - self.log('library component not found: ' + params); - } else { - self.run(params, selectorParams, args); - - } - } - }; - - -/* - Method: uiUpdate -Description: Functionality for uiUpdate. -@param {any} option - Description for option -@returns {any} - Result of the operation - */ -this.uiUpdate = function (option) { - window.dispatchEvent(new Event('resize')); - - }; - - -/* - Method: resizeEvent -Description: Functionality for resizeEvent. -@param {any} event - Description for event -@returns {any} - Result of the operation - */ -this.resizeEvent = function (event) { - - for (var selector in self.resizeActions) { - var element = self.query(selector); - for (var property in self.resizeActions[selector]) { - if (property == 'action') { - self.do(self.resizeActions[element].action, { selector: selector }); - - } else { - var value = self.resizeActions[selector][property]; - var result = self.replaceProperties(value) || ''; - - element.style[property] = result; - } - } - } - }; - - -/* - Method: pageFullScreen -Description: Functionality for pageFullScreen. -@param {any} onOff - Description for onOff -@returns {any} - Result of the operation - */ -this.pageFullScreen = function (onOff) { - self.log('pageFullScreen'); - if (onOff) - self.addClass(document.querySelector('body'), 'fullscreen'); - - else - self.removeClass(document.querySelector('body'), 'fullscreen'); - }; - - -/* - Method: link -Description: Functionality for link. -@param {any} link - Description for link -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.link = function (link, args) { - - link = self.replaceProperties(link, args); - window.location.href = link; - }; - - -/* - Method: reload -Description: Functionality for reload. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.reload = function () { - location.reload(); - }; - - -/* - Method: gotoHomePage -Description: Functionality for gotoHomePage. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.gotoHomePage = function () { - self.gotoPage(self.homePage()); - }; - - -/* - Method: homePage -Description: Functionality for homePage. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.homePage = function () { - - if (self.json.pages) { - if (Object.keys(self.json.pages).length > 0) { - - if (self.json.pages.home) - return 'home'; - - else - return Object.keys(self.json.pages)[0]; - } else { - self.log('No pages in "pages" node'); - } - } else { - self.log('Can\'t find the "pages" node'); - } - }; - - -/* - Method: updateCodeEditors -Description: Functionality for updateCodeEditors. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.updateCodeEditors = function () { - - var elements = document.querySelectorAll('.ace_editor'); - if (elements) { - elements.forEach(function (element, index) { - var editor = ace.edit(element); - editor.renderer.updateFull(true); - - }); - } - }; - - -/* - Method: gotoPage -Description: Functionality for gotoPage. -@param {any} pageId - Description for pageId -@param {any} fromHash - Description for fromHash -@returns {any} - Result of the operation - */ -this.gotoPage = function (pageId, fromHash) { - self.log('page'); - self.log('pageId'); - self.log(pageId); - self.log('fromHash'); - self.log(fromHash); - - if (pageId) { - - if (self.json.pages) { - if (self.json.pages[pageId]) { - var page = self.json.pages[pageId]; - - if (pageId !== self.json.setup.page.id || fromHash !== self.json.setup.page.hash) { - - if (fromHash) { - - self.json.setup.page.hash = fromHash; - } else { - - delete self.json.setup.page.hash; - } - - var fullScreen = self.json.pages[pageId].fullscreen || false; - - var pageRoles = (page.roles) ? String(page.roles).split(',') : undefined; - - if (self.params.d || !page.roles || pageRoles.indexOf(self.userRole()) >= 0) { - - if (pageId !== self.json.setup.page.id) { - - self.json.setup.page.id = pageId; - self.json.setup.page.title = page.title; - self.json.setup.page.roles = page.roles; - - self.hide({ - "class": "page" - }); - self.in({ - "class": "page", - "data-value": pageId, - "transition": "fadeIn" - }); - - self.uiUpdate(); - - } - - if (page.update) { - self.do(page.update); - - } - - if (page.init) self.do(page.init); - - self.log(page); - if (page.on) - self.on(page.on, { selector: '.page[data-value=' + pageId + ']' }); - - } else { - if (self.userRole() == 'guest') { - - } else { - self.alert('Non hai i privilegi per accedere a questa pagina'); - } - - } - } else { - - } - } else { - self.log('Can\'t find the page "' + pageId + '"'); - } - } else { - self.log('Can\'t find the main node "pages"'); - } - } else { - return self.json.setup.page; - } - }; - - var alertInterval; - - -/* - Method: getTime -Description: Functionality for getTime. -@param {any} ms - Description for ms -@returns {any} - Result of the operation - */ -this.getTime = function (ms) { - var sec = parseInt(ms / 1000); - var min = parseInt(sec / 60); - sec = sec - min * 60; - if (min < 10) min = '0' + min; - if (sec < 10) sec = '0' + sec; - return min + ':' + sec; - }; - - -/* - Method: sortablejs -Description: Functionality for sortablejs. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.sortablejs = function (params, selectorParams, args) { - let container = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - let query = self.query(container); - self.log('container'); - self.log(container); - self.log('query'); - self.log(query); - var sortable = Sortable.create(query); - }; - - -/* - Method: alert -Description: Functionality for alert. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.alert = function (params, args) { - - var paramsReplaced = self.cloneObject(params); - - if (paramsReplaced) { - if (paramsReplaced.do && paramsReplaced.do !== 'fire') { - return Swal[paramsReplaced.do](params); - - } else { - if (typeof paramsReplaced == 'string') paramsReplaced = self.text({ string: paramsReplaced, args: args }); - - if (typeof paramsReplaced == 'number') paramsReplaced = String(paramsReplaced); - if (paramsReplaced.title !== undefined) paramsReplaced.title = self.text({ string: paramsReplaced.title, args: args }); - - if (paramsReplaced.html && typeof paramsReplaced.html == 'string') paramsReplaced.html = self.replaceProperties(paramsReplaced.html, args); - if (paramsReplaced.text !== undefined) paramsReplaced.text = self.text({ string: paramsReplaced.text, args: args }); - - if (paramsReplaced.inputValue) paramsReplaced.inputValue = self.text({ string: paramsReplaced.inputValue, args: args }); - - if (paramsReplaced.cancelButtonText) paramsReplaced.cancelButtonText = self.text({ string: paramsReplaced.cancelButtonText, args: args }); - if (paramsReplaced.confirmButtonText) paramsReplaced.confirmButtonText = self.text({ string: paramsReplaced.confirmButtonText, args: args }); - if (paramsReplaced.denyButtonText) paramsReplaced.denyButtonText = self.text({ string: paramsReplaced.denyButtonText, args: args }); - - if (paramsReplaced.inputPlaceholder) paramsReplaced.inputPlaceholder = self.text({ string: paramsReplaced.inputPlaceholder, args: args }); - if (paramsReplaced.validationMessage) paramsReplaced.validationMessage = self.text({ string: paramsReplaced.validationMessage, args: args }); - - if (paramsReplaced.footer) { - paramsReplaced.footer = self.text({ string: paramsReplaced.footer, args: args }); - } - - if (paramsReplaced.upload) { - paramsReplaced.html = '
        ' + self.text('dragAndDropFiles') + '
        ' + self.text('chooseFiles') + '
        '; - - } - - alertObj.confirm = paramsReplaced.confirm; - alertObj.cancel = paramsReplaced.cancel; - alertObj.deny = paramsReplaced.deny; - alertObj.on = paramsReplaced.on; - alertObj.id = paramsReplaced.id; - delete paramsReplaced.on; - - var alertHtml = paramsReplaced.html || paramsReplaced.blocks; - if (alertHtml) - paramsReplaced.html = " "; - - var swalParams = self.replaceProperties(paramsReplaced, args); - - if (paramsReplaced.animate) { - var animationIn = paramsReplaced.animate.in || paramsReplaced.animate; - var animationOut = paramsReplaced.animate.out || paramsReplaced.animate; - if (paramsReplaced.animate.in) - animationIn = paramsReplaced.animate.in.transition || paramsReplaced.animate.in; - if (paramsReplaced.animate.out) - animationOut = paramsReplaced.animate.out.transition || paramsReplaced.animate.out; - swalParams.showClass = { - popup: 'animate__animated animate__faster animate__animated animate__' + animationIn - }; - swalParams.hideClass = { - popup: 'animate__animated animate__faster animate__animated animate__' + animationOut - }; - } - - var customIcon; - if (swalParams.icon) { - - if (typeof swalParams.icon !== 'string') { - customIcon = self.cloneObject(swalParams.icon); - delete swalParams.icon; - } - - } - - delete swalParams.blocks; - delete swalParams.onUpload; - delete swalParams.upload; - - if (swalParams.confirm) delete swalParams.confirm; - if (swalParams.cancel) delete swalParams.cancel; - if (swalParams.timerProgressBar) { - swalParams.onBeforeOpen = function () { - - alertInterval = setInterval(() => { - const content = Swal.getContent(); - if (content) { - const b = content.querySelector('b'); - if (b) { - b.textContent = self.getTime(Swal.getTimerLeft()); - } - } - }, 100); - }; - swalParams.onClose = function () { - clearInterval(alertInterval); - }; - } - - Swal.fire(swalParams).then((result) => { - - var alertResult = result.value; - - if (alertObj.on) { - if (alertObj.on.value && result.value) { - - if (alertObj.id) alertValues[alertObj.id] = result.value; - alertValues.value = result.value; - setTimeout(function () { - alertObj.on.value = self.replacePropertyWithPrefix(alertObj.on.value, 'alert', alertValues); - - self.do(alertObj.on.value, undefined, result.value); - - }, 500); - } - if (alertObj.on.isConfirmed && result.isConfirmed) { - if (alertObj.id) alertValues[alertObj.id] = result.isConfirmed; - alertObj.on.isConfirmed = self.replacePropertyWithPrefix(alertObj.on.isConfirmed, 'alert', alertValues); - alertObj.on.isConfirmed = self.replacePropertyWithPrefix(alertObj.on.isConfirmed, 'alert', result); - self.do(alertObj.on.isConfirmed, undefined, result.value); - - } - if (alertObj.on.isDenied && result.isDenied) { - alertObj.on.isDenied = self.replacePropertyWithPrefix(alertObj.on.isDenied, 'alert', result); - self.do(alertObj.on.isDenied, undefined, result.value); - - } - if (alertObj.on.isDismissed && result.isDismissed) { - alertObj.on.isDismissed = self.replacePropertyWithPrefix(alertObj.on.isDismissed, 'alert', result); - self.do(alertObj.on.isDismissed, undefined, result.dismiss); - - } - - console.log('alertValues'); - console.log(alertValues); - - } else { - - } - - }); - - if (alertHtml) - self.do(alertHtml, { selector: '#swal2-html-container' }); - - if (customIcon) { - - self.do(customIcon, { selector: '.swal2-icon' }); - - self.css({ - selector: '.swal2-icon', - style: { - 'border': '0px solid transparent' - } - }); - self.show({ - selector: '.swal2-icon' - }); - - } - - if (swalParams.on && swalParams.on.init) - self.do(swalParams.on.init); - - } - } - }; - - -/* - Method: findKey -Description: Functionality for findKey. -@param {any} obj - Description for obj -@param {any} key - Description for key -@returns {any} - Result of the operation - */ -this.findKey = function (obj, key) { - return obj.filter(function (item) { - return Boolean(item[key]); - }); - }; - - -/* - Method: formatBytes -Description: Functionality for formatBytes. -@param {any} bytes - Description for bytes -@param {any} decimals - Description for decimals -@returns {any} - Result of the operation - */ -var formatBytes = function (bytes, decimals) { - if (bytes == 0) return '0 Byte'; - var k = 1000; - var dm = decimals + 1 || 3; - var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - var i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; - }; - - -/* - Method: userRole -Description: Functionality for userRole. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.userRole = function () { - switch (Boolean(self.user('uid'))) { - case true: - return 'user'; - break; - case false: - return 'guest'; - break; - } - }; - - -/* - Method: userIn -Description: Functionality for userIn. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.userIn = function () { - - return Boolean(self.user('uid')); - }; - - -/* - Method: userOut -Description: Functionality for userOut. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.userOut = function () { - return (!self.user('uid')); - }; - - -/* - Method: user -Description: Functionality for user. -@param {any} param - Description for param -@returns {any} - Result of the operation - */ -this.user = function (param) { - - if (auth && auth.currentUser) - if (param == 'firstName') - return self.firstName(auth.currentUser['displayName']); - else if (auth.currentUser[param]) - return auth.currentUser[param]; - else if (!param) - return auth.currentUser; - - else - return undefined; - - else - return undefined; - }; - - -/* - Method: firstName -Description: Functionality for firstName. -@param {any} nameParam - Description for nameParam -@returns {any} - Result of the operation - */ -this.firstName = function (nameParam) { - var firstNameStr = (nameParam) ? nameParam.split(' ')[0] : ''; - return firstNameStr; - }; - - -/* - Method: userUid -Description: Functionality for userUid. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.userUid = function () { - if (auth) return auth.currentUser.uid; - else return undefined; - }; - - -/* - Method: userVerified -Description: Functionality for userVerified. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.userVerified = function () { - if (auth) return auth.currentUser.emailVerified; - else return undefined; - }; - - -/* - Method: thunkableMessage -Description: Functionality for thunkableMessage. -@param {any} message - Description for message -@param {any} callback - Description for callback -@returns {any} - Result of the operation - */ -this.thunkableMessage = function (message, callback) { - if (callback) callback(message); - }; - - this.onMessage = { - alert: "test" - }; - - -/* - Method: processMessage -Description: Functionality for processMessage. -@param {any} message - Description for message -@returns {any} - Result of the operation - */ -this.processMessage = function (message) { - self.alert('processMessage'); - self.do(self.onMessage, message); - - }; - - -/* - Method: thunkable -Description: Functionality for thunkable. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.thunkable = function (params, args) { - if (params.postMessage) { - var message = self.replaceProperties(params.postMessage, args); - if (message) { - try { - ThunkableWebviewerExtension.postMessage(message); - } catch (error) { - } - } - else - self.log('in function "thunkable" "postMessage" parameter is wrong'); - } - if (params.receiveMessage) { - self.onMessage = params.receiveMessage; - try { - ThunkableWebviewerExtension.receiveMessage(self.processMessage); - } catch (error) { - } - } - - }; - - -/* - Method: extendFunctions -Description: Functionality for extendFunctions. -@param {any} functions - Description for functions -@returns {any} - Result of the operation - */ -this.extendFunctions = function (functions) { - - for (var name in functions) { - if (functions[name].js) { - try { - - self.functions[name] = new Function(functions[name].js); - } catch (error) { - console.log('ERROR creating function %c' + name, 'color:orange;'); - self.log(functions[name].js); - self.log(error.message); - - } - } else { - self.log(name + ' function requires js property'); - } - } - }; - - -/* - Method: function -Description: Functionality for function. -@param {any} obj - Description for obj -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.function = function (obj, args) { - - if (obj.name && obj.js) { - - self.functions[obj.name] = new Function(obj.js); - } else if (obj.name && !obj.js) { - if (self.functions[obj.name]) { - - if (!obj.arguments || !Array.isArray(obj.arguments)) obj.arguments = [obj.arguments]; - try { - return self.functions[obj.name](...obj.arguments); - - } catch (error) { - console.log('ERROR in function %c' + obj.name, 'color:orange;'); - console.log('obj'); - console.log(obj); - console.log('function'); - console.log(self.json.functions[obj.name]); - console.log(error.message); - } - } else { - console.log('ERROR function undefined %c' + obj.name, 'color:orange;'); - } - - } else if (obj.js) { - - if (obj.arguments && Array.isArray(obj.arguments)) { - return new Function(obj.js).call(null, obj.arguments); - - } else { - return new Function(obj.js).call(null, obj.arguments); - } - } - - }; - - this.eval = -/* - Method: js -Description: Functionality for js. -@param {any} code - Description for code -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.js = function (code, args) { - - code = self.replaceProperties(code, args); - - try { - - return eval(code); - } catch (error) { - - return code; - } - - }; - - -/* - Method: if -Description: Functionality for if. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.if = function (params, selectorParams, args) { - - if (typeof params == 'object') { - - var conditionString = 'if'; - var condition; - - if (params.is !== undefined) { - if (typeof params.is == 'string') { - let isReplaced = self.replaceProperties(params.is, args, true); - self.log(isReplaced, 'grey'); - try { - condition = Boolean(eval(isReplaced)); - self.log(isReplaced + ' is ' + condition, 'grey'); - } catch (error) { - self.log(isReplaced, 'red'); - self.log('"if" condition wrong', 'red'); - self.log(error, 'red'); - } - conditionString += ' is ' + params.is; - } else if (Array.isArray(params.is)) { - let i = 0; - params.is[i]; - switch (params.is[i + 1]) { - case '=': condition = Boolean(eval(params.is[i] + '===' + params.is[i + 2])); break; - } - } - } else if (params.not !== undefined) { - condition = (!Boolean(eval(self.replaceProperties(params.not, args, true)))); - if (typeof params.not == 'string') conditionString += ' not ' + params.not; - } else if (params.regexp) { - const regex = new RegExp(params.regexp); - condition = Boolean(regex.test(params.string)); - } else if (params.isArray) { - condition = self.isArray(params.isArray); - conditionString += 'isArray ' + params.isArray; - } else if (params.exist) { - let elementExist = self.element({ path: params.exist }); - condition = (elementExist); - self.log('"if" exist ' + params.exist, 'grey'); - } else if (params.value && params.in) { - - condition = self.valueInJson(self.replaceProperties(params.in, args, true), self.replaceProperties(params.value)); - - self.log('"if" value ' + self.replaceProperties(params.value) + ' in array is ' + condition, 'grey'); - } else if (params.key && params.in) { - condition = self.keyInJson(self.replaceProperties(params.in, args, true), self.replaceProperties(params.key)); - self.log('"if" key ' + self.replaceProperties(params.key) + ' in object is ' + condition, 'grey'); - } else { - let selector = self.selector(params.selector || params.container, undefined) || self.selector(selectorParams, undefined); - - if (selector) { - if (params.exist) { - - condition = Boolean(self.exist(selector)); - conditionString += ' ' + selector + ' exist ' + params.exist; - } - if (params.hasClass) { - var element = self.query(selector); - condition = Boolean(self.hasClass(element, params.hasClass)); - conditionString += ' ' + selector + ' hasClass ' + params.hasClass; - } - if (params.isVisible) { - var element = self.query(selector); - condition = Boolean(self.isVisible(element, params.isVisible)); - conditionString += ' ' + selector + ' isVisible'; - } - if (params.isHidden) { - var element = self.query(selector); - condition = Boolean(self.isHidden(element, params.isHidden)); - conditionString += ' ' + selector + ' isHidden'; - } - if (params.inViewport) { - var element = self.query(selector); - condition = Boolean(self.inViewport(element, params.inViewport)); - conditionString += ' ' + selector + ' inViewport'; - } - if (params.outViewport) { - var element = self.query(selector); - condition = Boolean(self.outViewport(element, params.outViewport)); - conditionString += ' ' + selector + ' outViewport'; - } - if (params.isDisplay) { - var element = self.query(selector); - - condition = Boolean(self.isDisplay(element, params.isDisplay)); - conditionString += ' ' + selector + ' isDisplay ' + params.isDisplay; - } - } else { - self.log('the "if" function requires "is" or "not" parameter'); - } - } - - if (condition) - if (params.then) { - - if (typeof params.then == 'object') { - return self.do(params.then); - - } if (typeof params.then == 'string') { - return self.replaceProperties(params.then); - } else { - return params.then; - } - - } - else - self.log('the "if" function requires "then" parameter'); - else if (params.else) { - if (typeof params.else == 'object') { - return self.do(params.else); - - } if (typeof params.else == 'string') { - return self.replaceProperties(params.else); - } else { - return params.else; - } - } - } else { - - return Boolean(self.js(params, args)); - - } - }; - - -/* - Method: switch -Description: Functionality for switch. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.switch = function (params, args) { - - var value; - var answer; - if (params.expression) - value = String(self.js(params.expression, args)); - - else - self.log('"switch" function requires "expression" parameter'); - - if (params.cases) { - - if (value !== undefined && params.cases[value]) { - if (typeof params.cases[value] == 'object') - answer = self.do(params.cases[value], undefined, args); - - else - answer = params.cases[value]; - - } else if (params.cases['default']) { - self.log('default'); - self.log(params.cases['default']); - if (typeof params.cases['default'] == 'object') - answer = self.do(params.cases['default'], undefined, args); - - else - answer = params.cases['default']; - } - } else { - self.log('"switch" function requires "cases" parameter'); - self.log('answer'); - self.log(answer); - } - return answer; - }; - - -/* - Method: delay -Description: Functionality for delay. -@param {any} params - Description for params -@param {any} selector - Description for selector -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.delay = function (params, selector, args) { - self.log('delay'); - self.log('selector'); - self.log(selector); - var duration = params.duration || 1000; - duration = Number(self.replaceProperties(duration, args)); - self.log(duration); - if (params.do) { - setTimeout(function () { - self.do(params.do, selector, args); - - }, duration); - } - }; - - -/* - Method: firebasePasswordReset -Description: Functionality for firebasePasswordReset. -@param {any} paramEmail - Description for paramEmail -@param {any} paramSuccess - Description for paramSuccess -@param {any} paramError - Description for paramError -@returns {any} - Result of the operation - */ -this.firebasePasswordReset = function (paramEmail, paramSuccess, paramError) { - - firebase.auth().useDeviceLanguage(); - auth.sendPasswordResetEmail(paramEmail).then(function () { - - if (paramSuccess) self.do(paramSuccess); - - }).catch(function (error) { - - if (paramError) self.do(paramError, undefined, error.message); - - }); - }; - - -/* - Method: firebaseUpdateProfile -Description: Functionality for firebaseUpdateProfile. -@param {any} params - Description for params -@param {any} paramSuccess - Description for paramSuccess -@param {any} paramError - Description for paramError -@returns {any} - Result of the operation - */ -this.firebaseUpdateProfile = function (params, paramSuccess, paramError) { - self.log('firebaseUpdateProfile'); - self.log(params); - auth.currentUser.updateProfile(params).then(function () { - - self.log('User Profile Updated Successfully'); - if (paramSuccess) self.do(paramSuccess); - - }).catch(function (error) { - - if (paramError) self.do(paramError, undefined, error.message); - - }); - }; - - -/* - Method: firebaseRegister -Description: Functionality for firebaseRegister. -@param {any} params - Description for params -@param {any} success - Description for success -@param {any} error - Description for error -@returns {any} - Result of the operation - */ -this.firebaseRegister = function (params, success, error) { - if (params.email && params.password) { - - auth.createUserWithEmailAndPassword(params.email, params.password).then(cred => { - self.log(cred.user); - - var user = firebase.auth().currentUser; - - if (params.success) self.do(params.success); - }).catch(error => { - - if (params.error) self.do(params.error, undefined, error.message); - }); - } - }; - - -/* - Method: firebaseLogin -Description: Functionality for firebaseLogin. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.firebaseLogin = function (params) { - self.log('firebaseLogin'); - self.log(params); - - if (auth) { - auth.signInWithEmailAndPassword(String(params.email), String(params.password)).then(cred => { - - var user = firebase.auth().currentUser; - - if (user.emailVerified) { - if (params.success) self.do(self.replaceResult(params, undefined, cred)); - - } else { - self.sendEmailVerification(params); - } - }).catch(error => { - self.log('error.code'); - self.log(error.code); - if (params.error) self.do(self.replaceResult(params, undefined, error.message)); - - }); - } else { - - } - }; - - -/* - Method: firebaseLogout -Description: Functionality for firebaseLogout. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.firebaseLogout = function (params) { - self.log('firebaseLogout'); - firebase.auth().signOut().then(function () { - self.log('firebaseLogout SUCCESS'); - self.log(params.success); - if (params.success) { - - localStorage.clear(); - - self.do(params.success); - } - }).catch(function (error) { - self.log('firebaseLogout ERROR'); - self.log(error); - - if (params.error) self.do(params.error); - }); - }; - - -/* - Method: sendEmailVerification -Description: Functionality for sendEmailVerification. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.sendEmailVerification = function (params) { - self.log('sendEmailVerification'); - var user = firebase.auth().currentUser; - firebase.auth().languageCode = 'it'; - var successAction = params.success || self.reload; - user.sendEmailVerification().then(function () { - firebase.auth().signOut(); - self.alert({ - - icon: "success", - title: "verifyingemail", - html: "msgverifyingemail", - - showConfirmButton: false, - confirm: successAction - }); - - }); - }; - - -/* - Method: path -Description: Functionality for path. -@param {any} pathParams - Description for pathParams -@param {any} args - Description for args -@param {any} separatorParam - Description for separatorParam -@returns {any} - Result of the operation - */ -this.path = function (pathParams, args, separatorParam) { - var pathString = ''; - var separator = separatorParam || '/'; - - if (typeof pathParams == 'string') { - pathString = self.replaceProperties(pathParams, args); - } else { - for (var index in pathParams) { - pathObj = pathParams[index]; - if (pathString !== '') pathString += separator; - if (pathObj.string) - pathString += String(pathObj.string); - else if (pathObj.number) - pathString += Number(pathObj.number); - else if (pathObj.function) - pathString += self.doFunctionByName(pathObj.function, window, ''); - } - } - return pathString; - }; - - -/* - Method: executeFunctionByName -Description: Functionality for executeFunctionByName. -@param {any} functionName - Description for functionName -@param {any} context - Description for context -@returns {any} - Result of the operation - */ -this.executeFunctionByName = function (functionName, context ) { - - if (functionName) { - var args = [].slice.call(arguments).splice(2); - var namespaces = functionName.split("."); - var func = namespaces.pop(); - for (var i = 0; i < namespaces.length; i++) { - context = context[namespaces[i]]; - } - if (context[func] !== undefined) { - return context[func].apply(context, args); - } else { - - } - } else { - self.log('executeFunctionByName'); - self.log('functionName undefined'); - } - - }; - - this.functions = {}; - - this.methods = { - - run: function (params, container, args) { self.run(params, container, args); }, - delay: function (params, container, args) { self.delay(params, container, args); }, - ajax: function (params, container, args) { self.ajax(params, container, args); }, - do: function (params, container, args) { self.do(params, container, args); }, - module: function (params, container, args) { self.module(params, args); }, - js: function (params, container, args) { self.js(params, args); }, - function: function (params, container, args) { self.function(params, args); }, - dispatchEvent: function (params, container, args) { self.dispatchEvent(params, args); }, - - lang: function (params, container, args) { self.lang(params, args); }, - find: function (params, container, args) { self.find(params, args); }, - page: function (params, container, args) { self.page(params, args); }, - - for: function (params, container, args) { self.for(params, container, args); }, - if: function (params, container, args) { self.if(params, container, args); }, - switch: function (params, container, args) { self.switch(params, args); }, - set: function (params, container, args) { self.set(params, args); }, - - data: { - set: function (params, args) { - for (var param in params) { - - var value = params[param]; - - if (value) value = self.replaceProperties(value, args); - if (value && args) value = self.replacePropertyWithPrefix(value, 'result', args); - - self.element({ path: param, value: value }); - } - }, - get: function (params) { - return self.element(params); - }, - delete: function (params, args) { - var path = self.replaceProperties(params, args); - alert(path); - self.objToDelete = self.element({ path: path }); - delete self.objToDelete; - }, - add: function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || ''; - obj += String(value); - self.element({ path: path, value: obj }); - } - } - }, - sum: function (params, args) { - console.log('%cdeprecated key "sum". Use set{x: "{x}+1"}', 'color:orange'); - console.log(params); - console.log(args); - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj += Number(value); - self.element({ path: path, value: obj }); - } - } - }, - sub: function (params, args) { - console.log('%cdeprecated key "sub". Use set{x: "{x}+1"}', 'color:orange'); - console.log(params); - console.log(args); - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj -= Number(value); - self.element({ path: path, value: obj }); - } - } - }, - push: function (params, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.push(value); - self.element({ path: path, value: obj }); - } - } - } - }, - - text: function (params, container, args) { self.text(params, container, args); }, - html: function (params, container, args) { self.html(params, container, args); }, - attr: function (params, container, args) { self.attr(params, container, args); }, - empty: function (params, container, args) { self.empty(params, args); }, - delete: function (params, args) { - var path = self.replaceProperties(params, args); - - var obj = self.element({ path: path }); - self.log(JSON.stringify(obj)); - self.element({ path: path, delete: true }); - - self.log(obj); - }, - add: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - - if (value) { - var obj = self.element({ path: path }) || ''; - obj += String(value); - self.element({ path: path, value: obj }); - } - } - }, - sum: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj += Number(value); - self.element({ path: path, value: obj }); - } - } - }, - sub: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || 0; - obj -= Number(value); - self.element({ path: path, value: obj }); - } - } - }, - push: function (params, container, args) { - for (var param in params) { - var path = self.replaceProperties(param, args); - var value = self.replaceProperties(params[param], args); - if (value) { - var obj = self.element({ path: path }) || []; - obj.push(value); - self.element({ path: path, value: obj }); - self.log('push obj'); - self.log(obj); - } - } - }, - - calendar: function (params, container, args) { self.calendar(params, args); }, - array: function (params, container, args) { self.array(params, args); }, - replace: function (params, container, args) { self.replace(params, args); }, - shuffle: function (array) { - let currentIndex = array.length, randomIndex; - - while (currentIndex != 0) { - - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex--; - - [array[currentIndex], array[randomIndex]] = [ - array[randomIndex], array[currentIndex] - ]; - } - return array; - }, - - alert: function (params, container, args) { self.alert(params, args); }, - offcanvas: function (params, container, args) { self.offcanvas(params, args); }, - - out: function (params, container, args) { self.out(params, container, args); }, - qrcode: function (params, container, args) { self.qrcode(params, container, args); }, - hide: function (params, container, args) { self.hide(params, container, args); }, - show: function (params, container, args) { self.show(params, container, args); }, - toggle: function (params, container, args) { self.toggle(params, container, args); }, - sortablejs: function (params, container, args) { self.sortablejs(params, args); }, - lottie: function (params, container, args) { self.lottie(params, container, args); }, - chart: function (params, container, args) { - var selector = self.selector(container); - var element = self.query(selector); - element.innerHTML = ''; - const ctx = element.querySelector('canvas'); - const myChart = new Chart(ctx, self.replaceProperties(params)); - }, - - animate: function (params, container, args) { self.animate(params, container, args); }, - - uiUpdate: function (params, container, args) { self.uiUpdate(params, args); }, - swiper: { - data: {}, - init: function (params, selector, args) { - - setTimeout(function () { - - console.log('swiper inited'); - console.log(selector || params.selector); - console.log(params.options); - var swiperConfig = params.options; - self.methods.swiper.data[params.name] = new Swiper(self.selector(selector || params.selector), swiperConfig); - console.log(self.methods.swiper.data[params.name]); - }, 1000); - } - }, - - link: function (params, container, args) { self.link(params, args); }, - scroll: function (params, container, args) { self.scroll(params, args); }, - reload: function (params, container, args) { self.reload(params, args); }, - timer: function (params, container, args) { self.timer(params, args); }, - setInterval: function (params, container, args) { self.setInterval(params, args); }, - clearInterval: function (params, container, args) { self.clearInterval(params, args); }, - setTimeout: function (params, container, args) { self.setTimeout(params, args); }, - clearTimeout: function (params, container, args) { self.clearTimeout(params, args); }, - local: { - set: function (params) { - for (var param in params) { - var value = params[param]; - if (value) value = self.replaceProperties(value); - if (typeof value == 'object') value = JSON.stringify(value); - localStorage.setItem(param, value); - } - }, - get: function (key) { - var localValue = localStorage.getItem(key); - if (localValue && self.isJsonString(localValue)) - localValue = JSON.parse(localValue); - return localValue; - }, - remove: function (key) { - localStorage.removeItem(key); - }, - clear: function () { - localStorage.clear(); - } - }, - storage: { - _storage: new WeakMap(), - set: function (element, key, obj) { - if (!self.methods.storage._storage.has(element)) { - self.methods.storage._storage.set(element, new Map()); - } - self.methods.storage._storage.get(element).set(key, obj); - }, - get: function (element, key) { - return self.methods.storage._storage.get(element).get(key); - }, - has: function (element, key) { - return self.methods.storage._storage.has(element) && self.methods.storage._storage.get(element).has(key); - }, - remove: function (element, key) { - var ret = self.methods.storage._storage.get(element).delete(key); - if (!self.methods.storage._storage.get(element).size === 0) { - self.methods.storage._storage.delete(element); - } - return ret; - } - }, - - choose: function (params, container, args) { self.choose(params, container, args); }, - remove: function (params, container, args) { self.remove(params, container, args); }, - part: function (params, container, args) { self.part(params, container, args); }, - blocks: function (params, container, args) { self.part(params, container, args); }, - block: function (params, container, args) { self.part(params, container, args); }, - ace: function (params, container, args) { self.ace(params, container, args); }, - code: function (params, container, args) { self.code(params, container, args); }, - - database: function (params, container, args) { self.database(params, args); }, - firebase: function (params, container, args) { self.firebase(params, args); }, - - firebaseEvent: { - action: function (newObj) { - - var path = newObj.path; - delete newObj.path; - - document.querySelectorAll('[data-firebase="' + path + '"]').forEach(function (element, index) { - - var pathString = 'self.json.var.db.' + self.replaceAll(element.getAttribute('data-firebase'), '/', '.'); - var dbObj = self.docElement(pathString); - - var firebaseValue = newObj[element.getAttribute('data-value')]; - - var template = self.dataStorage.get(element, 'data-template'); - - if (element.tagName == 'UL') { - - var liTemplate = template.li || template.template; - - element.innerHTML = ''; - - var items = newObj; - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - - var dbParams = self.replaceItems(liTemplate, item, 'item') || ''; - - var container = element.getAttribute('data-selector'); - - self.li(dbParams, { selector: container }); - } - - } else if (element.tagName == 'SPAN' || element.tagName == 'P') { - - element.textContent = firebaseValue; - - } else if (element.tagName == 'SVG') { - - } else { - - if (template.blocks || template.html) { - var blocksTemplate = template.html || template.blocks; - - element.innerHTML = ''; - - var items = newObj; - self.log('newObj'); - self.log(newObj); - for (itemKey in items) { - var item = items[itemKey]; - item.key = itemKey; - var dbParams = self.replaceProperties(blocksTemplate, undefined, item) || ''; - - self.html(dbParams, { selector: container }); - } - } - - if (template.init) self.do(template.init); - - } - - }); - } - }, - - auth: { - init: function (params, container, args) { - self.log("auth init"); - auth = firebase.auth(); - auth.onAuthStateChanged(user => { - self.json.var.user = user; - if (!user) { - - self.log('authStateChanged: GUEST\n'); - - } else { - - self.log('authStateChanged: USER\n'); - self.log('name: ' + self.user('displayName') + '\nemail: ' + user.email + '\nuid:' + user.uid); - - } - - self.do(params.onAuthStateChanged); - - }); - }, - - sendEmailVerification: function (params, container, args) { - self.sendEmailVerification(params); - }, - - login: function (params, container, args) { - self.log('params.auth'); - self.log(params.auth); - self.log(args); - var fba = self.replaceProperties(params.auth, args); - self.log('fba'); - self.log(fba); - var fbAuth = self.cloneObject(fba); - self.log('fbAuth'); - self.log(fbAuth); - if (params.success) fbAuth.success = params.success; - if (params.error) fbAuth.error = params.error; - self.firebaseLogin(fbAuth, params.success, params.error); - }, - - register: function (params, container, args) { - - var fbAuth = self.replaceProperties(params.auth, args); - fbAuth.success = params.success; - fbAuth.error = params.error; - - self.firebaseRegister(fbAuth, params.success, params.error); - }, - - updateProfile: function (params, container, args) { - - params.profile = self.replaceProperties(params.profile, args); - self.firebaseUpdateProfile(params.profile, params.success, params.error); - }, - - passwordReset: function (params, container, args) { - - params.email = self.replaceProperties(params.email, args); - self.firebasePasswordReset(params.email, params.success, params.error); - }, - - logout: function (params, container, args) { - self.firebaseLogout(params); - } - }, - - thunkable: function (params, container, args) { self.thunkable(params, args); }, - - modelViewer: { - events: {}, - on: function (params) { - let container = self.selector(params.selector || params.container); - let element = self.query(container); - self.log('modelViewer on'); - self.log('container'); - self.log(container); - self.log('element'); - self.log(element); - if (element) { - self.methods.modelViewer.events[container] = {}; - - var event = 'load'; - if (params[event]) { - - self.methods.modelViewer.events[container][event] = params[event]; - self.log('modelViewer element'); - self.log(element); - element.addEventListener(event, (e) => { - self.log('modelViewer event'); - self.log(e); - let container = e.path[0].getAttribute('data-selector'); - self.log(container); - - self.do(self.methods.modelViewer.events[container][e.type]); - }); - } - } - }, - set: function (params) { - let element = self.query(self.selector(params.selector || params.container)); - if (element) { - if (params.color) { - let color = params.color.split(',').map(numberString => parseFloat(numberString)); - self.log('Changing color to: ', color); - const [material] = element.model.materials; - material.pbrMetallicRoughness.setBaseColorFactor(color); - } - if (params.exposure) element.exposure = params.exposure; - if (params.shadow) element.shadowIntensity = params.shadow; - if (params.orientation) element.orientation = params.orientation; - - } - } - } - }; - - -/* - Method: googleSignInPopup -Description: Functionality for googleSignInPopup. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.googleSignInPopup = function () { - self.log('googleSignInPopup'); - var provider = new firebase.auth.GoogleAuthProvider(); - - firebase.auth().useDeviceLanguage(); - - firebase.auth() - .signInWithPopup(provider) - .then((result) => { - - var credential = result.credential; - - var token = credential.accessToken; - - var user = result.user; - window.location.reload(); - - }).catch((error) => { - - var errorCode = error.code; - var errorMessage = error.message; - - var email = error.email; - - var credential = error.credential; - }); - }; - - -/* - Method: console -Description: Functionality for console. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.console = function (params, args) { - - if (typeof params.log == 'string' && params.color) { - var color = params.color || 'white'; - console.log('%c' + self.replaceProperties(params.log), 'color:' + color); - } else { - console.log(self.replaceProperties(params.log || params)); - } - }; - - -/* - Method: module -Description: Functionality for module. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.module = function (params, args) { - if (typeof params == 'string') { - var nameReplaced = self.replaceProperties(params, args); - return self.element({ root: self.modules, path: nameReplaced }); - } else { - if (params.name) { - if (params.value) { - var name = self.replaceProperties(params.name, args); - - var value = self.replaceProperties(value, args); - self.log('module'); - self.log(name); - self.log('value'); - self.log(value); - self.log(value.app.html.div.div[0].text.lang.en); - self.modules[name] = value; - } else if (params.url) { - self.addModule(params); - } - } - } - }; - - -/* - Method: db -Description: Functionality for db. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.db = function (params, args) { - self.log('db'); - if (typeof params == 'string') { - var paramsReplaced = self.replaceProperties(params, args); - self.log('paramsReplaced'); - self.log(paramsReplaced); - self.log(self.var('db.' + paramsReplaced, args)); - - return self.var('db.' + paramsReplaced, args); - - } - - }; - - -/* - Method: firebase -Description: Functionality for firebase. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.firebase = function (params, args) { - if (params.initializeApp) { - var firebaseConfig = self.replaceProperties(params.initializeApp); - firebase.initializeApp(firebaseConfig); - } else { - self.database(params, args); - } - }; - - -/* - Method: database -Description: Functionality for database. -@param {any} params - Description for params -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.database = function (params, args) { - - if (params.do == 'init') { - database = firebase.database(); - self.log('database'); - self.log(database); - } else { - if (database) { - - if (typeof params == 'string') { - - return self.db(params, args); - - } else { - - if (params) { - if (params.path) { - params.path = self.path(params.path, args); - } - - if (params.value) { - - params.value = self.replaceProperties(params.value, args); - - self.log("params.value post replace"); - self.log(params.value); - } - - if (params.do == 'init') { - } else if (params.do == 'increase') { - - self.firebaseIncrease(params); - - } else if (params.do == 'get') { - - self.firebaseGet(params.path, function (result) { - if (result.success) { - if (result.data) { - self.log('firebase get SUCCESS'); - self.log(params.success); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - - } else { - self.log('firebase get no result.data ERROR'); - - if (params.on && params.on.error) self.do(params.on.error); - } - } else { - self.log('firebase get ERROR'); - - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - - } - }); - } else if (params.do == 'new' && params.value) { - var newKey = self.getKey(params.path); - self.firebaseSet(params.path + '/' + newKey, params.value, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - - } - }); - } else if (params.do == 'remove' && params.path) { - self.firebaseRemove(params.path, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - - } - }); - } else if (params.do == 'addListener') { - self.firebaseAddListener(params); - } else if (params.do == 'removeListener') { - self.firebaseRemoveListener(params); - } else if (params.do == 'update') { - if (params.value) { - self.firebaseUpdate(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase update SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - - } else { - self.log('firebase update ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - - } - }); - } else { - self.log('data update requires value param'); - } - } else if (params.do == 'push') { - if (params.value) { - self.firebasePush(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase push SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - - } else { - self.log('firebase push ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - - } - }); - } else { - self.log('data push requires value param'); - } - } else { - if (params.value) { - self.firebaseSet(params.path, params.value, function (result) { - if (result.success) { - self.log('firebase set SUCCESS'); - if (params.on && params.on.success) self.do(params.on.success, undefined, result); - - } else { - self.log('firebase set ERROR'); - if (params.on && params.on.error) self.do(params.on.error, undefined, result); - - } - }); - } - } - - } - } - } else { - self.log('"database" function needs to be initialised'); - } - } - }; - - -/* - Method: ajax -Description: Functionality for ajax. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.ajax = function (params, selectorParams, args) { - - if (params.url) { - - var url = self.replaceProperties(params.url, args); - var data; - if (params.data) - data = JSON.stringify(self.replaceProperties(params.data, args)); - - var type = params.type || 'POST'; - var request = new XMLHttpRequest(); - request.open(type, url, true); - - request.onload = function () { - self.log('onload'); - self.log(this); - if (this.status >= 200 && this.status < 400) { - - var result = {}; - - var response = this.response; - response = response.replace(/(\\\")/g, '"'); - try { - response = decodeURI(response); - } catch (error) { - /* console.log('response'); - console.log(response); */ - console.log('decodeURI error'); - console.log(error); - } - result.response = self.parse(response); - result.status = this.status; - result.header = this.getAllResponseHeaders().split('\r\n').reduce((resultHeader, current) => { - let [name, value] = current.split(': '); - resultHeader[name] = value; - return resultHeader; - }, {}); - //} catch (e) { - //} - self.log('result'); - self.log(result); - if (params.success) - self.do(params.success, undefined, result); - //self.do(params.success, result); - //self.do(self.replaceProperty(params.success, 'result', result), result); - } else { - // We reached our target server, but it returned an error - if (params.error) - self.do(params.error, undefined, 'Server error'); - //self.do(params.error, 'Server error'); - } - }; - request.onerror = function (error) { - // There was a connection error of some sort - self.log('error'); - self.log(error); - self.log('this'); - self.log(this); - if (params.error) - self.do(params.error, undefined, 'Server unavailable'); - //self.do(params.error, 'Server unavailable'); - }; - //request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); - if (data) - request.send(data); - - else - request.send(); - } else { - self.log('ajax method requires url parameter'); - } - - /* $.ajax({ - url: paramsReplaced.url, - type: params.type || 'post', - //dataType: 'json', // questo dovrebbe evitare JSON.parse - //dataType: 'text', // verificare se necessario - data: paramsReplaced.data || {}, - success: function (result) { - self.log('ajax'); - self.log('result'); - self.log(result); - self.do(params.success, result); - //self.do(data); // in .params dovrebbe andare il resto - }, - error: function (error) { - var errorText = error.responseText || error; - self.do(params.error, errorText); - //self.do(data); // in .params dovrebbe andare il resto - } - }); */ - }; - - /* View in fullscreen */ - -/* - Method: openFullscreen -Description: Functionality for openFullscreen. -@param {any} id - Description for id -@returns {any} - Result of the operation - */ -this.openFullscreen = function (id) { - var element = document.getElementById(id); - - if (screenfull.isEnabled) { - screenfull.request(element); - } - - }; - - /* -/* - Method: addListener -Description: Functionality for addListener. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.addListener = function(params) { - var selector = self.selector(params); - if (selector) - $(selector).on(params.event, self.do(params.action)); - //event.stopPropagation(); - } */ - /* Close fullscreen */ - -/* - Method: closeFullscreen -Description: Functionality for closeFullscreen. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.closeFullscreen = function () { - - //document.exitFullscreen(); - screenfull.off('change'); // callback - }; - - /* -/* - Method: list -Description: Functionality for list. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@returns {any} - Result of the operation - */ -this.list = function (params, selectorParams) { - - var container = (selectorParams) ? self.selector(selectorParams) : params.container; - var selector = self.selector(self.extend({}, params, selectorParams)); - - if (selector) { - - if (params.list) params.items = params.list; // retro-compatibilità - - if (params.listAction) $(selector).data('listAction', params.listAction); - if (params.listClass) $(selector).data('listClass', params.listClass); // ul - - if (params.items) { - - $(selector).empty(); - var index = 0; - - //params.items = self.replaceTags({text:params.items, args:selectorParams}); - //params.items = self.replaceResult(params.items, selectorParams); - params.items = self.replaceProperties(params.items, selectorParams); - - for (var itemKey in params.items) { - // da rimuovere id="item'+itemKey+'" href="" - //self.log('PARAMETRI'); - //self.log(itemKey); - //self.log(params.items); - - $(selector).append('
      • '); - var item = params.items[itemKey]; - //var itemSelector = selector + ' li:eq(' + index + ')'; - var itemSelector = selector + ' li:eq(' + itemKey + ')'; - - // Item action - var itemAction; - if (item.action) - itemAction = item.action; - else if (params.action) - itemAction = params.action; - else if ($(selector).data('listAction')) - itemAction = $(selector).data('listAction'); - item.action = itemAction; - - if (item.action) { - $(itemSelector).addClass('list-group-item-action'); - $(itemSelector).css('cursor', 'pointer'); - } - if (item.color) $(itemSelector).css('color', item.color); - if (item.background) $(itemSelector).css('background', item.background); - - //$(itemSelector).append('
        '); - - var itemFields = params.items[itemKey].fields || params.items[itemKey]; // retro-compatibilità - //self.log('itemFields'); - //self.log(itemFields); - - for (var itemField in itemFields) { - var field = itemFields[itemField]; - //self.log(field); - if (itemField == 'icons') { - - self.icons(field, {container: itemSelector}); - - } else if ((itemField != 'params') && (itemField != 'action')) { // retro-compatibilità - $(itemSelector).append(''+self.text(itemFields[itemField])+''); - } - } - - // action - if (item.action) { - $(itemSelector).data('onData', item); - $(itemSelector).on(self.touch, function (event) { - event.stopPropagation(); - self.onEvent(this, event); - }); - } - // events - if (item.on) self.on(item.on, {container: selector}); - - index++; - } - } else if (params.append) { - // aggiunge una riga alla fine (calcolare path) - } else if (params.prepend) { - // aggiunge una riga all'inizio (calcolare path) - // sballa tutti i dati presenti in var.functions - // sarebbe meglio mem in data value tutto il json - // azione - } - - // List classes - - //if (params.id) $(selector).attr('id', params.id); - var listClass = $(selector).data('listClass'); - - if (listClass) { - var ulClass = listClass.ul || ''; - var liClass = listClass.li || ''; - - $(selector).addClass(ulClass); - $(selector + ' > li').addClass(liClass); - - var index = 0; - for (var field in listClass.fields) { - var fieldClass = listClass.fields[field] || ''; - $(selector + ' > li > span[data-field='+field+']').addClass(fieldClass); - index++; - } - } - } - } */ - -/* - Method: scroll -Description: Functionality for scroll. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.scroll = function (params) { - // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView - // {id, class, value} - var selector = self.selector(params.selector || params.container); - var block = document.querySelector(selector); - //var offset = elem.dataset.offset ? parseInt(elem.dataset.offset) : 0; - if (block) { - var bodyOffset = document.body.getBoundingClientRect().top; - window.scrollTo({ - top: block.getBoundingClientRect().top - bodyOffset, // + offset, - behavior: 'smooth' - }); - } else { - self.log('scroll to unknown element: ' + selector); - } - }; - - /* -/* - Method: scroll -Description: Functionality for scroll. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.scroll = function (params) { - // var selector = self.selector(params); - //var obj = $(selector).get(0); - - var selector = "g."+params.class+".myLabelStyle."+params.value; - - //var parent = $(selector).parent().get(0); - - //document.querySelector(selector).scrollIntoView(); - //self.resizeEvent(); // bug workaround - //$(selector).parent().scrollTop($(selector).position().top); - $(selector).parent().animate({ - //scrollTop: $(selector).position().top - //scrollTop: $(selector).position().top, - transform: 'translate(0,-'+$(selector).position().top+'), scale(1)' - }); - } - */ - //------------------------ - /* -/* - Method: do -Description: Functionality for do. -@param {any} data - Description for data -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.do = function (data, args) { - if (data) { - if (typeof data == 'string' && self.json.actions[data]) { - self.do(self.json.actions[data], args); - } else { - if (!data.index) data.index = 0; - if (!data.tasks) { - if (Array.isArray(data)) { - - if (data.index < data.length) { - self.do(data[data.index]); - data.index = data.index +1; - self.do(data); - } else { - delete data.index; - } - } else { - self.do(data); - } - //} else if (data.tasks.length > 0) { - } else { - if (data.index < data.tasks.length) { - var currentTask = data.tasks[data.index]; - //var currentTask = data.tasks.shift(); - if (currentTask.params == undefined) {currentTask.params = {}} - if (data.params == undefined) {data.params = {}} - if (currentTask.if == undefined) {currentTask.if = true} - var taskParams = currentTask.params; // parametri specifici del task - taskParams.params = data.params; - taskParams.index = data.index+1; - //for (var param in data.params) {taskParams[param] = data.params[param]; } // merge - taskParams.tasks = data.tasks; - var taskIf = (typeof currentTask.if == "function") ? currentTask.if() : currentTask.if; - - if (taskIf) { - if (currentTask.delay !== undefined) { - setTimeout(function () { - self.do(currentTask.task, taskParams); - - }, currentTask.delay); - } else if (currentTask.interval !== undefined) { - self.createTaskInterval(currentTask); - } else { - self.do(currentTask.task,taskParams); - - } - } else { - self.do(taskParams); - } - } - } - } - } - } */ - /* -/* - Method: playTaskInterval -Description: Functionality for playTaskInterval. -@param {any} taskFunction - Description for taskFunction -@returns {any} - Result of the operation - */ -this.playTaskInterval = function (taskFunction) { - self.log('playTaskInterval'); - var taskName = taskFunction.name; - if (tasksIntervals[taskName]) { - clearInterval(tasksIntervals[taskName].id); - tasksIntervals[taskName].id = setInterval(function () { - tasksIntervals[taskName].task(tasksIntervals[taskName].params); - }, tasksIntervals[taskName].interval); - } else { - self.log('taskName: '+taskName); - } - } - - -/* - Method: stopTaskInterval -Description: Functionality for stopTaskInterval. -@param {any} taskFunction - Description for taskFunction -@returns {any} - Result of the operation - */ -this.stopTaskInterval = function (taskFunction) { - self.log('stopTaskInterval'); - var taskName = taskFunction.name; - if (tasksIntervals[taskFunction.name]) { - clearInterval(tasksIntervals[taskFunction.name].id); - } else { - self.log('taskName: '+taskName); - } - } - - -/* - Method: createTaskInterval -Description: Functionality for createTaskInterval. -@param {any} myTask - Description for myTask -@returns {any} - Result of the operation - */ -this.createTaskInterval = function (myTask) { - tasksIntervals[myTask.task.name] = {}; - tasksIntervals[myTask.task.name].task = myTask.task; - tasksIntervals[myTask.task.name].params = myTask.params; - tasksIntervals[myTask.task.name].interval = myTask.interval; - self.playTaskInterval(myTask.task.name); - } - - -/* - Method: addTimedTask -Description: Functionality for addTimedTask. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.addTimedTask = function (data) { - self.log('addTimedTask'); - if (data.frequence && data.task) { - if (!data.active) {data.active = true;} - if (!timedTasks[data.frequence]) {timedTasks[data.frequence] = {}} - timedTasks[data.frequence][data.task] = {active:data.active, params:{}}; - if (data.params) { - timedTasks[data.frequence][id].params = data.params; - } - } - } - - -/* - Method: removeTimedTask -Description: Functionality for removeTimedTask. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.removeTimedTask = function (data) { - self.log('removeTimedTask'); - if (data.frequence && data.task) { - delete timedTasks[data.frequence][data.task]; - } - } - - -/* - Method: doTimedTask -Description: Functionality for doTimedTask. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.doTimedTask = function (data) { - self.log('doTimedTask'); - self.log(data); - for (var task in timedTasks[data.frequence]) { - var taskObj = timedTasks[data.frequence][task]; - if (taskObj.active) { - self.do(task, taskObj.params); - } - } - } */ - //------------------------ - // CSS METHODS - //------------------------ - /* // SELETTORI - var previewPanel = '.appPanel[data-value="pnlPreview"]'; - var toolsPanel = '.appPanel[data-value="pnlTools"]'; - - var stagePanel = '.framePanel[data-value="pnlStage"]'; - var devicePanel = '.framePanel[data-value="pnlDevice"]'; - - -/* - Method: closePanel -Description: Functionality for closePanel. -@param {any} value - Description for value -@returns {any} - Result of the operation - */ -this.closePanel = function(value) { - self.log(value); - - switch (value) { - case 'closePanelTools': - $(toolsPanel).fadeOut(); - $(previewPanel).fadeIn(); - case 'closePanelFrame': - $(devicePanel).fadeOut(); - $(stagePanel).fadeIn(); - } - } - */ - //------------------------ - // CSS METHODS - //------------------------ - /* -/* - Method: cssProp -Description: Functionality for cssProp. -@param {any} propPar - Description for propPar -@returns {any} - Result of the operation - */ -this.cssProp = function (propPar) { - var cssObj = {transform: ''}; - if ((propPar.x) && (propPar.y)) {cssObj.transform += ' translate('+propPar.x+'px,'+propPar.y+'px)'; } - if (propPar.rotateY) {cssObj.transform += ' rotateY('+propPar.rotateY+'deg)'; } - if (propPar.rotateX) {cssObj.transform += ' rotateX('+propPar.rotateX+'deg)'; } - if (propPar.scale) {cssObj.transform += ' scale('+propPar.scale+','+propPar.scale+')'; } - if (propPar.deg) {cssObj.transform += ' rotate('+propPar.deg+'deg)'; } - if (propPar.opacity) {cssObj.opacity = propPar.opacity;} - return cssObj; - } */ - /* -/* - Method: getCSS -Description: Functionality for getCSS. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.getCSS = function (data) { - var $inspector = $("
        ").css('display', 'none').addClass(data.class); - $("body").append($inspector); // add to DOM, in order to read the CSS property - try { - var props = []; - for (i=0; i { - /* self.log('animate'); - self.log('params'); - self.log(params); - - self.log('selectorParams'); - self.log(selectorParams); */ - - /* selectorParams.container = (params.container) ? params.container : selectorParams.container; - selectorParams.id = (params.id) ? params.id : selectorParams.id ; - selectorParams.class = (params.class) ? params.class : selectorParams.class; - selectorParams.value = (params.value) ? params.value : selectorParams.value; */ - const prefix = 'animate__'; - //var selector = self.selector(self.extend({}, params, selectorParams), undefined, true); // selectAll - let selector = self.selector(params.selector || params.container, undefined, true) || self.selector(selectorParams, undefined, true); - //var selector = self.selector(params.selector || params.container, selectorParams, true); // selectAll - /* self.log('animate'); - self.log('selector'); - self.log(selector); */ - var transition = params.transition || params; - transition = self.replaceProperties(transition, args); - - const duration = params.duration || '0.5s'; - - const animationName = `${prefix}${transition}`; - - if (!selector) { - self.log('animate function without selector'); - self.log(params); - self.log(selectorParams); - } else { - - var elements = self.queryAll(selector); - /* console.log('elements'); - console.log(elements); */ - //var elements = document.querySelectorAll(selector); - if (elements) - elements.forEach(function (element, index) { - if (element) { - //element.classList.add(`${prefix}animated`, animationName); - //console.log(element.classList); - element.classList.add('animate__animated', animationName); - element.style.setProperty('--animate-duration', duration); - } else { - console.log('element'); - console.log(element); - } - }); - - if (params.on && params.on.start) - self.do(params.on.start, { selector: selector }); - //self.do(params.on.start, undefined, {selector: selector}); - if (params.style) self.css(params, selectorParams); // TO DO: deprecated / to be removed - - //if (params.infinite) - // node.style.setProperty('--animate-infinite', 'infinite'); - // When the animation ends, we clean the classes and resolve the Promise - -/* - Method: handleAnimationEnd -Description: Functionality for handleAnimationEnd. -@param {any} event - Description for event -@returns {any} - Result of the operation - */ -function handleAnimationEnd(event) { - if (params.on && params.on.end) { - self.do(params.on.end, { selector: selector }); - //self.do(params.on.end, undefined, {selector: selector}); - /* self.log('handleAnimationEnd'); - self.log('params.on.end'); - self.log(params.on.end); */ - } - - event.stopPropagation(); - - if (elements) - elements.forEach(function (element, index) { - if (element) - element.classList.remove('animate__animated', animationName); - }); - resolve('Animation ended'); - } - - if (elements) - elements.forEach(function (element, index) { - if (element) - element.addEventListener('animationend', handleAnimationEnd, { once: true }); - }); - } - }); - }; - - /* - -/* - Method: animation -Description: Functionality for animation. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.animation = function (data) { // deprecated - - if (data.animation != undefined) { - if (data.animation == 'show') { - $(data.object).css({'display':'block', opacity:1}); - } else if (data.animation == 'hide') { - $(data.object).css({'display':'none'}); - } else { - //if (data.autoDisplay == undefined) {data.autoDisplay = true}; - //var animationObject = self.cloneObject(animations[data.animation]); - var animationObject = jQuery.extend({}, animations[data.animation]); - //if (data.autoDisplay) - // if (data.animation == 'fadeIn') $(data.object).css({'display':'block'}); - if (data.reverse) {animationObject.name += 'Reverse'} - if (data.duration !== undefined) {animationObject.duration = data.duration} - - animationObject.complete = function () { - if (data.autoDisplay) { - if ((data.animation == 'fadeOut') || (data.animation == 'hide')) { - $('data.object').css({'display':'none'}); - } - } - if (data.onComplete !== undefined) { - self.do(data.onComplete); - } - } - self.log('animationObject.name'); - self.log(animationObject.name); - self.log('animationObject'); - self.log(animationObject); - - // playKeyframe va aggiornato con - // animate({from, to, ease, type, stiffness, dumping, mass, velocity, duration}) - // https://popmotion.io/#quick-start-animation-animate-keyframes-options - //var obj = popmotion.styler($(data.object)); - //popmotion.animate(animationObject).start(obj.set); // $(data.object).css - - $(data.object).playKeyframe(animationObject); - } - } else { - $(data.object).resetKeyframe(); - $(data.object).css({'opacity':1,'display':'block'}); - self.log('ANIMATION UNDEFINED'); - self.log(data); - } - } - - -/* - Method: move -Description: Functionality for move. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.move = function (data) { // deprecated - var targetPos = {x:0,y:0}; - if (data.target != 'center') { targetPos = {x:384,y:384}; } - else if (data.target !== undefined) {targetPos = self.getTransform(data.target);} - else {self.log(data);} - if (data.move == 'toTarget') { - TweenMax.to(data.object, self.TweenMaxDuration(data.duration), { x: targetPos.x, y: targetPos.y}); - } else if (data.move == 'fromTarget') { - TweenMax.from(this, self.TweenMaxDuration(data.duration), { x: targetPos.x, y: targetPos.y}); - } - if (data.animation !== undefined) { - self.animation({object:data.object, animation:data.animation}); - } - } - - -/* - Method: TweenMaxDuration -Description: Functionality for TweenMaxDuration. -@param {any} duration - Description for duration -@returns {any} - Result of the operation - */ -this.TweenMaxDuration = function (duration) { - if (duration != undefined) {return Number(duration)/1000} else {return 0.667;} - } - */ - // CSS CLASSES - -/* - Method: addClassRule -Description: Functionality for addClassRule. -@param {any} ruleName - Description for ruleName -@param {any} ruleParams - Description for ruleParams -@returns {any} - Result of the operation - */ -this.addClassRule = function (ruleName, ruleParams) { - //self.log('addClassRule'); - var ruleProperties = '{'; - for (var property in ruleParams) { - if (typeof ruleParams[property] == 'object') { - self.addClassRule(ruleName + ' ' + property, ruleParams[property]); - } else { - ruleProperties += property + ':' + ruleParams[property] + ';'; - } - } - ruleProperties += '}'; - self.styleObj.sheet.insertRule(ruleName + ' ' + ruleProperties); - }; - - -/* - Method: addApplyRule -Description: Functionality for addApplyRule. -@param {any} ruleName - Description for ruleName -@param {any} ruleParams - Description for ruleParams -@returns {any} - Result of the operation - */ -this.addApplyRule = function (ruleName, ruleParams) { - // Use @apply to inline any existing utility classes into your own custom CSS - // https://tailwindcss.com/docs/functions-and-directives#apply - self.styleObj.sheet.insertRule(ruleName + ' {@apply ' + ruleParams + '}'); - }; - - -/* - Method: findPlugin -Description: Functionality for findPlugin. -@param {any} name - Description for name -@returns {any} - Result of the operation - */ -this.findPlugin = function (name) { - if (self.json.plugins) { - for (var plugin of self.json.plugins) { - if (plugin.name == name) return plugin; - } - } else { - return false; - } - }; - - -/* - Method: defineCss -Description: Functionality for defineCss. -@param {any} cssObj - Description for cssObj -@returns {any} - Result of the operation - */ -this.defineCss = function (cssObj) { - self.log('defineCss'); - - self.styleObj = document.createElement("style"); - - document.head.appendChild(self.styleObj); - self.styleObj.appendChild(document.createTextNode("")); - - /* self.styleObj.sheet.insertRule('@tailwind base;'); - self.styleObj.sheet.insertRule('@tailwind components;'); - self.styleObj.sheet.insertRule('@tailwind utilities;'); */ - // shortcuts (must be improved / can't be extended) - /* if (self.json.shortcuts && self.json.shortcuts.class) - shortcuts = self.json.shortcuts.class; */ - if (cssObj) { - if (Array.isArray(cssObj)) { - for (var cssElement of cssObj) { - //console.log(cssElement); - for (var elementName in cssElement) { - //console.log(elementName); - let valueWithData = self.replaceProperties(cssElement[elementName]); - self.addClassRule(elementName, valueWithData); - } - } - } else { - for (var elementName in cssObj) { - let valueWithData = self.replaceProperties(cssObj[elementName]); - self.addClassRule(elementName, valueWithData); - } - } - } - - if (self.pluginsLoaded.tailwindcss) { - var plugin = self.findPlugin('tailwindcss'); - //var config = (plugin) ? plugin.config : {preflight: false}; - var config = (self.json.setup.config.tailwindcss) ? self.json.setup.config.tailwindcss : { preflight: false }; - //if (self.json.style.theme) setup.theme = self.json.style.theme; - //loadPlugin(undefined, 'tailwind-config', undefined, undefined, JSON.stringify(config)) // version 2.2.0 - if (tailwind) - tailwind.config = config; - - else - console.log('tailwind object is undefined'); - } - - /* // OBSOLETE - if (self.pluginsLoaded.twind && window.twind) { - var plugin = self.findPlugin('twind'); - var config = (plugin) ? plugin.config : {preflight: false, mode:'silent'}; - //if (self.json.setup.target) setup.target = self.query(self.json.setup.target); - //if (self.json.style.theme) setup.theme = self.json.style.theme; - - window.twind.setup(config); - - } */ - /* if (self.pluginsLoaded.windicss && window.windicssRuntimeOptions) { - - var config = self.json.style.windi || { - // enabled preflight - preflight: false, - // scan the entire dom tree to infer the classnames on page loaded - extractInitial: false, - // generate mock classes for browser to do the auto-completeion - mockClasses: false, - // the windi config you are used to put in `windi.setup.js` - setup: {}, - theme: {extend: {}} - }; - if (self.json.style.theme) setup.theme.extend = self.json.style.theme; - window.windicssRuntimeOptions = config; - } */ - /* if (self.pluginsLoaded.unocss) { - - var config = self.json.style.unocss || { // -> self.json.plugins[].setup - rules: [ - // custom rules... - ], - presets: [ - // custom presets... - ], - // ... - }; - if (self.json.style.theme) setup.theme = self.json.style.theme; - if (self.json.shortcuts) setup.shortcuts = self.json.shortcuts; - - window.__unocss = config; - //alert(JSON.stringify(config)); - } */ - //self.do(data); - }; - - /* -/* - Method: createLoader -Description: Functionality for createLoader. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.createLoader = function (data) { - // !--
        Loading...
        --> - - if (self.json.loader) $('.preloader img').attr('src', self.json.loader); - self.do(data); - } */ - /* -/* - Method: preloadIcons -Description: Functionality for preloadIcons. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.preloadIcons = function (data) { - self.log('preloadIcons'); - // to do: check for duplicated ids - - if (self.json.icons) { - if (!data.icons && self.json.icons) data.icons = self.cloneObject(self.json.icons); - if (data.icons) { - var iconSet = Object.keys(data.icons)[0]; - var icons = data.icons[iconSet]; - delete data.icons[iconSet]; - if (icons.preload) { - - var ajax = new XMLHttpRequest(); - ajax.open("GET", icons.src, true); - ajax.onload = function(e) { - - if (this.status >= 200 && this.status < 400) { - - self.log('Icon set loaded ' + iconSet); - - var result = this.response; // responseText - //self.log(result); - var div = document.createElement("div"); - //var iconsHtml = new XMLSerializer().serializeToString(result); - var iconsHtml = result; - iconsHtml = self.replaceAll(iconsHtml, 'id="', 'id="' + iconSet + '_'); - div.innerHTML = iconsHtml; - div.setAttribute("style", "display: none"); - //div.setAttribute("aria-hidden", "true"); - //document.getElementbyId('preloadIcons').appendChild(element); - document.body.insertBefore(div, null); - if (Object.keys(data.icons).length > 0) - self.preloadIcons(data); - else - self.do(data); - } - } - ajax.send(); - - } else { - if (Object.keys(data.icons).length > 0) - self.preloadIcons(data); - else - self.do(data); - } - } else - self.do(data); - } else { - self.do(data); - } - } */ - /* -/* - Method: initApp -Description: Functionality for initApp. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.initApp = function (data) { - self.log('initApp'); - - self.defineCss(); - - window.addEventListener('resize', self.resizeEvent); - - if (self.json) { // can be self.json.init - //if (self.json.on.init) - if (self.json.on) - self.on(self.json.on); - - //else - // self.log('no on init functions'); - } - //self.do(data); - } - */ - /* -/* - Method: createUI -Description: Functionality for createUI. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.createUI = function (data) { - jsonic.do({ - tasks:[ - {task: self.firebaseInit}, - { - task: self.firebaseVerifyUser, - params: { - code: self.params.oobCode - } - }, - {task: self.getDevices, if: jsonic.userIn}, - {task: self.defineCss}, - {task: self.defineAnimations}, // animazioni css predefinite - {task: self.createHeader}, - {task: self.createMenu, params: { - container: '#menu', - id: data.params.mode || 'guest' - }}, - {task: jsonic.createPages} - ] - }); - } */ - /* -/* - Method: openPageFromUrl -Description: Functionality for openPageFromUrl. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.openPageFromUrl = function(data){ - jsonic.log('openPageFromUrl'); - jsonic.log('self.params'); - jsonic.log(self.params); - - var pageId = ''; - - //if (localStorage.getItem('scanning')) { - // self.hashopenTask({id:localStorage.getItem('scanningFile')}); - //} else { - - //self.disableFileIcons(); - - //var noDevices = (jsonic.userIn() && (!var.db.devices || Object.keys(var.db.devices).length == 0)); - //if (noDevices && !self.params.d && !self.params.m) { - // jsonic.gotoPage('devices'); - //} else { - - if (window.location.hash && window.location.hash !== '') { - //pageId = window.location.hash.substr(1); - self.hash(); - } else { - if (self.params.p) // retro-compatibilità - pageId = self.params.p; - else - pageId = self.homePage(); - self.gotoPage(pageId); - } - - //} - self.do(data); - } -*/ - /* - // Load a script from given `url` - -/* - Method: loadPlugin -Description: Functionality for loadPlugin. -@param {any} url - Description for url -@returns {any} - Result of the operation - */ -var loadPlugin = function(url) { - return new Promise(function(resolve, reject) { - const script = document.createElement('script'); - script.src = url; - - script.addEventListener('load', function() { - // The script is loaded completely - resolve(true); - }); - - document.head.appendChild(script); - }); - }; - - // Perform all promises in the order - -/* - Method: waterfall -Description: Functionality for waterfall. -@param {any} promises - Description for promises -@returns {any} - Result of the operation - */ -var waterfall = function(promises) { - return promises.reduce( - function(p, c) { - // Waiting for `p` completed - return p.then(function() { - // and then `c` - return c().then(function(result) { - return true; - }); - }); - }, - // The initial value passed to the reduce method - Promise.resolve([]) - ); - }; - - // Load an array of scripts in order - -/* - Method: loadScriptsInOrder -Description: Functionality for loadScriptsInOrder. -@param {any} arrayOfJs - Description for arrayOfJs -@returns {any} - Result of the operation - */ -var loadScriptsInOrder = function(arrayOfJs) { - self.log('loadScriptsInOrder'); - self.log(arrayOfJs); - const promises = arrayOfJs.map(function(url) { - self.log(url); - return loadScript(url); - }); - return waterfall(promises); - }; - */ - -/* - Method: hash -Description: Functionality for hash. -@param {any} path - Description for path -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.hash = function (path, args) { - self.log('hash'); - var path = self.replaceProperties(path, args); - self.log(path); - window.location.hash = path; - }; - - -/* - Method: page -Description: Functionality for page. -@param {any} path - Description for path -@param {any} args - Description for args -@returns {any} - Result of the operation - */ -this.page = function (path, args) { - self.log('page'); - var path = self.replaceProperties(path, args); - self.log(path); - if (path.startsWith('#')) - window.location.hash = path; - - else - window.location.href = path; - //window.location.hash = path; - }; - - -/* - Method: hashChangeEvent -Description: Functionality for hashChangeEvent. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.hashChangeEvent = function () { - self.log('hashChangeEvent'); - self.log(window.location.hash); - - /* if (window.location.hash && window.location.hash !== '') { - var hashParams = window.location.hash.substr(1).split('/'); - self.gotoPage(hashParams[0], hashParams[1]); - } else { - //pageId = self.homePage(); - if (self.json.setup && self.json.setup.wordpress && self.json.setup.wordpress.slug) - self.gotoPage(self.json.setup.wordpress.slug); - else - self.gotoPage(self.homePage()); - } - - if (json && json.app && json.app.on && json.app.on.page) { // page event - self.do(json.app.on.page); - } - - if (json && json.actions && json.actions.init) { // obsolete - self.do(json.actions.init); - } */ - }; - - /* -/* - Method: addPageListeners -Description: Functionality for addPageListeners. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.addPageListeners = function (data) { - self.log('addPageListeners'); - - // Resize event - window.addEventListener('resize', self.resizeEvent); - - // Location hash (url) event - window.addEventListener('hashchange', self.hashChangeEvent); - //$(window).on('hashchange', self.hashChangeEvent); - - self.hashChangeEvent(); - - self.do(data); - - } */ - /* // testing - -/* - Method: findValues -Description: Functionality for findValues. -@param {any} obj - Description for obj -@param {any} key - Description for key -@param {any} found - Description for found -@returns {any} - Result of the operation - */ -let findValues = function(obj, key, found) { - for (let localKey in obj) { - if (obj.hasOwnProperty(localKey)) { - let val = obj[localKey]; - //self.log(localKey) - if (localKey === key) { - found.add(val) - } else { - if (typeof val === 'object') { - findValues(val, key, found) - } - } - } - } - } - -/* - Method: uniqueValue -Description: Functionality for uniqueValue. -@param {any} obj - Description for obj -@param {any} key - Description for key -@param {any} value - Description for value -@returns {any} - Result of the operation - */ -function uniqueValue(obj, key, value) { - let found = new Set() - findValues(object, key, found) - return found.size === 1 && found.has(value); - } */ - -/* - Method: lookup -Description: Functionality for lookup. -@param {any} obj - Description for obj -@param {any} k - Description for k -@returns {any} - Result of the operation - */ -this.lookup = function (obj, k) { - for (var key in obj) { - var value = obj[key]; - - if (k == key) { - return [k, value]; - } - - if (typeof (value) === "object" && !Array.isArray(value)) { - var y = lookup(value, k); - if (y && y[0] == k) return y; - } - if (Array.isArray(value)) { - // for..in doesn't work the way you want on arrays in some browsers - // - for (var i = 0; i < value.length; ++i) { - var x = lookup(value[i], k); - if (x && x[0] == k) return x; - } - } - } - - return null; - }; - - -/* - Method: findValues -Description: Functionality for findValues. -@param {any} obj - Description for obj -@param {any} key - Description for key -@returns {any} - Result of the operation - */ -this.findValues = function (obj, key) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - let matrix = [...JSON.stringify(obj).matchAll(new RegExp('\"?' + key + '\"?\:\s*\"([^,\"]+)', 'gi'))]; - var results = []; - for (var element of matrix) - results.push(element[1]); - return results; - //return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + key + '\"?\:\s+\"' + value + '\"'))) // JSON5 compatible - }; - - // testing - -/* - Method: findKey -Description: Functionality for findKey. -@param {any} obj - Description for obj -@param {any} key - Description for key -@returns {any} - Result of the operation - */ -function findKey(obj, key) { - for ([k, v] of Object.entries(obj)) { - if (k == key) return v; - if (typeof v === 'object' && v !== null) { - let found = findKey(v, key); - if (found) return found; - } - } - } - - // lookup in json - -/* - Method: keyInJson -Description: Functionality for keyInJson. -@param {any} obj - Description for obj -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -this.keyInJson = function (obj, string) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + string + '\"?\:'))); // JSON5 compatible - }; - - // lookup in json - -/* - Method: valueInJson -Description: Functionality for valueInJson. -@param {any} obj - Description for obj -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -this.valueInJson = function (obj, string) { - //return Boolean(JSON.stringify(obj).indexOf('"' + string + '":') >= 0) - return Boolean(JSON.stringify(obj).match(new RegExp('\"?' + string + '\"?'))); // JSON5 compatible - }; - - /* -/* - Method: keyInFiles -Description: Functionality for keyInFiles. -@param {any} string - Description for string -@returns {any} - Result of the operation - */ -this.keyInFiles = function (string) { - var found = self.keyInJson(self.options, string); // in main app options: jsonic = jsonicApp(options) - for (fileName in self.modules) { - if (fileName !== 'resources' && self.keyInJson(self.modules[fileName], string)) - found = true; - } - return found; - } */ - /* -/* - Method: openPageFromUrl -Description: Functionality for openPageFromUrl. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.openPageFromUrl = function (data) { - self.log('openPageFromUrl'); - self.hashChangeEvent(); - self.do(data); - }; */ - /* -/* - Method: addEventListeners -Description: Functionality for addEventListeners. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.addEventListeners = function (data) { - self.log('addEventListeners'); - - // Resize event - window.addEventListener('resize', self.resizeEvent); - - // Location hash (url) event - window.addEventListener('hashchange', self.hashChangeEvent); - $(window).on('hashchange', self.hashChangeEvent); - - self.hashChangeEvent(); // add here on.hashchange - - // Fullscreen event - if (screenfull && screenfull.isEnabled) { - screenfull.on('change', () => { - self.log('Am I fullscreen?', screenfull.isFullscreen ? 'Yes' : 'No'); - if (screenfull.isFullscreen) { - var.fullscreen = true; - if (var.onFullScreenOpen) self.do(var.onFullScreenOpen); - } else { - var.fullscreen = false; - if (var.onFullScreenClose) self.do(var.onFullScreenClose); - } - }); - } - - if (json && json.app && json.app.on) { - - if (json.app.on.thunkable && json.app.on.thunkable.receiveMessage) - window.receiveMessage(function (message) { - //document.querySelector('#message').value = message; - jsonic.functions(json.app.on.thunkable.receiveMessage, message, undefined); - }); - - var container = json.app.container || 'body'; - self.on(json.app.on, {container: container}); - self.do(data); - } else { - self.do(data); - } - } */ - /* -/* - Method: loadIconset -Description: Functionality for loadIconset. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.loadIconset = function (data) { - self.log('loadIconset'); - - if (self.json.iconset) { - if (!self.pluginsLoaded['iconify']) { - let plugin = self.json.resources.pluginsFunctions['iconify']; - self.pluginsLoader([plugin], self.loadIconset, [data]); - } else { - var iconset; - - if (!self.json.iconset[0]) - iconset = [self.json.iconset]; - else - iconset = self.json.iconset; - - for (var index in iconset) { - - if (Iconify.addCollection(iconset[index])) - self.log('added iconset '+ iconset[index].prefix); - else - self.log('can\t add iconset '+ iconset[index].prefix); - //alert(x); - } - self.do(data); - - } - - } else { - self.do(data); - } - - } */ - // Si potrebbe creare una nuova istanza di jsonicApp - -/* - Method: start -Description: Functionality for start. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.start = function () { - - self.log('start'); - - //if (params.onFullScreenOpen) var.onFullScreenOpen = params.onFullScreenOpen; - //if (params.onFullScreenClose) var.onFullScreenClose = params.onFullScreenClose; - // PWA - /* if ('serviceWorker' in navigator) { - // Register a service worker hosted at the root of the - // site using the default scope. - navigator.serviceWorker.register('/app/assets/pwa/sw.js').then(function(registration) { - self.log('Service worker registration succeeded:', registration); - }, function(error) { - self.log('Service worker registration failed:', error); - }); - } else { - self.log('Service workers are not supported.'); - } */ - let deferredPrompt; - - window.addEventListener('beforeinstallprompt', (e) => { - // Prevent Chrome 67 and earlier from automatically showing the prompt - e.preventDefault(); - // Stash the event so it can be triggered later. - deferredPrompt = e; - }); - - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - self.json.setup.darkMode = e.matches ? "dark" : false; - }); - - // DEFINE ICONSET (iconify) - if (self.json.iconset) { - if (!self.pluginsLoaded['iconify']) { - let plugin = self.json.resources.pluginsFunctions['iconify']; - self.pluginsLoader([plugin], self.start); - return false; - } else { - var iconset; - - if (!self.json.iconset[0]) - iconset = [self.json.iconset]; - - else - iconset = self.json.iconset; - - for (var index in iconset) { - - if (Iconify.addCollection(iconset[index])) - self.log('added iconset ' + iconset[index].prefix); - - else - self.log('can\t add iconset ' + iconset[index].prefix); - //alert(x); - } - - } - - } - - // DEFINE CSS - //self.defineCss(); // TO DO: only additional css (do it on load module success) - // ADD RESIZE LISTENER (for dynamic styles) TO DO: check it - window.addEventListener('resize', self.resizeEvent); - - // PAGE - if (!self.json.setup.page) self.json.setup.page = {}; - self.json.setup.page.hash = window.location.hash.substr(1); - - // DO / ON - /* if (self.json) { - if (self.json.do) - self.do(self.json.do, undefined, self.json.container); - - if (self.json.on) - self.on(self.json.on, self.json.container); - } */ - var selector = self.json.selector || self.json.container; - - /* if (self.json.do) - self.do(self.json.do, undefined, selector); */ - // should go action/run - if (self.json.on) - self.on(self.json.on, selector); - - }; - - -/* - Method: extendJson -Description: Functionality for extendJson. -@param {any} jsonBase - Description for jsonBase -@param {any} jsonExtension - Description for jsonExtension -@returns {any} - Result of the operation - */ -this.extendJson = function (jsonBase, jsonExtension) { - // TO DO: should be renamed in extendApp (or executeModule) because extend self.json and add CSS style - if (jsonExtension.css) self.defineCss(jsonExtension.css); - if (jsonExtension.functions) self.extendFunctions(jsonExtension.functions); - - for (var key in jsonExtension) { - // AGGIUNGERE ALL'ARRAY DELLE AZIONI ON.INIT... - if (key == 'on') { - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') { - //jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - if (!jsonBase[key][subKey]) jsonBase[key][subKey] = []; - jsonBase[key][subKey].push(jsonExtension[key][subKey]); - } else { - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } - } - } else if (key == 'parts' || key == 'shortcuts') { // combine subelements - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } - /* } else if (key == 'css') { - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } */ - /* } else if (key == 'app') { // to do: obsolete - for (var subKey in jsonExtension[key]) { - if (typeof jsonExtension[key][subKey] !== 'string') - jsonBase[key][subKey] = self.extend({}, jsonBase[key][subKey], jsonExtension[key][subKey]); - else - jsonBase[key][subKey] = jsonExtension[key][subKey]; - } */ - } else if (key == 'iconset' || key == 'plugins') { // combine arrays - if (!jsonBase[key]) jsonBase[key] = []; - jsonBase[key] = jsonBase[key].concat(jsonExtension[key]); - } else { - if (key == 'css') { - } else { - jsonBase[key] = self.extend({}, jsonBase[key], jsonExtension[key]); - } - } - } - return jsonBase; - }; - - -/* - Method: loadModuleFromDb -Description: Functionality for loadModuleFromDb. -@param {any} data - Description for data -@returns {any} - Result of the operation - */ -this.loadModuleFromDb = function (data) { - self.log('loadModuleFromDb'); - self.firebaseGet('jsonic', function (result) { - if (result.success) { - self.log('firebase get SUCCESS'); - for (codeKey in result.data) - if (result.data[codeKey].code) - self.extendJson(json, result.data[codeKey].code); - //self.log('json'); - //self.log(json); - //if (params.success) self.do(params.success,result.data); - } else { - self.log('firebase get ERROR'); - //if (params.error) self.do(params.error, result.error); - // alert errore di connessione. alert riprova - } - self.do(data); - //self.do(data); - }); - }; - - this.modules = {}; - this.modulesLoading = {}; - - -/* - Method: fileType -Description: Functionality for fileType. -@param {any} fileName - Description for fileName -@returns {any} - Result of the operation - */ -this.fileType = function (fileName) { - return /(?:\.([^.]+))?$/.exec(fileName)[1]; - }; - - -/* - Method: jsoncToJson -Description: Functionality for jsoncToJson. -@param {any} jsoncText - Description for jsoncText -@returns {any} - Result of the operation - */ -this.jsoncToJson = function (jsoncText) { - return jsoncText.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1').replace(/\r/, "\n").replace(/\n[\n]+/, "\n"); - // https://stackoverflow.com/questions/244777/can-comments-be-used-in-json/24545329 - }; - //var json = jsoncToJson('https://fantacards.com/app/data.jsonc'); - //console.log(json); - -/* - Method: loadModule -Description: Functionality for loadModule. -@param {any} mod - Description for mod -@returns {any} - Result of the operation - */ -this.loadModule = function (mod) { - /* self.log('loadModule'); - self.log(mod); */ - // params: {files, onComplete} - // self.cloneObject(params.json) to avoid to remove from initial params - //if (typeof setup.modules == 'string') setup.modules = [setup.modules]; - if (!self.modulesLoading[mod.name] && !self.modules[mod.name]) { - self.modulesLoading[mod.name] = true; - - return new Promise(function (resolve, reject) { - //mod = self.replaceProperties(mod); - //self.log(mod); - - const getAPIData = new XMLHttpRequest(); - getAPIData.open("GET", mod.url); - getAPIData.onload = function () { - self.modulesLoading[mod.name] = false; - //console.log(getAPIData); - let responseText = getAPIData.responseText; - if (self.fileType(getAPIData.responseURL) == 'jsonc') - responseText = self.jsoncToJson(responseText); - // try - const result = JSON.parse(responseText); - // error self.log('Wrong JSON in module '+ mod.name); - if (self.isJson(result)) { - self.modules[mod.name] = result; - self.extendJson(self.json, result); - self.log('Loaded module ' + mod.name, 'grey'); - } else { - self.log('Wrong JSON in module ' + mod.name, 'red'); - } - resolve(); - }; - getAPIData.onerror = function () { - self.modulesLoading[mod.name] = false; - }; - getAPIData.send(); - }); - - } else { - self.log('Module ' + mod.name + ' already loaded', 'orange'); - } - - }; - - /* -/* - Method: loadPlugin -Description: Functionality for loadPlugin. -@param {any} url - Description for url -@returns {any} - Result of the operation - */ -var loadPlugin = function (url) { - //self.log('loading ' + url); - - return new Promise(function(resolve, reject) { - var type = 'script'; - if (url.endsWith('.css')) type = 'link'; - - let obj = document.createElement(type); - - // obj.src = url; - obj.async = false; - obj.onload = function() { - resolve(url); - }; - obj.onerror = function() { - self.log('error loading: '+url); - reject(url); - }; - - if (type === 'script') { - if (url) obj.src = url; - //if (code) obj.text = code; - obj.location = document.body; - document.body.appendChild(obj); - } else { - obj.href = url; - obj.rel = 'stylesheet'; - obj.type = 'text/css'; - obj.location = document.head; - document.head.appendChild(obj); - } - - //self.log('obj'); - //self.log(obj); - }); - } */ - -/* - Method: loadPlugin -Description: Functionality for loadPlugin. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -var loadPlugin = function (params) { - //self.log('loading ' + url); - - return new Promise(function (resolve, reject) { - var tag = 'script', type = 'text/javascript'; - if (params.type == 'script') { tag = 'script'; type = 'text/javascript'; } - else if (params.type == 'module') { tag = 'script'; type = 'module'; } - else if (params.type == 'tailwind-config') { tag = 'script'; type = 'tailwind-config'; } - else if (params.type == 'link') { tag = 'link'; type = 'text/css'; } - else if (params.type == 'font') { tag = 'link'; type = undefined; } - //if (!tag) - // tag = (url.endsWith('.js')) ? 'script' : 'link'; - let obj = document.createElement(tag); - if (params.content) - obj.appendChild(document.createTextNode(params.content)); - - obj.async = false; - obj.onload = function () { - self.pluginsLoaded[params.name] = { version: "1.0.0" }; - self.log('Loaded plugin ' + params.name, 'grey'); - resolve(params.url); - }; - obj.onerror = function () { - self.log('Error loading plugin ' + params.url, 'red'); - reject(params.url); - }; - - if (tag === 'script') { - if (params.url) obj.src = params.url; - //if (code) obj.text = code; - obj.location = document.body; - obj.type = type || 'text/javascript'; - /* if (type == 'tailwind-config') { - self.log('obj'); - self.log(obj); - } */ - document.body.appendChild(obj); - } else if (tag === 'link') { - obj.rel = params.rel || 'stylesheet'; - obj.location = document.head; - if (params.url) obj.href = params.url; - if (type) obj.type = type; - if (params.as) obj.as = params.as; - document.head.appendChild(obj); - } - }); - }; - - /* -/* - Method: loadPlugin -Description: Functionality for loadPlugin. -@param {any} url - Description for url -@param {any} tag - Description for tag -@param {any} rel - Description for rel -@param {any} as - Description for as -@returns {any} - Result of the operation - */ -var loadPlugin = function (url, tag, rel, as) { - //self.log('loading ' + url); - - //alert(url); - - return new Promise(function(resolve, reject) { - if (tag == 'js') tag = 'script'; - if (tag == 'css') tag = 'link'; - if (!tag) - tag = (url.endsWith('.js')) ? 'script' : 'link'; - - let obj = document.createElement(tag); - - obj.async = false; - obj.onload = function() { - self.log('loaded plugin: '+url); - resolve(url); - }; - obj.onerror = function() { - self.log('error loading: '+url); - reject(url); - }; - - if (tag === 'script') { - if (url) obj.src = url; - //if (code) obj.text = code; - obj.location = document.body; - document.body.appendChild(obj); - } else { - obj.href = url; - obj.rel = rel || 'stylesheet'; - if (obj.rel == 'stylesheet') - obj.type = 'text/css'; - if (as) - obj.as = as; - obj.location = document.head; - document.head.appendChild(obj); - } - }); - } - */ - this.uiLoaded = {}; - this.pluginsLoaded = {}; - - //The Firebase Realtime Database lets you store and query user data, and makes it available between users in realtime - -/* - Method: findUrl -Description: Functionality for findUrl. -@param {any} array - Description for array -@param {any} url - Description for url -@returns {any} - Result of the operation - */ -this.findUrl = function (array, url) { - for (var item of array) { - if (item.url == url) - return true; - } - }; - - /* -/* - Method: export -Description: Functionality for export. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.export = function (params) { - // {name, data} - if (params && params.name && params.data) { - let element = document.createElement('a'); - element.style.display = 'none'; - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(params.data))); - element.setAttribute('download', params.name); - document.body.appendChild(element); - element.click(); - document.body.removeChild(element); - } else { - self.log('"export" requires name and data attributes'); - } - } */ - /* -/* - Method: exportData -Description: Functionality for exportData. -@param {any} path - Description for path -@returns {any} - Result of the operation - */ -this.exportData = function (path) { - // data - const fileName = self.replaceAll(path, ' ', '.') + '.json'; - const jsonData = self.element({path: path, root: params.root}); - self.export({name: fileName, data: jsonData}); - } - */ - -/* - Method: loadPlugins -Description: Functionality for loadPlugins. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.loadPlugins = function () { - //self.log('loadPlugins'); - //var setup = json.setup; - // TEMPORAL API - // https://cdn.jsdelivr.net/npm/@cogitatio/tc39-temporal@0.0.12-alpha.2/index.js - // https://cdn.jsdelivr.net/npm/cogitatio-tc39-temporal@1.0.2/index.js - /* */ - var filesToLoad = []; - - // plugins - if (self.json.plugins) { - for (var index in self.json.plugins) { - - var plugin = self.json.plugins[index]; - - //self.log('loading ' + plugin.name + '...'); - var version = plugin.version || ''; - - if (!plugin.ondemand) { // V. >= 1.0.2 - - if (plugin.url) { // directly loaded - // plugin.name and version are needed? - if (!self.findUrl(filesToLoad, plugin.url)) { // not included yet - filesToLoad.push({ name: plugin.name, url: plugin.url, type: plugin.type }); - } - - } else { // from resources (TO DO: remove) - - var pluginsFiles = plugin.files || self.json.resources.pluginsFiles[plugin.name]; - - // moved in loadPlugin = ... onload - /* self.pluginsLoaded[plugin.name] = { - version: version - }; */ - if (!Array.isArray(pluginsFiles)) - pluginsFiles = [pluginsFiles]; - - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (plugin.params) url += '?' + plugin.params; - let pluginName = plugin.name || item.name; - if (!url || !self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({ name: pluginName, url: url, type: item.type, content: item.content }); - } - - } - } - } - } - - // ui - /* for (var index in config.ui) { - - var configUI = config.ui[index]; - - //self.log('loading ' + configUI.name + '...'); - - var version = configUI.version || ''; - var uiFiles = self.json.resources.uiFiles[configUI.name]; - - if (!Array.isArray(uiFiles)) - uiFiles = [uiFiles]; - - for (item of uiFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({url: url, type: item.type, content: item.content}); - } - } */ - // Auto load Google Fonts - // TO DO: comment - for (fontName of self.findValues(self.json, 'font-family')) { - if (self.json.resources.googleFonts.indexOf(fontName) >= 0) { - //alert(fontName); - fontName = self.replaceAll(fontName, ' ', '+'); - //filesToLoad.push({type: 'font', url:'https://fonts.googleapis.com/css2?family='+fontName+'&display=swap', rel:'preload', as:'font'}); - filesToLoad.push({ type: 'link', url: 'https://fonts.googleapis.com/css2?family=' + fontName }); - // +'&display=swap' // https://css-tricks.com/almanac/properties/f/font-display/ - } - } - - // Auto load plugins (firebase only) - /* if (config.plugins && config.plugins.autoload) { - self.log('plugins autoload'); - //for (var index in self.json.resources.pluginsFunctions) { - var pluginFunctions = self.json.resources.pluginsFirebase; // pluginFunctions - for (var index in self.json.resources.pluginsFirebase) { - //self.log(index + ':' + self.keyInFiles(index)); - if (self.keyInFiles(index)) { - if (pluginFunctions[index]) { - - var plugins = []; - if (Array.isArray(pluginFunctions[index])) - plugins = pluginFunctions[index]; - else - plugins = [pluginFunctions[index]]; - - for (plugin of plugins) { - - self.log('loading ' + plugin.name + '...'); - self.pluginsLoaded[plugin.name] = version; - - var version = plugin.version || ''; - var pluginsFiles = self.json.resources.pluginsFiles[plugin.name]; - - if (!Array.isArray(pluginsFiles)) - pluginsFiles = [pluginsFiles]; - - for (item of pluginsFiles) { - var url = self.replaceAll(item.url, '{version}', version); - if (!self.findUrl(filesToLoad, url)) // not included yet - filesToLoad.push({url: url, type: item.type, content: item.content}); - } - } - } - } - } - } */ - // load multiple scripts in sequence - // https://bit.ly/3nT5Ky1 - // one after another - // https://medium.com/@asimmittal/sequential-script-loading-in-javascript-a0b77ca9467c - // load multi js and css - // https://sphacks.io/load-multiple-js-scripts-dynamically-without-jquery/ - // save all Promises as array - let promises = []; - - //promises.push(loadPlugin("https: - - filesToLoad.forEach(function (item) { - if (item.url) - promises.push(loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content })); - - else - loadPlugin({ name: item.name, url: item.url, type: item.type, rel: item.rel, as: item.as, content: item.content }); - - }); - - Promise.all(promises).then(function () { - - self.start(); - - }).catch(function (script) { - self.log('Failed to load'); - self.log(script); - }); - - }; - - -/* - Method: modulesList -Description: Functionality for modulesList. -@param {any} modulesObj - Description for modulesObj -@returns {any} - Result of the operation - */ -this.modulesList = function (modulesObj) { - - var modulesList = []; - if (modulesObj) { - for (key in modulesObj) { - var mod = self.replaceProperties(modulesObj[key]); - modulesList = modulesList.concat(mod); - } - } - return self.replaceProperties(modulesObj); - }; - - -/* - Method: loadModules -Description: Functionality for loadModules. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.loadModules = function () { - - if (self.json.setup.modules) { - var modules = self.replaceProperties(self.json.setup.modules); - - var promises = []; - modules.forEach(function (item) { - if (!self.modulesLoading[item.name] && !self.modules[item.name]) { - promises.push(self.loadModule(item)); - } - }); - - Promise.all(promises).then(function () { - - self.loadPlugins(); - - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - }); - - } else { - self.loadPlugins(); - } - - }; - - this.moduleExecuted = {}; - - -/* - Method: addModule -Description: Functionality for addModule. -@param {any} params - Description for params -@returns {any} - Result of the operation - */ -this.addModule = function (params) { - - if (!self.modules[params.name]) { - - var promises = []; - - promises.push(self.loadModule(params)); - - Promise.all(promises).then(function () { - - if (!self.moduleExecuted[params.name]) { - - var module = self.modules[params.name]; - - if (module.html) { - self.moduleExecuted[params.name] = true; - self.html(module.html); - - } - } - if (params.success) - self.do(params.success); - - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - if (params.error) - self.do(params.error); - - }); - } else { - if (params.success) - self.do(params.success); - - } - }; - - -/* - Method: loadModuleGlobal -Description: Functionality for loadModuleGlobal. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -this.loadModuleGlobal = function () { - self.log('loadModuleGlobal'); - - var promises = []; - - var modules = []; - for (let key in self.json.setup.modules) { - var mod = self.replaceProperties(self.json.setup.modules[key]); - modules = modules.concat(self.cloneObject(mod)); - } - - for (let mod of modules) - promises.push(self.loadModule(mod)); - - Promise.all(promises).then(function () { - - self.loadModules(); - - }).catch(function (file) { - self.log('Failed to load'); - self.log(file); - }); - }; - - -/* - Method: code -Description: Functionality for code. -@param {any} params - Description for params -@param {any} selectorParams - Description for selectorParams -@returns {any} - Result of the operation - */ -this.code = function (params, selectorParams) { - - let container = self.selector(params.selector || params.container) || self.selector(selectorParams); - - self.log("this.code"); - self.log("container"); - self.log(container); - - var editorContainer = container.slice(1); - - var editor = ace.edit(editorContainer); - - var value = params.value; - if (!params.do || (params.do == 'set')) { - - if (params.theme) editor.setTheme(params.theme); - var editorMode = params.mode || "ace/mode/json"; - editor.getSession().setMode(editorMode); - - var editorStyle = self.extend({ - background: "rgba(255,255,255,0)" - }, params.style); - - var codeOptions = self.extend({ - fontSize: "11pt", - selectionStyle: "line", - highlightActiveLine: false, - wrap: true, - showLineNumbers: false, - showGutter: false, - fixedWidthGutter: false, - readOnly: true, - - }, params.options); - - editor.setOptions(codeOptions); - - var codeString; - if (typeof value == 'string') - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(JSON.parse(value), null, '\t'); - - else - codeString = value; - else { - if (editorMode == "ace/mode/json") - codeString = JSON.stringify(value, null, '\t'); - else { - var functionObj = self.docElement(value.function); - var functionParams = value.params; - codeString = functionObj(functionParams); - } - } - - var codeRows = codeString.split(/\r\n|\r|\n/).length; - - editor.setValue(codeString, -1); - } else if (params.do == 'get') { - return editor.getValue(); - } else { - self.log('"code" function requires value param'); - } - - }; - - -/* - Method: init -Description: Functionality for init. -@param {any} appString - Description for appString -@param {any} modulesString - Description for modulesString -@returns {any} - Result of the operation - */ -this.init = function (appString, modulesString) { - console.log('init'); - - if (typeof appString == 'string') { - - let modules = [{ "name": "app", "url": appString }]; - let modulesNames = (modulesString) ? modulesString.split(",") : []; - for (let modName of modulesNames) { - modules.push({ "name": modName, "url": "jsonic/modules/" + modName + ".json" }); - } - - self.json.setup = { "modules": modules }; - - } else { - - if (appString) self.extendJson(self.json, appString); - - if (appString.css) self.defineCss(appString.css); - - } - - self.loadModuleGlobal(); - }; - - -/* - Method: toJsonNode -Description: Functionality for toJsonNode. -@param {any} xml - Description for xml -@returns {any} - Result of the operation - */ -function toJsonNode(xml) { - let obj = {}; - if (xml.nodeType == 1) { - if (xml.attributes.length > 0) { - obj["attr"] = {}; - for (let j = 0; j < xml.attributes.length; j++) { - let attribute = xml.attributes.item(j); - obj["attr"][attribute.nodeName] = attribute.nodeValue; - } - } - } - if (xml.hasChildNodes()) { - for (let i = 0; i < xml.childNodes.length; i++) { - let item = xml.childNodes.item(i); - let nodeName = item.nodeName; - if (item.nodeType == 3 && nodeName == "#text") { - if (/^\s+$/.test(item.nodeValue)) { - } else obj.text = item.nodeValue; - } else { - if (typeof obj[nodeName] == "undefined") { - obj[nodeName] = toJsonNode(item); - } else { - if (!Array.isArray(obj[nodeName])) - obj[nodeName] = [obj[nodeName]]; - obj[nodeName].push(toJsonNode(item)); - } - } - } - } - return obj; - } - - -/* - Method: htmlToJson -Description: Functionality for htmlToJson. -@param {any} text - Description for text -@returns {any} - Result of the operation - */ -this.htmlToJson = function (text) { - let xmlDoc = new DOMParser().parseFromString(text, "text/xml"); - return JSON.stringify(toJsonNode(xmlDoc), null, "\t"); - }; - - -/* - Method: elementToJson -Description: Functionality for elementToJson. -@param {any} selector - Description for selector -@returns {any} - Result of the operation - */ -this.elementToJson = function (selector) { - let el = document.querySelector(selector); - return self.htmlToJson(el.getHTML()); - }; - - -/* - Method: clearSelection -Description: Functionality for clearSelection. -@param {any} - No parameters -@returns {any} - Result of the operation - */ -function clearSelection() { - if (window.getSelection) { window.getSelection().removeAllRanges(); } - else if (document.selection) { document.selection.empty(); } - } - - -/* - Method: importHtml -Description: Functionality for importHtml. -@param {any} htmlText - Description for htmlText -@returns {any} - Result of the operation - */ -this.importHtml = function (htmlText) { - - if (!htmlText) - htmlText = prompt("html/xml"); - if (htmlText) { - let jsonDoc = self.htmlToJson(htmlText); - let textarea = document.createElement("textarea"); - textarea.value = jsonDoc; - textarea.style = "position: absolute; z-index: 999999; background: white; width:100vw; height:100vh"; - - document.body.appendChild(textarea); - - textarea.addEventListener('click', function () { - textarea.remove(); - navigator.clipboard.writeText(textarea.value).then(() => console.log('copied!')); - }); - - } - }; - - if (typeof options == 'object') { - } else if (options) - self.init(arguments[0], arguments[1]); - -} - -var jsonApp = new jsonAppObj(); -var js = jsonApp; -var jsonic = jsonApp; - diff --git a/jsonic/js/post.html b/jsonic/js/post.html deleted file mode 100755 index 703bb83..0000000 --- a/jsonic/js/post.html +++ /dev/null @@ -1,13 +0,0 @@ -
        -
        - - - -
        -
        -
        -
        \ No newline at end of file