Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

overlayable.js 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Styles
  2. import '../../src/stylus/components/_overlay.styl';
  3. // Utilities
  4. import { keyCodes, addPassiveEventListener } from '../util/helpers';
  5. // Types
  6. import Vue from 'vue';
  7. /* @vue/component */
  8. export default Vue.extend().extend({
  9. name: 'overlayable',
  10. props: {
  11. hideOverlay: Boolean
  12. },
  13. data: function data() {
  14. return {
  15. overlay: null,
  16. overlayOffset: 0,
  17. overlayTimeout: undefined,
  18. overlayTransitionDuration: 500 + 150 // transition + delay
  19. };
  20. },
  21. watch: {
  22. hideOverlay: function hideOverlay(value) {
  23. if (value) this.removeOverlay();else this.genOverlay();
  24. }
  25. },
  26. beforeDestroy: function beforeDestroy() {
  27. this.removeOverlay();
  28. },
  29. methods: {
  30. genOverlay: function genOverlay() {
  31. var _this = this;
  32. // If fn is called and timeout is active
  33. // or overlay already exists
  34. // cancel removal of overlay and re-add active
  35. if (!this.isActive || this.hideOverlay || this.isActive && this.overlayTimeout || this.overlay) {
  36. clearTimeout(this.overlayTimeout);
  37. return this.overlay && this.overlay.classList.add('v-overlay--active');
  38. }
  39. this.overlay = document.createElement('div');
  40. this.overlay.className = 'v-overlay';
  41. if (this.absolute) this.overlay.className += ' v-overlay--absolute';
  42. this.hideScroll();
  43. var parent = this.absolute ? this.$el.parentNode : document.querySelector('[data-app]');
  44. parent && parent.insertBefore(this.overlay, parent.firstChild);
  45. // eslint-disable-next-line no-unused-expressions
  46. this.overlay.clientHeight; // Force repaint
  47. requestAnimationFrame(function () {
  48. // https://github.com/vuetifyjs/vuetify/issues/4678
  49. if (!_this.overlay) return;
  50. _this.overlay.className += ' v-overlay--active';
  51. if (_this.activeZIndex !== undefined) {
  52. _this.overlay.style.zIndex = String(_this.activeZIndex - 1);
  53. }
  54. });
  55. return true;
  56. },
  57. /** removeOverlay(false) will not restore the scollbar afterwards */
  58. removeOverlay: function removeOverlay() {
  59. var _this2 = this;
  60. var showScroll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  61. if (!this.overlay) {
  62. return showScroll && this.showScroll();
  63. }
  64. this.overlay.classList.remove('v-overlay--active');
  65. this.overlayTimeout = window.setTimeout(function () {
  66. // IE11 Fix
  67. try {
  68. if (_this2.overlay && _this2.overlay.parentNode) {
  69. _this2.overlay.parentNode.removeChild(_this2.overlay);
  70. }
  71. _this2.overlay = null;
  72. showScroll && _this2.showScroll();
  73. } catch (e) {
  74. console.log(e);
  75. }
  76. clearTimeout(_this2.overlayTimeout);
  77. _this2.overlayTimeout = undefined;
  78. }, this.overlayTransitionDuration);
  79. },
  80. scrollListener: function scrollListener(e) {
  81. if (e.type === 'keydown') {
  82. if (['INPUT', 'TEXTAREA', 'SELECT'].includes(e.target.tagName) ||
  83. // https://github.com/vuetifyjs/vuetify/issues/4715
  84. e.target.isContentEditable) return;
  85. var up = [keyCodes.up, keyCodes.pageup];
  86. var down = [keyCodes.down, keyCodes.pagedown];
  87. if (up.includes(e.keyCode)) {
  88. e.deltaY = -1;
  89. } else if (down.includes(e.keyCode)) {
  90. e.deltaY = 1;
  91. } else {
  92. return;
  93. }
  94. }
  95. if (e.target === this.overlay || e.type !== 'keydown' && e.target === document.body || this.checkPath(e)) e.preventDefault();
  96. },
  97. hasScrollbar: function hasScrollbar(el) {
  98. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  99. var style = window.getComputedStyle(el);
  100. return ['auto', 'scroll'].includes(style.overflowY) && el.scrollHeight > el.clientHeight;
  101. },
  102. shouldScroll: function shouldScroll(el, delta) {
  103. if (el.scrollTop === 0 && delta < 0) return true;
  104. return el.scrollTop + el.clientHeight === el.scrollHeight && delta > 0;
  105. },
  106. isInside: function isInside(el, parent) {
  107. if (el === parent) {
  108. return true;
  109. } else if (el === null || el === document.body) {
  110. return false;
  111. } else {
  112. return this.isInside(el.parentNode, parent);
  113. }
  114. },
  115. checkPath: function checkPath(e) {
  116. var path = e.path || this.composedPath(e);
  117. var delta = e.deltaY;
  118. if (e.type === 'keydown' && path[0] === document.body) {
  119. var dialog = this.$refs.dialog;
  120. var selected = window.getSelection().anchorNode;
  121. if (dialog && this.hasScrollbar(dialog) && this.isInside(selected, dialog)) {
  122. return this.shouldScroll(dialog, delta);
  123. }
  124. return true;
  125. }
  126. for (var index = 0; index < path.length; index++) {
  127. var el = path[index];
  128. if (el === document) return true;
  129. if (el === document.documentElement) return true;
  130. if (el === this.$refs.content) return true;
  131. if (this.hasScrollbar(el)) return this.shouldScroll(el, delta);
  132. }
  133. return true;
  134. },
  135. /**
  136. * Polyfill for Event.prototype.composedPath
  137. */
  138. composedPath: function composedPath(e) {
  139. if (e.composedPath) return e.composedPath();
  140. var path = [];
  141. var el = e.target;
  142. while (el) {
  143. path.push(el);
  144. if (el.tagName === 'HTML') {
  145. path.push(document);
  146. path.push(window);
  147. return path;
  148. }
  149. el = el.parentElement;
  150. }
  151. return path;
  152. },
  153. hideScroll: function hideScroll() {
  154. if (this.$vuetify.breakpoint.smAndDown) {
  155. document.documentElement.classList.add('overflow-y-hidden');
  156. } else {
  157. addPassiveEventListener(window, 'wheel', this.scrollListener, { passive: false });
  158. window.addEventListener('keydown', this.scrollListener);
  159. }
  160. },
  161. showScroll: function showScroll() {
  162. document.documentElement.classList.remove('overflow-y-hidden');
  163. window.removeEventListener('wheel', this.scrollListener);
  164. window.removeEventListener('keydown', this.scrollListener);
  165. }
  166. }
  167. });
  168. //# sourceMappingURL=overlayable.js.map