]> BookStack Code Mirror - bookstack/blobdiff - resources/js/components/index.js
Updated callout link formatting
[bookstack] / resources / js / components / index.js
index da194e438a06a71166d1f24475b290e50561cbc8..a0269ea61f771422d97f27e49e173681dd5885e9 100644 (file)
@@ -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<String, HTMLElement>} $refs
+ * @property {Object<String, HTMLElement[]>} $manyRefs
  * @property {Object<String, String>} $opts
+ * @property {function(string, Object)} $emit
  */
\ No newline at end of file