X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/76d02cd4725633c87c7885a319411a0671e814ae..refs/pull/2238/head:/resources/js/components/index.js diff --git a/resources/js/components/index.js b/resources/js/components/index.js index da194e438..a0269ea61 100644 --- a/resources/js/components/index.js +++ b/resources/js/components/index.js @@ -36,8 +36,18 @@ function initComponent(name, element) { try { instance = new componentModel(element); instance.$el = element; - instance.$refs = parseRefs(name, element); + const allRefs = parseRefs(name, element); + instance.$refs = allRefs.refs; + instance.$manyRefs = allRefs.manyRefs; instance.$opts = parseOpts(name, element); + instance.$emit = (eventName, data = {}) => { + data.from = instance; + const event = new CustomEvent(`${name}-${eventName}`, { + bubbles: true, + detail: data + }); + instance.$el.dispatchEvent(event); + }; if (typeof instance.setup === 'function') { instance.setup(); } @@ -67,18 +77,30 @@ function initComponent(name, element) { */ function parseRefs(name, element) { const refs = {}; + const manyRefs = {}; + const prefix = `${name}@` - const refElems = element.querySelectorAll(`[refs*="${prefix}"]`); + const selector = `[refs*="${prefix}"]`; + const refElems = [...element.querySelectorAll(selector)]; + if (element.matches(selector)) { + refElems.push(element); + } + for (const el of refElems) { const refNames = el.getAttribute('refs') .split(' ') .filter(str => str.startsWith(prefix)) - .map(str => str.replace(prefix, '')); + .map(str => str.replace(prefix, '')) + .map(kebabToCamel); for (const ref of refNames) { refs[ref] = el; + if (typeof manyRefs[ref] === 'undefined') { + manyRefs[ref] = []; + } + manyRefs[ref].push(el); } } - return refs; + return {refs, manyRefs}; } /** @@ -107,7 +129,7 @@ function parseOpts(name, 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(); + return words[0] + words.slice(1).map(ucFirst).join(''); } /** @@ -134,6 +156,7 @@ function initAll(parentElement) { } window.components.init = initAll; +window.components.first = (name) => (window.components[name] || [null])[0]; export default initAll; @@ -141,5 +164,7 @@ export default initAll; * @typedef Component * @property {HTMLElement} $el * @property {Object} $refs + * @property {Object} $manyRefs * @property {Object} $opts + * @property {function(string, Object)} $emit */ \ No newline at end of file