diff options
Diffstat (limited to 'app/assets/javascripts/filtered_search/droplab/drop_lab_deprecated.js')
-rw-r--r-- | app/assets/javascripts/filtered_search/droplab/drop_lab_deprecated.js | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/app/assets/javascripts/filtered_search/droplab/drop_lab_deprecated.js b/app/assets/javascripts/filtered_search/droplab/drop_lab_deprecated.js new file mode 100644 index 00000000000..15c4a4b7c6b --- /dev/null +++ b/app/assets/javascripts/filtered_search/droplab/drop_lab_deprecated.js @@ -0,0 +1,170 @@ +/** + * This library is deprecated and scheduled to be removed once the + * filtered_search component is replaced with GitLab's new Pajamas + * filter vue component. + * + * The documentation has been removed from the gitlab codebase but + * can still be found in the commit history here: + * https://gitlab.com/gitlab-org/gitlab/-/blob/28f20e28/doc/development/fe_guide/droplab/droplab.md + */ + +import { DATA_TRIGGER } from './constants'; +import HookButton from './hook_button'; +import HookInput from './hook_input'; +import Keyboard from './keyboard'; +import utils from './utils'; + +class DropLab { + constructor() { + this.ready = false; + this.hooks = []; + this.queuedData = []; + this.config = {}; + + this.eventWrapper = {}; + } + + loadStatic() { + const dropdownTriggers = [].slice.apply(document.querySelectorAll(`[${DATA_TRIGGER}]`)); + this.addHooks(dropdownTriggers); + } + + addData(...args) { + this.applyArgs(args, 'processAddData'); + } + + setData(...args) { + this.applyArgs(args, 'processSetData'); + } + + destroy() { + this.hooks.forEach((hook) => hook.destroy()); + this.hooks = []; + this.removeEvents(); + } + + applyArgs(args, methodName) { + if (this.ready) return this[methodName](...args); + + this.queuedData = this.queuedData || []; + this.queuedData.push(args); + + return this.ready; + } + + processAddData(trigger, data) { + this.processData(trigger, data, 'addData'); + } + + processSetData(trigger, data) { + this.processData(trigger, data, 'setData'); + } + + processData(trigger, data, methodName) { + this.hooks.forEach((hook) => { + if (Array.isArray(trigger)) hook.list[methodName](trigger); + + if (hook.trigger.id === trigger) hook.list[methodName](data); + }); + } + + addEvents() { + this.eventWrapper.documentClicked = this.documentClicked.bind(this); + document.addEventListener('click', this.eventWrapper.documentClicked); + } + + documentClicked(e) { + if (e.defaultPrevented) return; + + if (utils.isDropDownParts(e.target)) return; + + if (e.target.tagName !== 'UL') { + const closestUl = utils.closest(e.target, 'UL'); + if (utils.isDropDownParts(closestUl)) return; + } + + this.hooks.forEach((hook) => hook.list.hide()); + } + + removeEvents() { + document.removeEventListener('click', this.eventWrapper.documentClicked); + } + + changeHookList(trigger, list, plugins, config) { + const availableTrigger = + typeof trigger === 'string' ? document.getElementById(trigger) : trigger; + + this.hooks.forEach((hook, i) => { + const aHook = hook; + + aHook.list.list.dataset.dropdownActive = false; + + if (aHook.trigger !== availableTrigger) return; + + aHook.destroy(); + this.hooks.splice(i, 1); + this.addHook(availableTrigger, list, plugins, config); + }); + } + + addHook(hook, list, plugins, config) { + const availableHook = typeof hook === 'string' ? document.querySelector(hook) : hook; + let availableList; + + if (typeof list === 'string') { + availableList = document.querySelector(list); + } else if (list instanceof Element) { + availableList = list; + } else { + availableList = document.querySelector(hook.dataset[utils.toCamelCase(DATA_TRIGGER)]); + } + + availableList.dataset.dropdownActive = true; + + const HookObject = availableHook.tagName === 'INPUT' ? HookInput : HookButton; + this.hooks.push(new HookObject(availableHook, availableList, plugins, config)); + + return this; + } + + addHooks(hooks, plugins, config) { + hooks.forEach((hook) => this.addHook(hook, null, plugins, config)); + return this; + } + + setConfig(obj) { + this.config = obj; + } + + fireReady() { + const readyEvent = new CustomEvent('ready.dl', { + detail: { + dropdown: this, + }, + }); + document.dispatchEvent(readyEvent); + + this.ready = true; + } + + init(hook, list, plugins, config) { + if (hook) { + this.addHook(hook, list, plugins, config); + } else { + this.loadStatic(); + } + + this.addEvents(); + + Keyboard(); + + this.fireReady(); + + this.queuedData.forEach((data) => this.addData(data)); + this.queuedData = []; + + return this; + } +} + +export default DropLab; |