diff -r 318533413200 -r a1707c607eec src/pyams_skin/resources/js/myams.js --- a/src/pyams_skin/resources/js/myams.js Sun Jul 19 02:02:20 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6956 +0,0 @@ -/* - * MyAMS - * « My Application Management Skin » - * - * $Tag$ (rev. 1) - * A bootstrap based application/administration skin - * - * Custom administration and application skin tools - * Released under Zope Public License ZPL 1.1 - * ©2014-2020 Thierry Florac - */ - -"use strict"; - -(function ($, globals) { - - var console = globals.console; - - /** - * String prototype extensions - */ - String.prototype.startsWith = function (str) { - var slen = this.length, - dlen = str.length; - if (slen < dlen) { - return false; - } - return (this.substr(0, dlen) === str); - }; - - String.prototype.endsWith = function (str) { - var slen = this.length, - dlen = str.length; - if (slen < dlen) { - return false; - } - return (this.substr(slen - dlen) === str); - }; - - String.prototype.unserialize = function (str) { - var str = decodeURIComponent(this); - var chunks = str.split('&'), - obj = {}; - for (var c = 0; c < chunks.length; c++) { - var split = chunks[c].split('=', 2); - obj[split[0]] = split[1]; - } - return obj; - }; - - /** - * Array prototype extensions - */ - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (elt, from) { - var len = this.length; - - from = Number(from) || 0; - from = (from < 0) ? Math.ceil(from) : Math.floor(from); - if (from < 0) { - from += len; - } - - for (; from < len; from++) { - if (from in this && this[from] === elt) { - return from; - } - } - return -1; - }; - } - - - /** - * JQuery 'hasvalue' expression - * Filter inputs containing value - */ - $.expr[":"].hasvalue = function (obj, index, meta /*, stack*/) { - return $(obj).val() !== ""; - }; - - - /** - * JQuery 'econtains' expression - * Case insensitive contains expression - */ - $.expr[":"].econtains = function (obj, index, meta /*, stack*/) { - return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() === meta[3].toLowerCase(); - }; - - - /** - * JQuery 'withtext' expression - * Case sensitive exact search expression - */ - $.expr[":"].withtext = function (obj, index, meta /*, stack*/) { - return (obj.textContent || obj.innerText || $(obj).text() || "") === meta[3]; - }; - - - /** - * JQuery filter on parents class - * This filter is often combined with ":not()" to select DOM objects which don't have - * parents of a given class. - * For example: - * - * $('.hint:not(:parents(.nohints))', element); - * - * will select all elements with ".hint" class which don't have a parent with '.nohints' class. - */ - $.expr[':'].parents = function (obj, index, meta /*, stack*/) { - return $(obj).parents(meta[3]).length > 0; - }; - - - /** - * JQuery 'scrollbarWidth' function - * Get width of default vertical scrollbar - */ - if ($.scrollbarWidth === undefined) { - $.scrollbarWidth = function () { - var parent = $('
').appendTo('body'); - var child = parent.children(); - var width = child.innerWidth() - child.height(99).innerWidth(); - parent.remove(); - return width; - }; - } - - - /** - * MyAMS JQuery extensions - */ - $.fn.extend({ - - /** - * Check if current object is empty or not - */ - exists: function () { - return $(this).length > 0; - }, - - /** - * Get object if it supports given CSS class, - * otherwise look for parents - */ - objectOrParentWithClass: function (klass) { - if (this.hasClass(klass)) { - return this; - } else { - return this.parents('.' + klass); - } - }, - - /** - * Build an array of attributes of the given selection - */ - listattr: function (attr) { - var result = []; - this.each(function () { - result.push($(this).attr(attr)); - }); - return result; - }, - - /** - * CSS style function - * Code from Aram Kocharyan on stackoverflow.com - */ - style: function (styleName, value, priority) { - // DOM node - var node = this.get(0); - // Ensure we have a DOM node - if (typeof(node) === 'undefined') { - return; - } - // CSSStyleDeclaration - var style = this.get(0).style; - // Getter/Setter - if (typeof(styleName) !== 'undefined') { - if (typeof(value) !== 'undefined') { - // Set style property - priority = typeof(priority) !== 'undefined' ? priority : ''; - style.setProperty(styleName, value, priority); - return this; - } else { - // Get style property - return style.getPropertyValue(styleName); - } - } else { - // Get CSSStyleDeclaration - return style; - } - }, - - /** - * Remove CSS classes starting with a given prefix - */ - removeClassPrefix: function (prefix) { - this.each(function (i, it) { - var classes = it.className.split(" ").map(function (item) { - return item.startsWith(prefix) ? "" : item; - }); - it.className = $.trim(classes.join(" ")); - }); - return this; - } - }); - - - /** - * MyAMS extensions to JQuery - */ - if (globals.MyAMS === undefined) { - globals.MyAMS = { - devmode: true, - devext: '', - lang: 'en', - throttleDelay: 350, - menuSpeed: 235, - navbarHeight: 49, - ajaxNav: true, - safeMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'], - csrfCookieName: 'csrf_token', - csrfHeaderName: 'X-CSRF-Token', - enableWidgets: true, - enableMobile: false, - enableFastclick: false, - warnOnFormChange: false, - formChangedCallback: null, - ismobile: (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase())) - }; - } - var MyAMS = globals.MyAMS; - var ams = MyAMS; - - /** - * Get MyAMS base URL - * Copyright Andrew Davy: https://forrst.com/posts/Get_the_URL_of_the_current_javascript_file-Dst - */ - MyAMS.baseURL = (function () { - var script = $('script[src*="/myams.js"], script[src*="/myams.min.js"], ' + - 'script[src*="/myams-core.js"], script[src*="/myams-core.min.js"], ' + - 'script[src*="/myams-require.js"], script[src*="/myams-require.min.js"]'); - var src = script.attr("src"); - ams.devmode = src.indexOf('.min.js') < 0; - ams.devext = ams.devmode ? '' : '.min'; - return src.substring(0, src.lastIndexOf('/') + 1); - })(); - - - /** - * Basic logging function which log all arguments to console - */ - MyAMS.log = function () { - if (console) { - console.debug && console.debug(this, arguments); - } - }; - - - /** - * Extract parameter value from given query string - */ - MyAMS.getQueryVar = function (src, varName) { - // Check src - if (src.indexOf('?') < 0) { - return false; - } - if (!src.endsWith('&')) { - src += '&'; - } - // Dynamic replacement RegExp - var regex = new RegExp('.*?[&\\?]' + varName + '=(.*?)&.*'); - // Apply RegExp to the query string - var val = src.replace(regex, "$1"); - // If the string is the same, we didn't find a match - return false - return val === src ? false : val; - }; - - - /** - * Color conversion function - */ - MyAMS.rgb2hex = function (color) { - return "#" + $.map(color.match(/\b(\d+)\b/g), function (digit) { - return ('0' + parseInt(digit).toString(16)).slice(-2); - }).join(''); - }; - - - /** - * Generate a random ID - */ - MyAMS.generateId = function () { - function s4() { - return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); - } - - return s4() + s4() + s4() + s4(); - }; - - - /** - * Generate a random UUID - */ - MyAMS.generateUUID = function () { - var d = new Date().getTime(); - var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = (d + Math.random() * 16) % 16 | 0; - d = Math.floor(d / 16); - return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); - }); - return uuid; - }; - - - /** - * Get an object given by name - */ - MyAMS.getObject = function (objectName, context) { - if (!objectName) { - return undefined; - } - if (typeof(objectName) !== 'string') { - return objectName; - } - var namespaces = objectName.split("."); - context = (context === undefined || context === null) ? window : context; - for (var i = 0; i < namespaces.length; i++) { - try { - context = context[namespaces[i]]; - } catch (e) { - return undefined; - } - } - return context; - }; - - /** - * Get and execute a function given by name - * Small piece of code by Jason Bunting - */ - MyAMS.getFunctionByName = function (functionName, context) { - if (functionName === undefined) { - return undefined; - } else if (typeof(functionName) === 'function') { - return functionName; - } - var namespaces = functionName.split("."); - var func = namespaces.pop(); - context = (context === undefined || context === null) ? window : context; - for (var i = 0; i < namespaces.length; i++) { - try { - context = context[namespaces[i]]; - } catch (e) { - return undefined; - } - } - try { - return context[func]; - } catch (e) { - return undefined; - } - }; - - MyAMS.executeFunctionByName = function (functionName, context /*, args */) { - var func = ams.getFunctionByName(functionName, window); - if (typeof(func) === 'function') { - var args = Array.prototype.slice.call(arguments, 2); - return func.apply(context, args); - } - }; - - /** - * Check to know if given element is still present in DOM - */ - MyAMS.isInDOM = function (element) { - element = $(element); - if (!element.exists()) { - return false; - } - return globals.document.body.contains(element[0]); - }; - - /** - * Get target URL matching given source - * - * Given URL can include variable names (with their namespace), given between braces, as in {MyAMS.baseURL} - */ - MyAMS.getSource = function (url) { - return url.replace(/{[^{}]*}/g, function (match) { - return ams.getFunctionByName(match.substr(1, match.length - 2)); - }); - }; - - /** - * Script loader function - * - * @param url: script URL - * @param callback: a callback to be called after script loading - * @param options: a set of options to be added to AJAX call - * @param onerror: an error callback to be called instead of generic callback - */ - MyAMS.getScript = function (url, callback, options, onerror) { - if (typeof(callback) === 'object') { - onerror = options; - options = callback; - callback = null; - } - if (options === undefined) { - options = {}; - } - var defaults = { - dataType: 'script', - url: ams.getSource(url), - success: callback, - error: onerror || ams.error.show, - cache: !ams.devmode, - async: options.async === undefined ? typeof(callback) === 'function' : options.async - }; - var settings = $.extend({}, defaults, options); - return $.ajax(settings); - }; - - /** - * CSS file loader function - * Cross-browser code copied from Stoyan Stefanov blog to be able to - * call a callback when CSS is realy loaded. - * See: https://www.phpied.com/when-is-a-stylesheet-really-loaded - * - * @param url: CSS file URL - * @param id: a unique ID given to CSS file - * @param callback: optional callback function to be called when CSS file is loaded. If set, callback is called - * with a 'first_load' boolean argument to indicate is CSS was already loaded (*false* value) or not (*true* - * value). - * @param options: callback options - */ - MyAMS.getCSS = function (url, id, callback, options) { - if (callback) { - callback = ams.getFunctionByName(callback); - } - var head = $('HEAD'); - var style = $('style[data-ams-id="' + id + '"]', head); - if (style.length === 0) { - style = $('