UNPKG

data-ws-hooks

Version:

Hooks html tags to js actions by using custom data attributes. Bootsratp style. Specifically useful for easily handling click events.

591 lines (497 loc) 16 kB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ window.wsGlobals = window.wsGlobals || {}; window.wsGlobals.DataHooks = require("./index").DataHooks; },{"./index":2}],2:[function(require,module,exports){ const resolvePath = require('object-resolve-path'); const DATA_ATTRIBUTE_NAMES = { onClick: "data-ws-onclick", tabData: "data-ws-tab", toggleHiddenButton: "data-ws-toggle-hidden-button", toggleHiddenData: "data-ws-toggle-hidden-data", srcHook: "data-ws-src", } class GenericDomHooks { // TODO: Add all hooks to here - this will be the only one called: static initAll() { GenericDomHooks.setDataOnClickHooks(); GenericDomHooks.setSrcHooks(); GenericDomHooks.setTabSelectorsHooks(); GenericDomHooks.setToggleHiddenHooks(); } static setDataOnClickHooks() { let attributeName = DATA_ATTRIBUTE_NAMES.onClick; let wsGlobals = window.wsGlobals || {}; document.querySelectorAll( "[" + attributeName + "]" ).forEach((el)=>{ el.addEventListener('click',(ev)=> { if (ev.currentTarget instanceof Element) { let value = ev.currentTarget.getAttribute(attributeName); console.log('clicked el with data-ws-onclick="' + value + '"'); if (value.includes(":")) { let parts = value.split(":"); let action = parts[0]; let name = parts[1]; if (action=="hideClass" && name) { GenericDomHooks.hideClass(name); } else if (action=="copy") { let target; if (!name) { target = ev.currentTarget; } else if (name.includes("#")) { let parts = name.split("#")[1].split(":"); target = document.getElementById(parts[0]); } if (target) { GenericDomHooks.copyInputValue(target); } } } else { let valueFunction; try { valueFunction = resolvePath(wsGlobals,value) || resolvePath(window,value); } catch (e) { valueFunction = null; } if (valueFunction && (valueFunction instanceof Function)) { valueFunction(ev.currentTarget); } } } }); }); }; static setSrcHooks() { let attributeName = DATA_ATTRIBUTE_NAMES.srcHook; let wsGlobals = window.wsGlobals || {}; document.querySelectorAll( "[" + attributeName + "]" ).forEach((el)=>{ let src = el.getAttribute(attributeName); el.setAttribute("src", src); }); }; static hideClass(className) { document.querySelectorAll( "." + className ).forEach((el)=>{ if (el instanceof Element) { let style = (el.getAttribute("style") || "") + ";display:none"; el.setAttribute("style", style); } }); } static setTabSelectorsHooks() { // Per tab selector click: function onTabSelected(tabName) { let tabSelectors = document.getElementsByClassName("tab-selector"); for (const tabSelector of tabSelectors) { if (tabSelector.getAttribute(DATA_ATTRIBUTE_NAMES.tabData) == tabName) { tabSelector.className = "tab-selector selected"; } else { tabSelector.className = "tab-selector"; } } let tabSections = document.getElementsByClassName("tab-section"); for (const tab of tabSections) { if (tab.getAttribute(DATA_ATTRIBUTE_NAMES.tabData) == tabName) { tab.className = "tab-section"; } else { tab.className = "tab-section hidden"; } } } let tabSelectors = document.getElementsByClassName("tab-selector"); for (const tabSelector of tabSelectors) { tabSelector.addEventListener('click', function (e) { onTabSelected(tabSelector.getAttribute(DATA_ATTRIBUTE_NAMES.tabData)); }) } } static setToggleHiddenHooks() { let buttonAttributeName = DATA_ATTRIBUTE_NAMES.toggleHiddenButton; let dataAttributeName = DATA_ATTRIBUTE_NAMES.toggleHiddenData; document.querySelectorAll( "[" + buttonAttributeName + "]" ).forEach((el)=>{ el.addEventListener('click',(ev)=> { if (ev.currentTarget instanceof Element) { let value = ev.currentTarget.getAttribute(buttonAttributeName); document.querySelectorAll( "[" + dataAttributeName + "='" + value + "']" ).forEach((elData)=>{ if (elData instanceof Element) { if (elData.classList.contains('hidden')) { elData.classList.remove('hidden'); } else { elData.classList.add('hidden'); } } }); } }); }); } static copyInputValue(target, text) { //debugger; console.log('copyInputValue, ', target, text); let successMessage = "✅ Copied successfully"; // console.log(target); let el = target; let value = text; if (!text) { value = el.value; if (!value) { if (target.tagName.toLowerCase() != "input") { el = target.querySelector("input"); } if (!el) { return; } else { value = el.value; } } if (value == successMessage) { return; } } this.copyToClipboard(value, (isSuccess)=>{ if (isSuccess) { el.value = successMessage; setTimeout(()=>{ el.value = value; },1000); } else {} }); } static async copyToClipboard (txt, ondone) { console.log('copyTo... ', txt, ondone); try { //document.body.focus(); await navigator.clipboard.writeText(txt); if (ondone) { ondone(true); } return true; } catch (err) { if (ondone) { ondone(false); } return false; } }; } GenericDomHooks.initAll(); exports.DataHooks = GenericDomHooks; },{"object-resolve-path":3}],3:[function(require,module,exports){ var Path = require('./path') /** * * @param {Object} o * @param {String} path * @returns {*} */ module.exports = function (o, path) { if (typeof path !== 'string') { throw new TypeError('path must be a string') } if (typeof o !== 'object') { throw new TypeError('object must be passed') } var pathObj = Path.get(path) if (!pathObj.valid) { throw new Error('path is not a valid object path') } return pathObj.getValueFrom(o) } },{"./path":4}],4:[function(require,module,exports){ // gutted from https://github.com/Polymer/observe-js/blob/master/src/observe.js function noop () {} function detectEval () { // Don't test for eval if we're running in a Chrome App environment. // We check for APIs set that only exist in a Chrome App context. if (typeof chrome !== 'undefined' && chrome.app && chrome.app.runtime) { return false } // Firefox OS Apps do not allow eval. This feature detection is very hacky // but even if some other platform adds support for this function this code // will continue to work. if (typeof navigator != 'undefined' && navigator.getDeviceStorage) { return false } try { var f = new Function('', 'return true;') return f() } catch (ex) { return false } } var hasEval = detectEval() function isIndex (s) { return +s === s >>> 0 && s !== '' } function isObject (obj) { return obj === Object(obj) } var createObject = ('__proto__' in {}) ? function (obj) { return obj } : function (obj) { var proto = obj.__proto__ if (!proto) return obj var newObject = Object.create(proto) Object.getOwnPropertyNames(obj).forEach(function (name) { Object.defineProperty(newObject, name, Object.getOwnPropertyDescriptor(obj, name)) }) return newObject } function parsePath (path) { var keys = [] var index = -1 var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath' var actions = { push: function () { if (key === undefined) return keys.push(key) key = undefined }, append: function () { if (key === undefined) key = newChar else key += newChar } } function maybeUnescapeQuote () { if (index >= path.length) return var nextChar = path[index + 1] if ((mode == 'inSingleQuote' && nextChar == "'") || (mode == 'inDoubleQuote' && nextChar == '"')) { index++ newChar = nextChar actions.append() return true } } while (mode) { index++ c = path[index] if (c == '\\' && maybeUnescapeQuote(mode)) continue type = getPathCharType(c) typeMap = pathStateMachine[mode] transition = typeMap[type] || typeMap['else'] || 'error' if (transition == 'error') return // parse error mode = transition[0] action = actions[transition[1]] || noop newChar = transition[2] === undefined ? c : transition[2] action() if (mode === 'afterPath') { return keys } } return // parse error } var identStart = '[\$_a-zA-Z]' var identPart = '[\$_a-zA-Z0-9]' var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$') function isIdent (s) { return identRegExp.test(s) } var constructorIsPrivate = {} function Path (parts, privateToken) { if (privateToken !== constructorIsPrivate) throw Error('Use Path.get to retrieve path objects') for (var i = 0; i < parts.length; i++) { this.push(String(parts[i])) } if (hasEval && this.length) { this.getValueFrom = this.compiledGetValueFromFn() } } var pathCache = {} function getPath (pathString) { if (pathString instanceof Path) return pathString if (pathString == null || pathString.length == 0) pathString = '' if (typeof pathString != 'string') { if (isIndex(pathString.length)) { // Constructed with array-like (pre-parsed) keys return new Path(pathString, constructorIsPrivate) } pathString = String(pathString) } var path = pathCache[pathString] if (path) return path var parts = parsePath(pathString) if (!parts) return invalidPath var path = new Path(parts, constructorIsPrivate) pathCache[pathString] = path return path } Path.get = getPath function formatAccessor (key) { if (isIndex(key)) { return '[' + key + ']' } else { return '["' + key.replace(/"/g, '\\"') + '"]' } } Path.prototype = createObject({ __proto__: [], valid: true, toString: function () { var pathString = '' for (var i = 0; i < this.length; i++) { var key = this[i] if (isIdent(key)) { pathString += i ? '.' + key : key } else { pathString += formatAccessor(key) } } return pathString }, getValueFrom: function (obj, directObserver) { for (var i = 0; i < this.length; i++) { if (obj == null) return obj = obj[this[i]] } return obj }, iterateObjects: function (obj, observe) { for (var i = 0; i < this.length; i++) { if (i) obj = obj[this[i - 1]] if (!isObject(obj)) return observe(obj, this[i]) } }, compiledGetValueFromFn: function () { var str = '' var pathString = 'obj' str += 'if (obj != null' var i = 0 var key for (; i < (this.length - 1); i++) { key = this[i] pathString += isIdent(key) ? '.' + key : formatAccessor(key) str += ' &&\n ' + pathString + ' != null' } str += ')\n' var key = this[i] pathString += isIdent(key) ? '.' + key : formatAccessor(key) str += ' return ' + pathString + ';\nelse\n return undefined;' return new Function('obj', str) }, setValueFrom: function (obj, value) { if (!this.length) return false for (var i = 0; i < this.length - 1; i++) { if (!isObject(obj)) return false obj = obj[this[i]] } if (!isObject(obj)) return false obj[this[i]] = value return true } }) function getPathCharType (char) { if (char === undefined) return 'eof' var code = char.charCodeAt(0) switch (code) { case 0x5B: // [ case 0x5D: // ] case 0x2E: // . case 0x22: // " case 0x27: // ' case 0x30: // 0 return char case 0x5F: // _ case 0x24: // $ return 'ident' case 0x20: // Space case 0x09: // Tab case 0x0A: // Newline case 0x0D: // Return case 0xA0: // No-break space case 0xFEFF: // Byte Order Mark case 0x2028: // Line Separator case 0x2029: // Paragraph Separator return 'ws' } // a-z, A-Z if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A)) return 'ident' // 1-9 if (0x31 <= code && code <= 0x39) return 'number' return 'else' } var pathStateMachine = { 'beforePath': { 'ws': ['beforePath'], 'ident': ['inIdent', 'append'], '[': ['beforeElement'], 'eof': ['afterPath'] }, 'inPath': { 'ws': ['inPath'], '.': ['beforeIdent'], '[': ['beforeElement'], 'eof': ['afterPath'] }, 'beforeIdent': { 'ws': ['beforeIdent'], 'ident': ['inIdent', 'append'] }, 'inIdent': { 'ident': ['inIdent', 'append'], '0': ['inIdent', 'append'], 'number': ['inIdent', 'append'], 'ws': ['inPath', 'push'], '.': ['beforeIdent', 'push'], '[': ['beforeElement', 'push'], 'eof': ['afterPath', 'push'] }, 'beforeElement': { 'ws': ['beforeElement'], '0': ['afterZero', 'append'], 'number': ['inIndex', 'append'], "'": ['inSingleQuote', 'append', ''], '"': ['inDoubleQuote', 'append', ''] }, 'afterZero': { 'ws': ['afterElement', 'push'], ']': ['inPath', 'push'] }, 'inIndex': { '0': ['inIndex', 'append'], 'number': ['inIndex', 'append'], 'ws': ['afterElement'], ']': ['inPath', 'push'] }, 'inSingleQuote': { "'": ['afterElement'], 'eof': ['error'], 'else': ['inSingleQuote', 'append'] }, 'inDoubleQuote': { '"': ['afterElement'], 'eof': ['error'], 'else': ['inDoubleQuote', 'append'] }, 'afterElement': { 'ws': ['afterElement'], ']': ['inPath', 'push'] } } var invalidPath = new Path('', constructorIsPrivate) invalidPath.valid = false invalidPath.getValueFrom = invalidPath.setValueFrom = function () {} module.exports = Path },{}]},{},[1]);