summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/popovers/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/popovers/index.js')
-rw-r--r--app/assets/javascripts/popovers/index.js51
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;
+};