From 5747164818d80d7cf77323fa3c47c054e3534c9e Mon Sep 17 00:00:00 2001 From: Gidoont Date: Wed, 23 Jun 2021 16:53:57 +0300 Subject: [PATCH 1/4] Added support for Shadow DOM --- .idea/.gitignore | 8 ++ .idea/codeStyles/Project.xml | 75 +++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ .idea/encodings.xml | 4 + .idea/inspectionProfiles/Project_Default.xml | 6 ++ .idea/misc.xml | 6 ++ .idea/modules.xml | 8 ++ .idea/v-tooltip.iml | 8 ++ .idea/vcs.xml | 6 ++ README.md | 2 +- docs-src/PageHome.vue | 6 ++ docs-src/shadow/TooltipShadowDOMContainer.vue | 38 ++++++++++ docs-src/shadow/TooltipShadowDOMContent.vue | 36 +++++++++ src/components/Popover.vue | 2 +- src/lib/tooltip.js | 13 ++-- src/utils.js | 19 +++++ 16 files changed, 234 insertions(+), 8 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/v-tooltip.iml create mode 100644 .idea/vcs.xml create mode 100644 docs-src/shadow/TooltipShadowDOMContainer.vue create mode 100644 docs-src/shadow/TooltipShadowDOMContent.vue diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..73f69e09 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..4827e75f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,75 @@ + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..79ee123c --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 00000000..15a15b21 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..03d9549e --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..039e6a73 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..a8c12943 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/v-tooltip.iml b/.idea/v-tooltip.iml new file mode 100644 index 00000000..c956989b --- /dev/null +++ b/.idea/v-tooltip.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index c6497f7e..5b24cadb 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ Or a reactive property: - `trigger` - Events triggering the tooltip separated with spaces: `'hover'`, `'click'`, `'focus'` or `'manual'` (`'manual'` can't be combined with any other event). - `show` - Boolean to manually open or hide the tooltip. - `offset` - Offset of the position (px). -- `container` - Selector: Container where the tooltip will be appended (e.g. `'body'`). Set it to `false` to append popover on target parent node. +- `container` - Selector: Container where the tooltip will be appended (e.g. `'body'`). Set it to `false` to append popover on target parent node. Provide a callback to resolve container dynamically, signature would be `callback(targetElement)`. - `boundariesElement` - DOM element for the tooltip boundaries. - `template` - HTML template of the tooltip. - `arrowSelector` - CSS selector to get the arrow element in the tooltip template. diff --git a/docs-src/PageHome.vue b/docs-src/PageHome.vue index 42216e75..93db6162 100644 --- a/docs-src/PageHome.vue +++ b/docs-src/PageHome.vue @@ -305,6 +305,10 @@ + + @@ -314,6 +318,7 @@ import screenfull from 'screenfull' import CodeSnippet from './CodeSnippet.vue' import Collapse from './Collapse.vue' import ExampleComponent from './ExampleComponent.vue' +import TooltipShadowDOMContainer from './shadow/TooltipShadowDOMContainer' const mainSnippet = ` import Vue from 'vue' @@ -612,6 +617,7 @@ export default { CodeSnippet, Collapse, ExampleComponent, + TooltipShadowDOMContainer }, data () { diff --git a/docs-src/shadow/TooltipShadowDOMContainer.vue b/docs-src/shadow/TooltipShadowDOMContainer.vue new file mode 100644 index 00000000..67543f92 --- /dev/null +++ b/docs-src/shadow/TooltipShadowDOMContainer.vue @@ -0,0 +1,38 @@ + + + diff --git a/docs-src/shadow/TooltipShadowDOMContent.vue b/docs-src/shadow/TooltipShadowDOMContent.vue new file mode 100644 index 00000000..2d4c6a83 --- /dev/null +++ b/docs-src/shadow/TooltipShadowDOMContent.vue @@ -0,0 +1,36 @@ + + + + + + + diff --git a/src/components/Popover.vue b/src/components/Popover.vue index 5b256ea5..de92e9ff 100644 --- a/src/components/Popover.vue +++ b/src/components/Popover.vue @@ -705,7 +705,7 @@ function handleGlobalClose (event, touch = false) { for (let i = 0; i < openPopovers.length; i++) { const popover = openPopovers[i] if (popover.$refs.popover) { - const contains = popover.$refs.popover.contains(event.target) + const contains = popover.$refs.popover.contains(event.composedPath()[0]) requestAnimationFrame(() => { if (event.closeAllPopover || (event.closePopover && contains) || (popover.autoHide && !contains)) { popover.$_handleGlobalClose(event, touch) diff --git a/src/lib/tooltip.js b/src/lib/tooltip.js index 1837f8ef..9e490175 100644 --- a/src/lib/tooltip.js +++ b/src/lib/tooltip.js @@ -2,7 +2,7 @@ import Popper from 'popper.js' import { getOptions, directive } from '../directives/v-tooltip' -import { addClasses, removeClasses, supportsPassive } from '../utils' +import { addClasses, isInDocument, removeClasses, supportsPassive } from '../utils' import isEqual from 'lodash/isEqual' const DEFAULT_OPTIONS = { @@ -287,8 +287,8 @@ export default class Tooltip { } _show (reference, options) { - if (options && typeof options.container === 'string') { - const container = document.querySelector(options.container) + if (options) { + const container = this._findContainer(options.container); if (!container) return } @@ -490,6 +490,9 @@ export default class Tooltip { // if container is a query, get the relative element if (typeof container === 'string') { container = window.document.querySelector(container) + } else if (typeof container === 'function') { + // if container is function that returns an element, resolve it + container = container(reference) } else if (container === false) { // if container is `false`, set it to reference parent container = reference.parentNode @@ -578,9 +581,7 @@ export default class Tooltip { if (this._isOpen === false) { return } - if (!this._tooltipNode.ownerDocument.body.contains(this._tooltipNode)) { - return - } + if (!isInDocument(this._tooltipNode)) return // if we are hiding because of a mouseleave, we must check that the new // reference isn't the tooltip, because in this case we don't want to hide it diff --git a/src/utils.js b/src/utils.js index 2a1a1491..dc884b7e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -10,6 +10,25 @@ export function convertToArray (value) { return value } +/** + * Check if an element is in the DOM (Including the Shadow DOM). + * @param element + * @returns {boolean} + */ +export function isInDocument (element) { + let currentElement = element + while (currentElement && currentElement.parentNode) { + if (currentElement.parentNode === document) { + return true + } else if (currentElement.parentNode instanceof DocumentFragment) { + currentElement = currentElement.parentNode.host + } else { + currentElement = currentElement.parentNode + } + } + return false +} + /** * Add classes to an element. * This method checks to ensure that the classes don't already exist before adding them. From 6e7c017789c2b7ec0cc7968279fa3030a22ba017 Mon Sep 17 00:00:00 2001 From: Gidoont Date: Wed, 23 Jun 2021 17:17:16 +0300 Subject: [PATCH 2/4] Added .idea to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e7dda6cb..bacbeeb6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ npm-debug.log coverage/ +.idea/ dist/ From d5f45251a5132b0cda664022979c1791388345e1 Mon Sep 17 00:00:00 2001 From: Gidoont Date: Wed, 23 Jun 2021 17:19:29 +0300 Subject: [PATCH 3/4] Removed .idea folder --- .idea/.gitignore | 8 --- .idea/codeStyles/Project.xml | 75 -------------------- .idea/codeStyles/codeStyleConfig.xml | 5 -- .idea/encodings.xml | 4 -- .idea/inspectionProfiles/Project_Default.xml | 6 -- .idea/misc.xml | 6 -- .idea/modules.xml | 8 --- .idea/v-tooltip.iml | 8 --- .idea/vcs.xml | 6 -- 9 files changed, 126 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/v-tooltip.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 73f69e09..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 4827e75f..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 15a15b21..00000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549e..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 039e6a73..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index a8c12943..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/v-tooltip.iml b/.idea/v-tooltip.iml deleted file mode 100644 index c956989b..00000000 --- a/.idea/v-tooltip.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 0ec7697ab2d21a76de2fd9a12fbec2645a37a177 Mon Sep 17 00:00:00 2001 From: Gidoont Date: Wed, 23 Jun 2021 17:40:40 +0300 Subject: [PATCH 4/4] Updated types --- docs-src/shadow/TooltipShadowDOMContent.vue | 2 +- src/lib/tooltip.js | 2 +- types/index.d.ts | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs-src/shadow/TooltipShadowDOMContent.vue b/docs-src/shadow/TooltipShadowDOMContent.vue index 2d4c6a83..70249620 100644 --- a/docs-src/shadow/TooltipShadowDOMContent.vue +++ b/docs-src/shadow/TooltipShadowDOMContent.vue @@ -22,7 +22,7 @@ export default { data () { return { msg: 'This is a button within shadowDOM', - el: this.$root.$el.parentElement, + el: (targetElement) => this.$root.$el.parentElement, } }, diff --git a/src/lib/tooltip.js b/src/lib/tooltip.js index 9e490175..429e95de 100644 --- a/src/lib/tooltip.js +++ b/src/lib/tooltip.js @@ -288,7 +288,7 @@ export default class Tooltip { _show (reference, options) { if (options) { - const container = this._findContainer(options.container); + const container = this._findContainer(options.container, reference) if (!container) return } diff --git a/types/index.d.ts b/types/index.d.ts index 7e619de0..8c373805 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -72,8 +72,7 @@ export interface GlobalVTooltipOptions { * Default container where the tooltip will be appended * @default 'body' */ - defaultContainer: string | HTMLElement | false - + defaultContainer: string | HTMLElement | false | ((targetElement: Element) => Element) defaultBoundariesElement: string | HTMLElement defaultPopperOptions: any @@ -203,4 +202,4 @@ export default vToolTip; export const VPopover: VueConstructor; export const VClosePopover: DirectiveOptions; -export const VTooltip: DirectiveOptions; \ No newline at end of file +export const VTooltip: DirectiveOptions;