{"version":3,"sources":["../../../../src/static/js/binder/controller.js"],"sourcesContent":["import { kebabToCamel, parseBoolean, parseDuration } from \"./util.js\";\n\n/**\n * @class\n * @name Controller\n * @namespace Controller\n */\nclass Controller extends HTMLElement {\n /**\n * @static\n * @name observedAttributes\n * @type String[]\n * @memberof! Controller\n * @description These are the attributes to watch for and react to changes\n * This is handled by `attributeChangedCallback()`\n * The default implementation will call `set{AttributeName}(oldValue, newValue)`\n */\n static observedAttributes = [];\n static tag = undefined;\n\n static withTag(tag) {\n return class extends this {\n static tag = tag;\n };\n }\n\n /**\n * Create a new custom controller element\n * @param {*} args\n */\n constructor(args) {\n super();\n this.debug({ msg: \"Constructing binder element\" });\n\n // Store for internal data\n this._internal = {};\n\n this.root = this;\n this.args = args || {};\n this.data = {};\n\n // Keep track of all attached events\n this._events = [];\n\n // Add the data-controller attribute to the element\n this.setAttribute(\"data-controller\", this.localName);\n this.emit(\"binder:created\", {});\n }\n\n /**\n * Work in progress\n * If the element has a `` with a `:use-shadow` attribute, it will be used to create a shadow root\n * When using the shadow DOM the `bind()` call fails\n */\n handleShadow() {\n // If the component has a template then we will clone it and render that to the DOM\n // If the template has the :use-shadow attribute then we will clone it onto the shadow DOM\n // This allows isolating the component from the regular DOM (including styles)\n this.template = this.querySelector(\"template\");\n\n // The template is optional, if not specified then we will do everything directly on the DOM within the component\n if (this.template) {\n this.content = this.template.content.cloneNode(true);\n\n // Only use the shadowDOM when specified\n if (this.template.hasAttribute(\":use-shadow\")) {\n this.debug({ msg: \"Initialising shadow DOM\" });\n this.attachShadow({ mode: \"open\" }).appendChild(this.content.cloneNode(true));\n\n this.root = this.shadowRoot;\n this.hasShadow = true;\n } else {\n this.appendChild(this.content.cloneNode(true));\n this.hasShadow = false;\n }\n }\n }\n\n /**\n * @method\n * @name connectCallback\n * @memberof! Controller\n * @description Called when element is rendered in the DOM\n * See: {@link https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks}\n */\n async connectedCallback() {\n if (!this.isConnected) return;\n\n this.handleShadow();\n\n // Bind the element to this instance\n this.bind();\n\n // Init the element\n if (\"renderOnInit\" in this.args) {\n this.renderOnInit = parseBoolean(this.args.renderOnInit);\n } else {\n this.renderOnInit = true;\n }\n await this.init(this.args);\n\n // Render\n if (this.args.autoRender) {\n const interval = parseDuration(this.args.autoRender);\n this.setAutoRender(interval);\n }\n\n if (this.renderOnInit) this.render();\n\n this.emit(\"binder:connected\", {});\n }\n\n /**\n * Runs when the element in removed from the DOM\n */\n disconnectedCallback() {\n this._events.forEach(e => e.el.removeEventListener(e.eventType, e.event));\n this._events = [];\n\n this.emit(\"binder:disconnected\", { detail: { from: this } });\n }\n\n /**\n * @method\n * @name attributeChangedCallback\n * @memberof! Controller\n * @description The default implementation of attributeChangedCallback\n * See: {@link https://developers.google.com/web/fundamentals/web-components/customelements#attrchanges}\n * We will convert the attribute name to camel case, strip out the leading `data-` or `aria-` parts and call `set{AttributeName}(oldValue, newValue)` (if it exists)\n * Eg. A change to `data-disabled` will call `setDisabled(oldValue, newValue)`\n * @param {string} name The name of the attribute that changed\n * @param {string} oldValue The old value of the attribute\n * @param {string} newValue The new value of the attribute\n */\n attributeChangedCallback(name, oldValue, newValue) {\n let handler = name.replace(/^data-/, \"\");\n handler = handler.replace(/^aria-/, \"\");\n handler = kebabToCamel(handler);\n handler = `set${handler.charAt(0).toUpperCase()}${handler.slice(1)}`;\n\n if (handler in this && typeof this[handler] === \"function\") {\n this[handler](oldValue, newValue);\n }\n }\n\n /**\n * @method\n * @name Controller#emit\n * @memberof! Controller\n * @description Emit a new event from this controller\n * @param {string} eventName The name of the event, automatically prefixed with `${this.localName}:`\n * @param {object} detail Optional object that is passed in the event under the key `detail`\n * @param {object} config Optional configuration object that can be passed to `new CustomEvent()`\n */\n emit(eventName, detail = {}, config = {}) {\n this.dispatchEvent(\n new CustomEvent(eventName, {\n bubbles: true,\n cancelable: true,\n composed: true,\n detail: detail,\n ...config,\n })\n );\n }\n\n /**\n * @method\n * @name listenFor\n * @memberof! Controller\n * @description Listens for an event to be fired from a child element\n * @param {Element} target The element to listen for events from, use `window` to listen for global events\n * @param {string} eventName The name of the event to listen for\n * @param {function} callback The callback to call when the event is fired\n */\n listenFor(target, eventName, callback) {\n target.addEventListener(eventName, e => callback(e));\n }\n\n /**\n * @method\n * @name bind\n * @memberof! Controller\n * @description Initializes the controller instance\n * Can be called manaually when the child elements change to force refreshing the controller state\n * eg. re-attach events etc...\n */\n bind() {\n // We only want to configure the arguments on the first bind()\n if (!this._internal.bound) this.#bindArgs();\n\n this.#bindElements();\n this.#bindEvents();\n\n this._internal.bound = true;\n }\n\n /**\n * @method\n * @name setAutoRender\n * @memberof! Controller\n * @description Sets an interval to auto call `this.render()`\n * Overwrites previously set render intervals\n * @param {*} interval Duration in milliseconds\n */\n setAutoRender(interval) {\n if (interval === undefined) {\n console.error(`[${this.localName}] Undefined interval passed to setAutoRender`);\n return;\n }\n\n if (this._internal.autoRenderInterval) {\n window.clearInterval(this._internal.autoRenderInterval);\n }\n\n this._internal.autoRenderInterval = window.setInterval(() => this.render(), interval);\n }\n\n /**\n * @method\n * @name init\n * @memberof! Controller\n * @description Called during the `connectedCallback()` (when an element is created in the DOM)\n * Expected to be overridden\n * @param {*} args\n */\n async init(_args) {}\n\n /**\n * @method\n * @name render\n * @memberof! Controller\n * @param {Element} rootNode The root node to search from\n * @description Re-renders everything with the :render attribute\n */\n async render(rootNode = null) {\n if (!rootNode) rootNode = this;\n\n this.#findRenderableElements(rootNode).forEach(el => {\n // Store the original template as an attribute on the element on first render\n let template = el.getAttribute(\"_template\");\n if (!template) {\n template = el.innerText;\n el.setAttribute(\"_template\", template);\n }\n\n // If the element has the attribute with .eval then eval the template\n // This should be used sparingly and only when the content is trusted\n const evalMode = el.hasAttribute(\":render.eval\");\n\n // TODO: Make the replacer syntax configurable\n let replacerRegex = /\\{(.*?)\\}/g; // Find template vars, eg {var}\n\n template.replace(replacerRegex, (replacer, key) => {\n if (evalMode) {\n const fn = new Function(`return ${key}`);\n template = template.replace(replacer, fn.call(this));\n } else {\n // If not in `evalMode` then we do an eval-like replacement\n // We will dig into the controller instance and replace in the variables\n // This handles dot notation and array notation\n let pos = null;\n\n // Split on dots and brackets and strip out any quotes\n key.split(/[.[\\]]/)\n .filter(item => !!item)\n .forEach(part => {\n part = part.replace(/[\"']/g, \"\"); // Strip out square brackets\n part = part.replace(/\\(\\)/g, \"\"); // Strip out function parens\n\n if (pos == null && part === \"this\") {\n pos = this;\n return;\n }\n\n if (pos && part in pos) {\n pos = pos[part];\n } else {\n pos = null;\n return;\n }\n });\n\n if (pos == null) pos = \"\";\n if (typeof pos === \"function\") pos = pos.call(this);\n template = template.replace(replacer, pos.toString() || \"\");\n }\n });\n\n // TODO: This may be innefecient\n el.innerHTML = template;\n });\n\n this.emit(\"binder:render\", {});\n }\n\n /**\n * @method\n * @private\n * @name findRenderableElements\n * @memberof! Controller\n * @param {Element} rootNode The root node to search from\n * @description Find all elements on the controller which have :render attributes\n * :render is a special action that let's the controller know to render this elements content when the render() method is called\n */\n #findRenderableElements(rootNode = null) {\n if (!rootNode) rootNode = this;\n return [...rootNode.querySelectorAll(\"[\\\\:render]\"), ...rootNode.querySelectorAll(\"[\\\\:render\\\\.eval]\")].filter(el => this.belongsToController(el));\n }\n\n /**\n * @method\n * @private\n * @name bindArgs\n * @memberof! Controller\n * @description Bind all attributes on the controller tag into the instance under `this`\n * Converts kebab-case to camelCase\n * EG. will set `this.args.someArg = 150`\n */\n #bindArgs() {\n this.args = {};\n\n this.getAttributeNames().forEach(attr => {\n const value = this.getAttribute(attr);\n const key = kebabToCamel(attr).replace(\":\", \"\");\n this.args[key] = value;\n });\n }\n\n /**\n * @method\n * @private\n * @name bindElements\n * @memberof! Controller\n * @description Bind any elements with a `:bind` attribute to the controller under `this.binds`\n */\n #bindElements() {\n this.binds = {};\n\n const boundElements = this.querySelectorAll(\"[\\\\:bind]\");\n boundElements.forEach(el => {\n if (this.belongsToController(el)) {\n const key = el.getAttribute(\":bind\");\n\n if (Object.hasOwn(this.binds, key)) {\n if (Array.isArray(this.binds[key])) {\n this.binds[key].push(el);\n } else {\n this.binds[key] = [this.binds[key], el];\n }\n } else {\n this.binds[key] = el;\n }\n }\n });\n }\n\n /**\n * @method\n * @private\n * @name bindEvents\n * @memberof! Controller\n * @description Finds all events within a controller element\n * Events are in the format `@{eventType}={method}\"`\n * EG. @click=\"handleClick\"\n *\n * The attribute key can also end with a combination of modifiers:\n * - `.prevent`: Automatically calls `event.preventDefault()`\n * - `.stop`: Automatically calls `event.stopPropagation()`\n * - `.eval`: Will evaluate the attribute value\n */\n #bindEvents() {\n // We need to delete all events and before binding\n // Otherwise we would end up with duplicate events upon muliple bind() calls\n this._events.forEach(e => e.el.removeEventListener(e.eventType, e.event));\n this._events = [];\n\n const bindEvent = async (el, eventType, modifiers) => {\n let attributeName = `@${eventType}`;\n if (modifiers.length) attributeName += `.${modifiers.join(\".\")}`;\n\n const value = el.getAttribute(attributeName);\n const action = value.replace(\"this.\", \"\").replace(\"()\", \"\");\n\n const callable = async event => {\n if (modifiers.includes(\"prevent\")) event.preventDefault();\n if (modifiers.includes(\"stop\")) event.stopPropagation();\n\n if (modifiers.includes(\"eval\")) {\n const fn = new Function(\"e\", `${value}`);\n fn.call(this, event);\n } else {\n try {\n if (action === \"render\") {\n // Render doesn't take an event\n await this[action].call(this);\n } else {\n await this[action].call(this, event);\n }\n } catch (e) {\n console.error(`Failed to call '${action}' to handle '${event.type}' event on tag '${this.localName}'`, e);\n }\n }\n\n if (modifiers.includes(\"render\")) this.render();\n };\n\n el.addEventListener(eventType, callable);\n\n this._events.push({\n el: el,\n event: callable,\n eventType: eventType,\n });\n };\n\n // Go through all nodes which have events on them\n // eg. nodes which have any attribute starting with `@`\n for (let node of this.#findEventNodes()) {\n if (!this.belongsToController(node)) continue;\n this.debug({ msg: \"Attaching event listeners\", source: node });\n\n for (let attr of node.getAttributeNames()) {\n if (!attr.startsWith(\"@\")) continue;\n\n let [event, ...modifiers] = attr.replace(\"@\", \"\").split(\".\");\n\n bindEvent(node, event, modifiers);\n }\n }\n }\n\n /**\n * @method\n * @private\n * @name findEventNodes\n * @memberof! Controller\n * @description Generator returning nodes which have events on them\n * We do things a little differently depending on whether we are using the shadow DOM or not\n * If using the light DOM we use `document.evaluate` with an xpath expression\n * If using the shadow DOM we need to manually iterate through all nodes, which is slower\n */\n *#findEventNodes() {\n // TODO: Actually benchmark this to confirm if it's slower\n if (this.hasShadow) {\n const allNodes = this.root.querySelectorAll(\"*\");\n for (let node of allNodes) {\n if (node.getAttributeNames().filter(attr => attr.startsWith(\"@\")).length > 0) {\n yield node;\n }\n }\n } else {\n const nodesWithEvents = document.evaluate('.//*[@*[starts-with(name(), \"@\")]]', this.root);\n let eventNode = nodesWithEvents.iterateNext();\n while (eventNode) {\n yield eventNode;\n eventNode = nodesWithEvents.iterateNext();\n }\n }\n }\n\n /**\n * @method\n * @private\n * @name getElementType\n * @memberof! Controller\n * @description Return the type of an element\n * @param {Element} el The DOM element to check\n * @returns {String} The element type, e.g. 'input|text'\n */\n #getElementType(el) {\n if (el.tagName.toLowerCase() === \"input\") {\n return [el.tagName, el.type].map(item => item.toLowerCase()).join(\"|\");\n }\n return el.tagName.toLowerCase();\n }\n\n /**\n * @method\n * @private\n * @name belongsToController\n * @memberof! Controller\n * @description Return true if the given element belongs to this controller\n * @param {Element} el The controller root DOM element\n * @returns {Boolean} True if the element belongs to the controller\n */\n belongsToController(el) {\n // Controllers don't belong to themselves, go up a level to find their parent\n if (el.hasAttribute(\"data-controller\")) el = el.parentElement;\n\n const closestController = el.closest(\"[data-controller]\");\n return closestController === this;\n }\n\n /**\n * Helper debug function\n * Only enabled when\n * - `window.__BINDER_DEBUG__` is set to `true`\n * - `window.__BINDER_DEBUG__` is an array on this controllers `localName` is present\n * @param {Object} obj The data to log\n */\n debug(obj) {\n let shouldLog = false;\n\n if (window.__BINDER_DEBUG__ === true) shouldLog = true;\n if (Array.isArray(window.__BINDER_DEBUG__) && window.__BINDER_DEBUG__.includes(this.localName)) shouldLog = true;\n\n if (shouldLog) {\n obj.controller = this;\n console.debug(obj);\n }\n }\n}\n\nexport { Controller };\n"],"names":["kebabToCamel","parseBoolean","parseDuration","Controller","HTMLElement","withTag","tag","handleShadow","template","querySelector","content","cloneNode","hasAttribute","debug","msg","attachShadow","mode","appendChild","root","shadowRoot","hasShadow","connectedCallback","isConnected","bind","args","renderOnInit","init","autoRender","interval","setAutoRender","render","emit","disconnectedCallback","_events","forEach","e","el","removeEventListener","eventType","event","detail","from","attributeChangedCallback","name","oldValue","newValue","handler","replace","charAt","toUpperCase","slice","eventName","config","dispatchEvent","CustomEvent","bubbles","cancelable","composed","listenFor","target","callback","addEventListener","_internal","bound","bindArgs","bindElements","bindEvents","undefined","console","error","localName","autoRenderInterval","window","clearInterval","setInterval","_args","rootNode","findRenderableElements","getAttribute","innerText","setAttribute","evalMode","replacerRegex","replacer","key","fn","Function","call","pos","split","filter","item","part","toString","innerHTML","belongsToController","parentElement","closestController","closest","obj","shouldLog","__BINDER_DEBUG__","Array","isArray","includes","controller","constructor","data","observedAttributes","querySelectorAll","getAttributeNames","attr","value","binds","boundElements","Object","hasOwn","push","bindEvent","modifiers","attributeName","length","join","action","callable","preventDefault","stopPropagation","type","node","findEventNodes","source","startsWith","allNodes","nodesWithEvents","document","evaluate","eventNode","iterateNext","tagName","toLowerCase","map"],"mappings":"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"}