X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/891543ff0a3a1cb1190d58dc9698435f58b3e5cc..refs/pull/4467/head:/resources/js/services/components.js diff --git a/resources/js/services/components.js b/resources/js/services/components.js index 7434f6430..beb0ce92f 100644 --- a/resources/js/services/components.js +++ b/resources/js/services/components.js @@ -1,3 +1,5 @@ +import {kebabToCamel, camelToKebab} from './text'; + /** * A mapping of active components keyed by name, with values being arrays of component * instances since there can be multiple components of the same type. @@ -17,44 +19,6 @@ const componentModelMap = {}; */ const elementComponentMap = new WeakMap(); -/** - * Initialize a component instance on the given dom element. - * @param {String} name - * @param {Element} element - */ -function initComponent(name, element) { - /** @type {Function|undefined} **/ - const componentModel = componentModelMap[name]; - if (componentModel === undefined) return; - - // Create our component instance - /** @type {Component} **/ - let instance; - try { - instance = new componentModel(); - instance.$name = name; - instance.$el = element; - const allRefs = parseRefs(name, element); - instance.$refs = allRefs.refs; - instance.$manyRefs = allRefs.manyRefs; - instance.$opts = parseOpts(name, element); - instance.setup(); - } catch (e) { - console.error('Failed to create component', e, name, element); - } - - // Add to global listing - if (typeof components[name] === "undefined") { - components[name] = []; - } - components[name].push(instance); - - // Add to element mapping - const elComponents = elementComponentMap.get(element) || {}; - elComponents[name] = instance; - elementComponentMap.set(element, elComponents); -} - /** * Parse out the element references within the given element * for the given component name. @@ -65,7 +29,7 @@ function parseRefs(name, element) { const refs = {}; const manyRefs = {}; - const prefix = `${name}@` + const prefix = `${name}@`; const selector = `[refs*="${prefix}"]`; const refElems = [...element.querySelectorAll(selector)]; if (element.matches(selector)) { @@ -91,13 +55,13 @@ function parseRefs(name, element) { /** * Parse out the element component options. - * @param {String} name + * @param {String} componentName * @param {Element} element * @return {Object} */ -function parseOpts(name, element) { +function parseOpts(componentName, element) { const opts = {}; - const prefix = `option:${name}:`; + const prefix = `option:${componentName}:`; for (const {name, value} of element.attributes) { if (name.startsWith(prefix)) { const optName = name.replace(prefix, ''); @@ -108,14 +72,41 @@ function parseOpts(name, element) { } /** - * Convert a kebab-case string to camelCase - * @param {String} kebab - * @returns {string} + * Initialize a component instance on the given dom element. + * @param {String} name + * @param {Element} element */ -function kebabToCamel(kebab) { - const ucFirst = (word) => word.slice(0,1).toUpperCase() + word.slice(1); - const words = kebab.split('-'); - return words[0] + words.slice(1).map(ucFirst).join(''); +function initComponent(name, element) { + /** @type {Function|undefined} * */ + const ComponentModel = componentModelMap[name]; + if (ComponentModel === undefined) return; + + // Create our component instance + /** @type {Component} * */ + let instance; + try { + instance = new ComponentModel(); + instance.$name = name; + instance.$el = element; + const allRefs = parseRefs(name, element); + instance.$refs = allRefs.refs; + instance.$manyRefs = allRefs.manyRefs; + instance.$opts = parseOpts(name, element); + instance.setup(); + } catch (e) { + console.error('Failed to create component', e, name, element); + } + + // Add to global listing + if (typeof components[name] === 'undefined') { + components[name] = []; + } + components[name].push(instance); + + // Add to element mapping + const elComponents = elementComponentMap.get(element) || {}; + elComponents[name] = instance; + elementComponentMap.set(element, elComponents); } /** @@ -123,7 +114,7 @@ function kebabToCamel(kebab) { * @param {Element|Document} parentElement */ export function init(parentElement = document) { - const componentElems = parentElement.querySelectorAll(`[component],[components]`); + const componentElems = parentElement.querySelectorAll('[component],[components]'); for (const el of componentElems) { const componentNames = `${el.getAttribute('component') || ''} ${(el.getAttribute('components'))}`.toLowerCase().split(' ').filter(Boolean); @@ -172,7 +163,3 @@ export function firstOnElement(element, name) { const elComponents = elementComponentMap.get(element) || {}; return elComponents[name] || null; } - -function camelToKebab(camelStr) { - return camelStr.replace(/[A-Z]/g, (str, offset) => (offset > 0 ? '-' : '') + str.toLowerCase()); -} \ No newline at end of file