diff options
author | Eric Eastwood <contact@ericeastwood.com> | 2017-06-06 15:46:31 -0500 |
---|---|---|
committer | Eric Eastwood <contact@ericeastwood.com> | 2017-06-06 16:18:51 -0500 |
commit | 83e66eef414ad7bc77950e83d54e9e851dda373c (patch) | |
tree | 9c29a7e5ebbc885449a01207e357a4e75fac9f53 | |
parent | 6ac1caa01a4c059f5bcb7c9da2e83001e5469f73 (diff) | |
download | gitlab-ce-33223-multiple-tooltips-on-the-same-vue-component.tar.gz |
Add support for multiple tooltips in the same Vue component33223-multiple-tooltips-on-the-same-vue-component
Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/33223
17 files changed, 102 insertions, 41 deletions
diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue index 41d5453f1b2..baa28746f3b 100644 --- a/app/assets/javascripts/environments/components/environment_actions.vue +++ b/app/assets/javascripts/environments/components/environment_actions.vue @@ -54,10 +54,9 @@ export default { role="group"> <button type="button" - class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container has-tooltip" + class="dropdown btn btn-default dropdown-new js-dropdown-play-icon-container js-vue-tooltip" data-container="body" data-toggle="dropdown" - ref="tooltip" :title="title" :aria-label="title" :disabled="isLoading"> diff --git a/app/assets/javascripts/issue_show/components/fields/project_move.vue b/app/assets/javascripts/issue_show/components/fields/project_move.vue index f811fb0de24..51623574dc3 100644 --- a/app/assets/javascripts/issue_show/components/fields/project_move.vue +++ b/app/assets/javascripts/issue_show/components/fields/project_move.vue @@ -71,9 +71,9 @@ data-placeholder="Move to a different project" /> </div> <span + class="js-vue-tooltip" data-placement="auto top" - title="Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location." - ref="tooltip"> + title="Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location."> <i class="fa fa-question-circle" aria-hidden="true"> diff --git a/app/assets/javascripts/pipelines/components/graph/action_component.vue b/app/assets/javascripts/pipelines/components/graph/action_component.vue index 1f9e3d39779..315959f939a 100644 --- a/app/assets/javascripts/pipelines/components/graph/action_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/action_component.vue @@ -49,8 +49,7 @@ :data-method="actionMethod" :title="tooltipText" :href="link" - ref="tooltip" - class="ci-action-icon-container" + class="ci-action-icon-container js-vue-tooltip" data-toggle="tooltip" data-container="body"> diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue index 19cafff4e1c..5501c777bbc 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue @@ -45,9 +45,8 @@ :data-method="actionMethod" :title="tooltipText" :href="link" - ref="tooltip" rel="nofollow" - class="ci-action-icon-wrapper js-ci-status-icon" + class="ci-action-icon-wrapper js-ci-status-icon js-vue-tooltip" data-toggle="tooltip" data-container="body" v-html="actionIconSvg" diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue index d597af8dfb5..cdc213b97f2 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue @@ -56,9 +56,8 @@ type="button" data-toggle="dropdown" data-container="body" - class="dropdown-menu-toggle build-content" - :title="tooltipText" - ref="tooltip"> + class="dropdown-menu-toggle build-content js-vue-tooltip" + :title="tooltipText"> <job-name-component :name="job.name" diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue index b39c936101e..0a32e33a71f 100644 --- a/app/assets/javascripts/pipelines/components/graph/job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue @@ -80,8 +80,8 @@ v-if="job.status.details_path" :href="job.status.details_path" :title="tooltipText" + class="js-vue-tooltip" :class="cssClassJobName" - ref="tooltip" data-toggle="tooltip" data-container="body"> @@ -94,8 +94,8 @@ <div v-else :title="tooltipText" + class="js-vue-tooltip" :class="cssClassJobName" - ref="tooltip" data-toggle="tooltip" data-container="body"> diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 4781a8ff1da..ce4cb3bd3b6 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -44,16 +44,14 @@ export default { </span> <span v-if="pipeline.flags.latest" - class="js-pipeline-url-lastest label label-success" - title="Latest pipeline for this branch" - ref="tooltip"> + class="js-pipeline-url-lastest js-vue-tooltip label label-success" + title="Latest pipeline for this branch"> latest </span> <span v-if="pipeline.flags.yaml_errors" - class="js-pipeline-url-yaml label label-danger" - :title="pipeline.yaml_errors" - ref="tooltip"> + class="js-pipeline-url-yaml js-vue-tooltip label label-danger" + :title="pipeline.yaml_errors"> yaml invalid </span> <span diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.js b/app/assets/javascripts/pipelines/components/pipelines_actions.js index b9e066c5db1..0c987734776 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_actions.js +++ b/app/assets/javascripts/pipelines/components/pipelines_actions.js @@ -59,12 +59,11 @@ export default { <div class="btn-group" v-if="actions"> <button type="button" - class="dropdown-toggle btn btn-default has-tooltip js-pipeline-dropdown-manual-actions" + class="dropdown-toggle btn btn-default has-tooltip js-pipeline-dropdown-manual-actions js-vue-tooltip" title="Manual job" data-toggle="dropdown" data-placement="top" aria-label="Manual job" - ref="tooltip" :disabled="isLoading"> ${playIconSvg} <i diff --git a/app/assets/javascripts/pipelines/components/time_ago.js b/app/assets/javascripts/pipelines/components/time_ago.js index 188f74cc705..ea15557ec23 100644 --- a/app/assets/javascripts/pipelines/components/time_ago.js +++ b/app/assets/javascripts/pipelines/components/time_ago.js @@ -85,7 +85,7 @@ export default { aria-hidden="true" /> <time - ref="tooltip" + class="js-vue-tooltip" data-toggle="tooltip" data-placement="top" data-container="body" diff --git a/app/assets/javascripts/vue_shared/components/header_ci_component.vue b/app/assets/javascripts/vue_shared/components/header_ci_component.vue index fe6d6a792e7..d7b5cfc9fbc 100644 --- a/app/assets/javascripts/vue_shared/components/header_ci_component.vue +++ b/app/assets/javascripts/vue_shared/components/header_ci_component.vue @@ -86,8 +86,7 @@ export default { <a :href="user.path" :title="user.email" - class="js-user-link commit-committer-link" - ref="tooltip"> + class="js-user-link js-vue-tooltip commit-committer-link"> <user-avatar-image :img-src="user.avatar_url" diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index 1a11f493b7f..4ad5272d280 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -95,12 +95,11 @@ <div class="toolbar-group"> <button aria-label="Go full screen" - class="toolbar-btn js-zen-enter" + class="toolbar-btn js-zen-enter js-vue-tooltip" data-container="body" tabindex="-1" title="Go full screen" - type="button" - ref="tooltip"> + type="button"> <i aria-hidden="true" class="fa fa-arrows-alt fa-fw"> diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue index 096be507625..6a0288e9d26 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue @@ -40,9 +40,8 @@ <template> <button type="button" - class="toolbar-btn js-md hidden-xs" + class="toolbar-btn js-md hidden-xs js-vue-tooltip" tabindex="-1" - ref="tooltip" data-container="body" :data-md-tag="tag" :data-md-block="tagBlock" diff --git a/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue b/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue index af2b4c6786e..6ab41bc9806 100644 --- a/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue +++ b/app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue @@ -48,11 +48,10 @@ export default { <template> <time :class="[timeagoCssClass, cssClass]" - class="js-timeago js-timeago-render" + class="js-timeago js-timeago-render js-vue-tooltip" :title="tooltipTitle(time)" :data-placement="tooltipPlacement" - data-container="body" - ref="tooltip"> + data-container="body"> {{timeFormated(time)}} </time> </template> diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue index cd6f8c7aee4..5cfa096615b 100644 --- a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue +++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue @@ -72,7 +72,7 @@ export default { <template> <img - class="avatar" + class="avatar js-vue-tooltip" :class="[avatarSizeClass, cssClasses]" :src="imageSource" :width="size" @@ -81,6 +81,5 @@ export default { :data-container="tooltipContainer" :data-placement="tooltipPlacement" :title="tooltipText" - ref="tooltip" /> </template> diff --git a/app/assets/javascripts/vue_shared/mixins/tooltip.js b/app/assets/javascripts/vue_shared/mixins/tooltip.js index 995c0c98505..a419fe78b2b 100644 --- a/app/assets/javascripts/vue_shared/mixins/tooltip.js +++ b/app/assets/javascripts/vue_shared/mixins/tooltip.js @@ -1,13 +1,20 @@ +function $filterFind(el, selector) { + return $(el) + .find('*') // Take the current selection and find all descendants, + .addBack() // add the original selection back to the set + .filter(selector); // and filter by the selector. +} + export default { mounted() { - $(this.$refs.tooltip).tooltip(); + $filterFind(this.$el, '.js-vue-tooltip').tooltip(); }, updated() { - $(this.$refs.tooltip).tooltip('fixTitle'); + $filterFind(this.$el, '.js-vue-tooltip').tooltip('fixTitle'); }, beforeDestroy() { - $(this.$refs.tooltip).tooltip('destroy'); + $filterFind(this.$el, '.js-vue-tooltip').tooltip('destroy'); }, }; diff --git a/doc/development/fe_guide/style_guide_js.md b/doc/development/fe_guide/style_guide_js.md index d2d89517241..f77d863fbc7 100644 --- a/doc/development/fe_guide/style_guide_js.md +++ b/doc/development/fe_guide/style_guide_js.md @@ -463,20 +463,24 @@ A forEach will cause side effects, it will be mutating the array being iterated. 1. `destroyed` #### Vue and Boostrap -1. Tooltips: Do not rely on `has-tooltip` class name for vue components +1. Tooltips: Do not rely on `has-tooltip` class name for Vue components ```javascript // bad - <span class="has-tooltip"> + <span + class="has-tooltip" + title="Some tooltip text"> Text </span> // good - <span data-toggle="tooltip"> + <span + class="js-vue-tooltip" + title="Some tooltip text"> Text </span> ``` -1. Tooltips: When using a tooltip, include the tooltip mixin +1. Tooltips: When using a tooltip, include the tooltip mixin, `./app/assets/javascripts/vue_shared/mixins/tooltip.js` 1. Don't change `data-original-title`. ```javascript diff --git a/spec/javascripts/vue_shared/mixins/tooltip_spec.js b/spec/javascripts/vue_shared/mixins/tooltip_spec.js new file mode 100644 index 00000000000..ad11dca4052 --- /dev/null +++ b/spec/javascripts/vue_shared/mixins/tooltip_spec.js @@ -0,0 +1,62 @@ +import Vue from 'vue'; +import tooltipMixin from '~/vue_shared/mixins/tooltip'; + +describe('Tooltip mixin', () => { + let vm; + + afterEach(() => { + if (vm) { + vm.$destroy(); + } + }); + + describe('with a single tooltip', () => { + beforeEach(() => { + const SomeComponent = Vue.extend({ + mixins: [ + tooltipMixin, + ], + template: ` + <div + class="js-vue-tooltip" + title="foo"> + </div> + `, + }); + + vm = new SomeComponent().$mount(); + }); + + it('should have tooltip plugin applied', () => { + expect($(vm.$el).data('bs.tooltip')).toBeDefined(); + }); + }); + + describe('with multiple tooltips', () => { + beforeEach(() => { + const SomeComponent = Vue.extend({ + mixins: [ + tooltipMixin, + ], + template: ` + <div> + <div + class="js-vue-tooltip" + title="foo"> + </div> + <div + class="js-vue-tooltip" + title="bar"> + </div> + </div> + `, + }); + + vm = new SomeComponent().$mount(); + }); + + it('should have tooltip plugin applied to all instances', () => { + expect($(vm.$el).find('.js-vue-tooltip').data('bs.tooltip')).toBeDefined(); + }); + }); +}); |