diff options
Diffstat (limited to 'js/common.js')
-rwxr-xr-x | js/common.js | 273 |
1 files changed, 208 insertions, 65 deletions
diff --git a/js/common.js b/js/common.js index fb5cc6531..670ee1b30 100755 --- a/js/common.js +++ b/js/common.js @@ -1,60 +1,225 @@ 'use strict'; -/* global dijit, __, App, Ajax */ +/* global dijit, __, App, dojo, __csrf_token */ /* eslint-disable no-new */ -/* error reporting shim */ -// TODO: deprecated; remove -/* function exception_error(e, e_compat, filename, lineno, colno) { - if (typeof e == "string") - e = e_compat; +/* exported $ */ +function $(id) { + console.warn("FIXME: please use App.byId() or document.getElementById() instead of $():", id); + return document.getElementById(id); +} - App.Error.report(e, {filename: filename, lineno: lineno, colno: colno}); -} */ +/* exported $$ */ +function $$(query) { + console.warn("FIXME: please use App.findAll() or document.querySelectorAll() instead of $$():", query); + return document.querySelectorAll(query); +} -/* xhr shorthand helpers */ -/* exported xhrPost */ -function xhrPost(url, params, complete) { - console.log("xhrPost:", params); +Element.prototype.hasClassName = function(className) { + return this.classList.contains(className); +}; - return new Promise((resolve, reject) => { - new Ajax.Request(url, { - parameters: params, - onComplete: function(reply) { - if (complete != undefined) complete(reply); +Element.prototype.addClassName = function(className) { + return this.classList.add(className); +}; - resolve(reply); - } - }); +Element.prototype.removeClassName = function(className) { + return this.classList.remove(className); +}; + +Element.prototype.toggleClassName = function(className) { + if (this.hasClassName(className)) + return this.removeClassName(className); + else + return this.addClassName(className); +}; + + +Element.prototype.setStyle = function(args) { + Object.keys(args).forEach((k) => { + this.style[k] = args[k]; }); +}; + +Element.prototype.show = function() { + this.style.display = ""; +}; + +Element.prototype.hide = function() { + this.style.display = "none"; +}; + +Element.prototype.toggle = function() { + if (this.visible()) + this.hide(); + else + this.show(); +}; + +// https://gist.github.com/alirezas/c4f9f43e9fe1abba9a4824dd6fc60a55 +Element.prototype.fadeOut = function() { + this.style.opacity = 1; + const self = this; + + (function fade() { + if ((self.style.opacity -= 0.1) < 0) { + self.style.display = "none"; + } else { + requestAnimationFrame(fade); + } + }()); +}; + +Element.prototype.fadeIn = function(display = undefined){ + this.style.opacity = 0; + this.style.display = display == undefined ? "block" : display; + const self = this; + + (function fade() { + let val = parseFloat(self.style.opacity); + if (!((val += 0.1) > 1)) { + self.style.opacity = val; + requestAnimationFrame(fade); + } + }()); +}; + +Element.prototype.visible = function() { + return this.style.display != "none" && this.offsetHeight != 0 && this.offsetWidth != 0; } -/* exported xhrJson */ -function xhrJson(url, params, complete) { - return new Promise((resolve, reject) => - xhrPost(url, params).then((reply) => { - let obj = null; - - try { - obj = JSON.parse(reply.responseText); - } catch (e) { - console.error("xhrJson", e, reply); - } +Element.visible = function(elem) { + if (typeof elem == "string") + elem = document.getElementById(elem); + + return elem.visible(); +} + +Element.show = function(elem) { + if (typeof elem == "string") + elem = document.getElementById(elem); + + return elem.show(); +} - if (complete != undefined) complete(obj); +Element.hide = function(elem) { + if (typeof elem == "string") + elem = document.getElementById(elem); - resolve(obj); - })); + return elem.hide(); +} + +Element.toggle = function(elem) { + if (typeof elem == "string") + elem = document.getElementById(elem); + + return elem.toggle(); +} + +Element.hasClassName = function (elem, className) { + if (typeof elem == "string") + elem = document.getElementById(elem); + + return elem.hasClassName(className); } -/* add method to remove element from array */ Array.prototype.remove = function(s) { for (let i=0; i < this.length; i++) { if (s == this[i]) this.splice(i, 1); } }; +Array.prototype.uniq = function() { + return this.filter((v, i, a) => a.indexOf(v) === i); +}; + +String.prototype.stripTags = function() { + return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, ''); +} + +/* exported xhr */ +const xhr = { + post: function(url, params = {}, complete = undefined) { + console.log('xhr.post', '>>>', params); + + return new Promise((resolve, reject) => { + if (typeof __csrf_token != "undefined") + params = {...params, ...{csrf_token: __csrf_token}}; + + dojo.xhrPost({url: url, + postData: dojo.objectToQuery(params), + handleAs: "text", + error: function(error) { + reject(error); + }, + load: function(data, ioargs) { + console.log('xhr.post', '<<<', ioargs.xhr); + + if (complete != undefined) + complete(data, ioargs.xhr); + + resolve(data) + }} + ); + }); + }, + json: function(url, params = {}, complete = undefined) { + return new Promise((resolve, reject) => + this.post(url, params).then((data) => { + let obj = null; + + try { + obj = JSON.parse(data); + } catch (e) { + console.error("xhr.json", e, xhr); + reject(e); + } + + console.log('xhr.json', '<<<', obj); + + if (obj && typeof App != "undefined") + if (!App.handleRpcJson(obj)) { + reject(obj); + return; + } + + if (complete != undefined) complete(obj); + + resolve(obj); + } + )); + } +}; + +/* exported xhrPost */ +function xhrPost(url, params = {}, complete = undefined) { + console.log("xhrPost:", params); + + return new Promise((resolve, reject) => { + if (typeof __csrf_token != "undefined") + params = {...params, ...{csrf_token: __csrf_token}}; + + dojo.xhrPost({url: url, + postData: dojo.objectToQuery(params), + handleAs: "text", + error: function(error) { + reject(error); + }, + load: function(data, ioargs) { + if (complete != undefined) + complete(ioargs.xhr); + + resolve(ioargs.xhr) + }}); + }); +} + +/* exported xhrJson */ +function xhrJson(url, params = {}, complete = undefined) { + return xhr.json(url, params, complete); +} + /* common helpers not worthy of separate Dojo modules */ /* exported Lists */ @@ -64,14 +229,14 @@ const Lists = { // account for dojo checkboxes elem = elem.domNode || elem; - const row = elem.up("li"); + const row = elem.closest("li"); if (row) checked ? row.addClassName("Selected") : row.removeClassName("Selected"); }, select: function(elemId, selected) { - $(elemId).select("li").each((row) => { - const checkNode = row.select(".dijitCheckBox,input[type=checkbox]")[0]; + $(elemId).querySelectorAll("li").forEach((row) => { + const checkNode = row.querySelector(".dijitCheckBox,input[type=checkbox]"); if (checkNode) { const widget = dijit.getEnclosingWidget(checkNode); @@ -94,15 +259,15 @@ const Tables = { const checked = elem.domNode ? elem.attr("checked") : elem.checked; elem = elem.domNode || elem; - const row = elem.up("tr"); + const row = elem.closest("tr"); if (row) checked ? row.addClassName("Selected") : row.removeClassName("Selected"); }, select: function(elemId, selected) { - $(elemId).select("tr").each((row) => { - const checkNode = row.select(".dijitCheckBox,input[type=checkbox]")[0]; + $(elemId).querySelectorAll("tr").forEach((row) => { + const checkNode = row.querySelector(".dijitCheckBox,input[type=checkbox]"); if (checkNode) { const widget = dijit.getEnclosingWidget(checkNode); @@ -119,7 +284,7 @@ const Tables = { getSelected: function(elemId) { const rv = []; - $(elemId).select("tr").each((row) => { + $(elemId).querySelectorAll("tr").forEach((row) => { if (row.hasClassName("Selected")) { // either older prefix-XXX notation or separate attribute const rowId = row.getAttribute("data-row-id") || row.id.replace(/^[A-Z]*?-/, ""); @@ -173,7 +338,7 @@ const Notify = { kind = kind || this.KIND_GENERIC; keep = keep || false; - const notify = $("notify"); + const notify = App.byId("notify"); window.clearTimeout(this.timeout); @@ -238,25 +403,3 @@ const Notify = { } }; -// http://stackoverflow.com/questions/6251937/how-to-get-selecteduser-highlighted-text-in-contenteditable-element-and-replac -/* exported getSelectionText */ -function getSelectionText() { - let text = ""; - - if (typeof window.getSelection != "undefined") { - const sel = window.getSelection(); - if (sel.rangeCount) { - const container = document.createElement("div"); - for (let i = 0, len = sel.rangeCount; i < len; ++i) { - container.appendChild(sel.getRangeAt(i).cloneContents()); - } - text = container.innerHTML; - } - } else if (typeof document.selection != "undefined") { - if (document.selection.type == "Text") { - text = document.selection.createRange().textText; - } - } - - return text.stripTags(); -} |