X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/76d02cd4725633c87c7885a319411a0671e814ae..refs/pull/2298/head:/resources/js/components/index.js diff --git a/resources/js/components/index.js b/resources/js/components/index.js index da194e438..87c496c91 100644 --- a/resources/js/components/index.js +++ b/resources/js/components/index.js @@ -1,12 +1,108 @@ -const componentMapping = {}; +import addRemoveRows from "./add-remove-rows.js" +import ajaxDeleteRow from "./ajax-delete-row.js" +import ajaxForm from "./ajax-form.js" +import attachments from "./attachments.js" +import autoSuggest from "./auto-suggest.js" +import backToTop from "./back-to-top.js" +import bookSort from "./book-sort.js" +import breadcrumbListing from "./breadcrumb-listing.js" +import chapterToggle from "./chapter-toggle.js" +import codeEditor from "./code-editor.js" +import codeHighlighter from "./code-highlighter.js" +import collapsible from "./collapsible.js" +import customCheckbox from "./custom-checkbox.js" +import detailsHighlighter from "./details-highlighter.js" +import dropdown from "./dropdown.js" +import dropzone from "./dropzone.js" +import editorToolbox from "./editor-toolbox.js" +import entityPermissionsEditor from "./entity-permissions-editor.js" +import entitySearch from "./entity-search.js" +import entitySelector from "./entity-selector.js" +import entitySelectorPopup from "./entity-selector-popup.js" +import eventEmitSelect from "./event-emit-select.js" +import expandToggle from "./expand-toggle.js" +import headerMobileToggle from "./header-mobile-toggle.js" +import homepageControl from "./homepage-control.js" +import imageManager from "./image-manager.js" +import imagePicker from "./image-picker.js" +import index from "./index.js" +import listSortControl from "./list-sort-control.js" +import markdownEditor from "./markdown-editor.js" +import newUserPassword from "./new-user-password.js" +import notification from "./notification.js" +import optionalInput from "./optional-input.js" +import pageComments from "./page-comments.js" +import pageDisplay from "./page-display.js" +import pageEditor from "./page-editor.js" +import pagePicker from "./page-picker.js" +import permissionsTable from "./permissions-table.js" +import popup from "./popup.js" +import settingAppColorPicker from "./setting-app-color-picker.js" +import settingColorPicker from "./setting-color-picker.js" +import shelfSort from "./shelf-sort.js" +import sidebar from "./sidebar.js" +import sortableList from "./sortable-list.js" +import submitOnChange from "./submit-on-change.js" +import tabs from "./tabs.js" +import tagManager from "./tag-manager.js" +import templateManager from "./template-manager.js" +import toggleSwitch from "./toggle-switch.js" +import triLayout from "./tri-layout.js" +import wysiwygEditor from "./wysiwyg-editor.js" -const definitionFiles = require.context('./', false, /\.js$/); -for (const fileName of definitionFiles.keys()) { - const name = fileName.replace('./', '').split('.')[0]; - if (name !== 'index') { - componentMapping[name] = definitionFiles(fileName).default; - } -} +const componentMapping = { + "add-remove-rows": addRemoveRows, + "ajax-delete-row": ajaxDeleteRow, + "ajax-form": ajaxForm, + "attachments": attachments, + "auto-suggest": autoSuggest, + "back-to-top": backToTop, + "book-sort": bookSort, + "breadcrumb-listing": breadcrumbListing, + "chapter-toggle": chapterToggle, + "code-editor": codeEditor, + "code-highlighter": codeHighlighter, + "collapsible": collapsible, + "custom-checkbox": customCheckbox, + "details-highlighter": detailsHighlighter, + "dropdown": dropdown, + "dropzone": dropzone, + "editor-toolbox": editorToolbox, + "entity-permissions-editor": entityPermissionsEditor, + "entity-search": entitySearch, + "entity-selector": entitySelector, + "entity-selector-popup": entitySelectorPopup, + "event-emit-select": eventEmitSelect, + "expand-toggle": expandToggle, + "header-mobile-toggle": headerMobileToggle, + "homepage-control": homepageControl, + "image-manager": imageManager, + "image-picker": imagePicker, + "index": index, + "list-sort-control": listSortControl, + "markdown-editor": markdownEditor, + "new-user-password": newUserPassword, + "notification": notification, + "optional-input": optionalInput, + "page-comments": pageComments, + "page-display": pageDisplay, + "page-editor": pageEditor, + "page-picker": pagePicker, + "permissions-table": permissionsTable, + "popup": popup, + "setting-app-color-picker": settingAppColorPicker, + "setting-color-picker": settingColorPicker, + "shelf-sort": shelfSort, + "sidebar": sidebar, + "sortable-list": sortableList, + "submit-on-change": submitOnChange, + "tabs": tabs, + "tag-manager": tagManager, + "template-manager": templateManager, + "toggle-switch": toggleSwitch, + "tri-layout": triLayout, + "wysiwyg-editor": wysiwygEditor, +}; window.components = {}; @@ -36,8 +132,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 +173,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 +225,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 +252,7 @@ function initAll(parentElement) { } window.components.init = initAll; +window.components.first = (name) => (window.components[name] || [null])[0]; export default initAll; @@ -141,5 +260,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