summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Eastwood <contact@ericeastwood.com>2017-06-06 15:46:31 -0500
committerEric Eastwood <contact@ericeastwood.com>2017-06-06 16:18:51 -0500
commit83e66eef414ad7bc77950e83d54e9e851dda373c (patch)
tree9c29a7e5ebbc885449a01207e357a4e75fac9f53
parent6ac1caa01a4c059f5bcb7c9da2e83001e5469f73 (diff)
downloadgitlab-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
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.vue3
-rw-r--r--app/assets/javascripts/issue_show/components/fields/project_move.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/graph/action_component.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/dropdown_action_component.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue5
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_component.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_url.vue10
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_actions.js3
-rw-r--r--app/assets/javascripts/pipelines/components/time_ago.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/header_ci_component.vue3
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue3
-rw-r--r--app/assets/javascripts/vue_shared/components/time_ago_tooltip.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue3
-rw-r--r--app/assets/javascripts/vue_shared/mixins/tooltip.js13
-rw-r--r--doc/development/fe_guide/style_guide_js.md12
-rw-r--r--spec/javascripts/vue_shared/mixins/tooltip_spec.js62
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();
+ });
+ });
+});