contextmenu.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // import Vue from "vue";
  2. import { isFunction, isEmpty } from "utils/validate";
  3. import LemonPopover from "../components/popover.vue";
  4. let popover;
  5. const hidePopover = () => {
  6. if (popover) popover.style.display = "none";
  7. };
  8. const showPopover = () => {
  9. if (popover) popover.style.display = "block";
  10. };
  11. document.addEventListener("click", e => {
  12. hidePopover();
  13. });
  14. export default {
  15. hide: hidePopover,
  16. bind(el, binding, vnode) {
  17. el.addEventListener(
  18. binding.modifiers.click ? "click" : "contextmenu",
  19. e => {
  20. if (isEmpty(binding.value) || !Array.isArray(binding.value)) return;
  21. if (binding.modifiers.click) e.stopPropagation();
  22. e.preventDefault();
  23. LemonPopover.methods.closeAll();
  24. let component;
  25. let visibleItems = [];
  26. if (binding.modifiers.message) component = vnode.context;
  27. else if (binding.modifiers.contact) component = vnode.child;
  28. if (!popover) {
  29. popover = document.createElement("div");
  30. popover.className = "lemon-contextmenu";
  31. document.body.appendChild(popover);
  32. }
  33. popover.innerHTML = binding.value
  34. .map(item => {
  35. let visible;
  36. if (isFunction(item.visible)) {
  37. visible = item.visible(component);
  38. } else {
  39. visible = item.visible === undefined ? true : item.visible;
  40. }
  41. if (visible) {
  42. visibleItems.push(item);
  43. const icon = item.icon
  44. ? `<i class="lemon-contextmenu__icon ${item.icon}"></i>`
  45. : "";
  46. return `<div style="color:${item.color}" title="${
  47. item.text
  48. }" class="lemon-contextmenu__item">${icon}<span>${
  49. item.text
  50. }</span></div>`;
  51. }
  52. return "";
  53. })
  54. .join("");
  55. popover.style.top = `${e.pageY}px`;
  56. popover.style.left = `${e.pageX}px`;
  57. popover.childNodes.forEach((node, index) => {
  58. const { click, render } = visibleItems[index];
  59. node.addEventListener("click", e => {
  60. e.stopPropagation();
  61. if (isFunction(click)) click(e, component, hidePopover);
  62. });
  63. // if (isFunction(render)) {
  64. // const ins = Vue.extend({
  65. // render: h => {
  66. // return render(h, component, hidePopover);
  67. // },
  68. // });
  69. // const renderComponent = new ins().$mount();
  70. // node.querySelector("span").innerHTML =
  71. // renderComponent.$el.outerHTML;
  72. // }
  73. });
  74. showPopover();
  75. },
  76. );
  77. },
  78. };