debian-mirror-gitlab/app/assets/javascripts/droplab/drop_lab.js

158 lines
3.7 KiB
JavaScript
Raw Normal View History

2017-08-17 22:00:37 +05:30
import HookButton from './hook_button';
import HookInput from './hook_input';
import utils from './utils';
import Keyboard from './keyboard';
import { DATA_TRIGGER } from './constants';
2017-09-10 17:25:29 +05:30
class DropLab {
constructor() {
this.ready = false;
this.hooks = [];
this.queuedData = [];
this.config = {};
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
this.eventWrapper = {};
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
loadStatic() {
const dropdownTriggers = [].slice.apply(document.querySelectorAll(`[${DATA_TRIGGER}]`));
2017-08-17 22:00:37 +05:30
this.addHooks(dropdownTriggers);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
addData(...args) {
this.applyArgs(args, 'processAddData');
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
setData(...args) {
this.applyArgs(args, 'processSetData');
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
destroy() {
2017-08-17 22:00:37 +05:30
this.hooks.forEach(hook => hook.destroy());
this.hooks = [];
this.removeEvents();
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
applyArgs(args, methodName) {
if (this.ready) return this[methodName](...args);
2017-08-17 22:00:37 +05:30
this.queuedData = this.queuedData || [];
this.queuedData.push(args);
2017-09-10 17:25:29 +05:30
return this.ready;
}
processAddData(trigger, data) {
this.processData(trigger, data, 'addData');
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
processSetData(trigger, data) {
this.processData(trigger, data, 'setData');
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
processData(trigger, data, methodName) {
2018-12-13 13:39:08 +05:30
this.hooks.forEach(hook => {
2017-08-17 22:00:37 +05:30
if (Array.isArray(trigger)) hook.list[methodName](trigger);
if (hook.trigger.id === trigger) hook.list[methodName](data);
});
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
addEvents() {
this.eventWrapper.documentClicked = this.documentClicked.bind(this);
2019-12-04 20:38:33 +05:30
document.addEventListener('mousedown', this.eventWrapper.documentClicked);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
documentClicked(e) {
2017-08-17 22:00:37 +05:30
let thisTag = e.target;
if (thisTag.tagName !== 'UL') thisTag = utils.closest(thisTag, 'UL');
2017-09-10 17:25:29 +05:30
if (utils.isDropDownParts(thisTag, this.hooks)) return;
if (utils.isDropDownParts(e.target, this.hooks)) return;
2017-08-17 22:00:37 +05:30
this.hooks.forEach(hook => hook.list.hide());
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
removeEvents() {
2019-12-04 20:38:33 +05:30
document.removeEventListener('mousedown', this.eventWrapper.documentClicked);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
changeHookList(trigger, list, plugins, config) {
2018-12-13 13:39:08 +05:30
const availableTrigger =
typeof trigger === 'string' ? document.getElementById(trigger) : trigger;
2017-08-17 22:00:37 +05:30
this.hooks.forEach((hook, i) => {
2017-09-10 17:25:29 +05:30
const aHook = hook;
aHook.list.list.dataset.dropdownActive = false;
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
if (aHook.trigger !== availableTrigger) return;
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
aHook.destroy();
2017-08-17 22:00:37 +05:30
this.hooks.splice(i, 1);
this.addHook(availableTrigger, list, plugins, config);
});
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
addHook(hook, list, plugins, config) {
2017-08-17 22:00:37 +05:30
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;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
addHooks(hooks, plugins, config) {
2017-08-17 22:00:37 +05:30
hooks.forEach(hook => this.addHook(hook, null, plugins, config));
return this;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
setConfig(obj) {
2017-08-17 22:00:37 +05:30
this.config = obj;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
fireReady() {
2017-08-17 22:00:37 +05:30
const readyEvent = new CustomEvent('ready.dl', {
detail: {
dropdown: this,
},
});
document.dispatchEvent(readyEvent);
this.ready = true;
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
init(hook, list, plugins, config) {
if (hook) {
this.addHook(hook, list, plugins, config);
} else {
this.loadStatic();
}
2017-08-17 22:00:37 +05:30
this.addEvents();
Keyboard();
this.fireReady();
this.queuedData.forEach(data => this.addData(data));
this.queuedData = [];
return this;
2017-09-10 17:25:29 +05:30
}
}
2017-08-17 22:00:37 +05:30
export default DropLab;