X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/76d02cd4725633c87c7885a319411a0671e814ae..refs/pull/3908/head:/resources/js/components/index.js diff --git a/resources/js/components/index.js b/resources/js/components/index.js index da194e438..27bce48db 100644 --- a/resources/js/components/index.js +++ b/resources/js/components/index.js @@ -1,145 +1,59 @@ -const componentMapping = {}; - -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; - } -} - -window.components = {}; - -/** - * Initialize components of the given name within the given element. - * @param {String} componentName - * @param {HTMLElement|Document} parentElement - */ -function searchForComponentInParent(componentName, parentElement) { - const elems = parentElement.querySelectorAll(`[${componentName}]`); - for (let j = 0, jLen = elems.length; j < jLen; j++) { - initComponent(componentName, elems[j]); - } -} - -/** - * Initialize a component instance on the given dom element. - * @param {String} name - * @param {Element} element - */ -function initComponent(name, element) { - const componentModel = componentMapping[name]; - if (componentModel === undefined) return; - - // Create our component instance - let instance; - try { - instance = new componentModel(element); - instance.$el = element; - instance.$refs = parseRefs(name, element); - instance.$opts = parseOpts(name, element); - if (typeof instance.setup === 'function') { - instance.setup(); - } - } catch (e) { - console.error('Failed to create component', e, name, element); - } - - - // Add to global listing - if (typeof window.components[name] === "undefined") { - window.components[name] = []; - } - window.components[name].push(instance); - - // Add to element listing - if (typeof element.components === 'undefined') { - element.components = {}; - } - element.components[name] = instance; -} - -/** - * Parse out the element references within the given element - * for the given component name. - * @param {String} name - * @param {Element} element - */ -function parseRefs(name, element) { - const refs = {}; - const prefix = `${name}@` - const refElems = element.querySelectorAll(`[refs*="${prefix}"]`); - for (const el of refElems) { - const refNames = el.getAttribute('refs') - .split(' ') - .filter(str => str.startsWith(prefix)) - .map(str => str.replace(prefix, '')); - for (const ref of refNames) { - refs[ref] = el; - } - } - return refs; -} - -/** - * Parse out the element component options. - * @param {String} name - * @param {Element} element - * @return {Object} - */ -function parseOpts(name, element) { - const opts = {}; - const prefix = `option:${name}:`; - for (const {name, value} of element.attributes) { - if (name.startsWith(prefix)) { - const optName = name.replace(prefix, ''); - opts[kebabToCamel(optName)] = value || ''; - } - } - return opts; -} - -/** - * Convert a kebab-case string to camelCase - * @param {String} kebab - * @returns {string} - */ -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(); -} - -/** - * Initialize all components found within the given element. - * @param parentElement - */ -function initAll(parentElement) { - if (typeof parentElement === 'undefined') parentElement = document; - - // Old attribute system - for (const componentName of Object.keys(componentMapping)) { - searchForComponentInParent(componentName, parentElement); - } - - // New component system - const componentElems = parentElement.querySelectorAll(`[component],[components]`); - - for (const el of componentElems) { - const componentNames = `${el.getAttribute('component') || ''} ${(el.getAttribute('components'))}`.toLowerCase().split(' ').filter(Boolean); - for (const name of componentNames) { - initComponent(name, el); - } - } -} - -window.components.init = initAll; - -export default initAll; - -/** - * @typedef Component - * @property {HTMLElement} $el - * @property {Object} $refs - * @property {Object} $opts - */ \ No newline at end of file +export {AddRemoveRows} from "./add-remove-rows.js" +export {AjaxDeleteRow} from "./ajax-delete-row.js" +export {AjaxForm} from "./ajax-form.js" +export {Attachments} from "./attachments.js" +export {AttachmentsList} from "./attachments-list.js" +export {AutoSuggest} from "./auto-suggest.js" +export {AutoSubmit} from "./auto-submit.js" +export {BackToTop} from "./back-to-top.js" +export {BookSort} from "./book-sort.js" +export {ChapterContents} from "./chapter-contents.js" +export {CodeEditor} from "./code-editor.js" +export {CodeHighlighter} from "./code-highlighter.js" +export {CodeTextarea} from "./code-textarea.js" +export {Collapsible} from "./collapsible.js" +export {ConfirmDialog} from "./confirm-dialog" +export {CustomCheckbox} from "./custom-checkbox.js" +export {DetailsHighlighter} from "./details-highlighter.js" +export {Dropdown} from "./dropdown.js" +export {DropdownSearch} from "./dropdown-search.js" +export {Dropzone} from "./dropzone.js" +export {EditorToolbox} from "./editor-toolbox.js" +export {EntityPermissions} from "./entity-permissions" +export {EntitySearch} from "./entity-search.js" +export {EntitySelector} from "./entity-selector.js" +export {EntitySelectorPopup} from "./entity-selector-popup.js" +export {EventEmitSelect} from "./event-emit-select.js" +export {ExpandToggle} from "./expand-toggle.js" +export {GlobalSearch} from "./global-search.js" +export {HeaderMobileToggle} from "./header-mobile-toggle.js" +export {ImageManager} from "./image-manager.js" +export {ImagePicker} from "./image-picker.js" +export {ListSortControl} from "./list-sort-control.js" +export {MarkdownEditor} from "./markdown-editor.js" +export {NewUserPassword} from "./new-user-password.js" +export {Notification} from "./notification.js" +export {OptionalInput} from "./optional-input.js" +export {PageComments} from "./page-comments.js" +export {PageDisplay} from "./page-display.js" +export {PageEditor} from "./page-editor.js" +export {PagePicker} from "./page-picker.js" +export {PermissionsTable} from "./permissions-table.js" +export {Pointer} from "./pointer.js" +export {Popup} from "./popup.js" +export {SettingAppColorPicker} from "./setting-app-color-picker.js" +export {SettingColorPicker} from "./setting-color-picker.js" +export {SettingHomepageControl} from "./setting-homepage-control.js" +export {ShelfSort} from "./shelf-sort.js" +export {Shortcuts} from "./shortcuts" +export {ShortcutInput} from "./shortcut-input" +export {SortableList} from "./sortable-list.js" +export {SubmitOnChange} from "./submit-on-change.js" +export {Tabs} from "./tabs.js" +export {TagManager} from "./tag-manager.js" +export {TemplateManager} from "./template-manager.js" +export {ToggleSwitch} from "./toggle-switch.js" +export {TriLayout} from "./tri-layout.js" +export {UserSelect} from "./user-select.js" +export {WebhookEvents} from "./webhook-events" +export {WysiwygEditor} from "./wysiwyg-editor.js"