diff options
Diffstat (limited to 'app/assets/javascripts/popovers/index.js')
-rw-r--r-- | app/assets/javascripts/popovers/index.js | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/app/assets/javascripts/popovers/index.js b/app/assets/javascripts/popovers/index.js new file mode 100644 index 00000000000..bfb61f02a3a --- /dev/null +++ b/app/assets/javascripts/popovers/index.js @@ -0,0 +1,51 @@ +import Vue from 'vue'; +import { toArray } from 'lodash'; +import PopoversComponent from './components/popovers.vue'; + +let app; + +const APP_ELEMENT_ID = 'gl-popovers-app'; + +const getPopoversApp = () => { + if (!app) { + const container = document.createElement('div'); + container.setAttribute('id', APP_ELEMENT_ID); + document.body.appendChild(container); + + const Popovers = Vue.extend(PopoversComponent); + app = new Popovers(); + app.$mount(`#${APP_ELEMENT_ID}`); + } + + return app; +}; + +const isPopover = (node, selector) => node.matches && node.matches(selector); + +const handlePopoverEvent = (rootTarget, e, selector) => { + for (let { target } = e; target && target !== rootTarget; target = target.parentNode) { + if (isPopover(target, selector)) { + getPopoversApp().addPopovers([target]); + break; + } + } +}; + +export const initPopovers = () => { + ['mouseenter', 'focus', 'click'].forEach(event => { + document.addEventListener( + event, + e => handlePopoverEvent(document, e, '[data-toggle="popover"]'), + true, + ); + }); + + return getPopoversApp(); +}; + +export const dispose = elements => toArray(elements).forEach(getPopoversApp().dispose); + +export const destroy = () => { + getPopoversApp().$destroy(); + app = null; +}; |