aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Mazovetskiy <[email protected]>2015-08-31 13:03:09 +0100
committerGleb Mazovetskiy <[email protected]>2015-08-31 13:03:09 +0100
commit33a510c63c9a898d68da807205afbbb8e1dfce16 (patch)
treec953ef46e464dd1556c3b11fab8b10b300bc8b29
parent8941bdfbda237bed621935cac439520eddc79150 (diff)
parentc7d8e7a0777da91df2359655a7132e2b55482c0a (diff)
downloadbootstrap-33a510c63c9a898d68da807205afbbb8e1dfce16.tar.xz
bootstrap-33a510c63c9a898d68da807205afbbb8e1dfce16.zip
Merge pull request #17402 from twbs/pr-14552-v4
Accept elements as the tooltip / popover content
-rw-r--r--docs/components/popovers.md4
-rw-r--r--docs/components/tooltips.md2
-rw-r--r--js/src/popover.js21
-rw-r--r--js/src/tooltip.js26
-rw-r--r--js/tests/unit/popover.js36
-rw-r--r--js/tests/unit/tooltip.js29
6 files changed, 93 insertions, 25 deletions
diff --git a/docs/components/popovers.md b/docs/components/popovers.md
index 98672d23e..f48d860ea 100644
--- a/docs/components/popovers.md
+++ b/docs/components/popovers.md
@@ -193,7 +193,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
</tr>
<tr>
<td>content</td>
- <td>string | function</td>
+ <td>string | element | function</td>
<td>''</td>
<td>
<p>Default content value if <code>data-content</code> attribute isn't present.</p>
@@ -245,7 +245,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
</tr>
<tr>
<td>title</td>
- <td>string | function</td>
+ <td>string | element | function</td>
<td>''</td>
<td>
<p>Default title value if <code>title</code> attribute isn't present.</p>
diff --git a/docs/components/tooltips.md b/docs/components/tooltips.md
index 65bd2703b..f2936469b 100644
--- a/docs/components/tooltips.md
+++ b/docs/components/tooltips.md
@@ -203,7 +203,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
</tr>
<tr>
<td>title</td>
- <td>string | function</td>
+ <td>string | element | function</td>
<td>''</td>
<td>
<p>Default title value if <code>title</code> attribute isn't present.</p>
diff --git a/js/src/popover.js b/js/src/popover.js
index 99e48e64f..b8b24a1c4 100644
--- a/js/src/popover.js
+++ b/js/src/popover.js
@@ -34,7 +34,7 @@ const Popover = (($) => {
})
const DefaultType = $.extend({}, Tooltip.DefaultType, {
- content : '(string|function)'
+ content : '(string|element|function)'
})
const ClassName = {
@@ -113,24 +113,13 @@ const Popover = (($) => {
}
setContent() {
- let tip = this.getTipElement()
- let title = this.getTitle()
- let content = this._getContent()
- let $titleElement = $(tip).find(Selector.TITLE)
-
- if ($titleElement) {
- $titleElement[
- this.config.html ? 'html' : 'text'
- ](title)
- }
+ let $tip = $(this.getTipElement())
// we use append for html objects to maintain js events
- $(tip).find(Selector.CONTENT).children().detach().end()[
- this.config.html ?
- (typeof content === 'string' ? 'html' : 'append') : 'text'
- ](content)
+ this.setElementContent($tip.find(Selector.TITLE), this.getTitle())
+ this.setElementContent($tip.find(Selector.CONTENT), this._getContent())
- $(tip)
+ $tip
.removeClass(ClassName.FADE)
.removeClass(ClassName.IN)
diff --git a/js/src/tooltip.js b/js/src/tooltip.js
index aa5c73945..151cd6f51 100644
--- a/js/src/tooltip.js
+++ b/js/src/tooltip.js
@@ -43,7 +43,7 @@ const Tooltip = (($) => {
const DefaultType = {
animation : 'boolean',
template : 'string',
- title : '(string|function)',
+ title : '(string|element|function)',
trigger : 'string',
delay : '(number|object)',
html : 'boolean',
@@ -356,19 +356,33 @@ const Tooltip = (($) => {
}
setContent() {
- let tip = this.getTipElement()
- let title = this.getTitle()
- let method = this.config.html ? 'html' : 'text'
+ let $tip = $(this.getTipElement())
- $(tip).find(Selector.TOOLTIP_INNER)[method](title)
+ this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle())
- $(tip)
+ $tip
.removeClass(ClassName.FADE)
.removeClass(ClassName.IN)
this.cleanupTether()
}
+ setElementContent($element, content) {
+ let html = this.config.html
+ if (typeof content === 'object' && (content.nodeType || content.jquery)) {
+ // content is a DOM node or a jQuery
+ if (html) {
+ if (!$(content).parent().is($element)) {
+ $element.empty().append(content)
+ }
+ } else {
+ $element.text($(content).text())
+ }
+ } else {
+ $element[html ? 'html' : 'text'](content)
+ }
+ }
+
getTitle() {
let title = this.element.getAttribute('data-original-title')
diff --git a/js/tests/unit/popover.js b/js/tests/unit/popover.js
index 8347e9f03..894468695 100644
--- a/js/tests/unit/popover.js
+++ b/js/tests/unit/popover.js
@@ -86,6 +86,42 @@ $(function () {
assert.strictEqual($('.popover').length, 0, 'popover was removed')
})
+ QUnit.test('should allow DOMElement title and content (html: true)', function (assert) {
+ assert.expect(5)
+ var title = document.createTextNode('@glebm <3 writing tests')
+ var content = $('<i>¯\\_(ツ)_/¯</i>').get(0)
+ var $popover = $('<a href="#" rel="tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapPopover({ html: true, title: title, content: content })
+
+ $popover.bootstrapPopover('show')
+
+ assert.notEqual($('.popover').length, 0, 'popover inserted')
+ assert.strictEqual($('.popover .popover-title').text(), '@glebm <3 writing tests', 'title inserted')
+ assert.ok($.contains($('.popover').get(0), title), 'title node moved, not copied')
+ // toLowerCase because IE8 will return <I>...</I>
+ assert.strictEqual($('.popover .popover-content').html().toLowerCase(), '<i>¯\\_(ツ)_/¯</i>', 'content inserted')
+ assert.ok($.contains($('.popover').get(0), content), 'content node moved, not copied')
+ })
+
+ QUnit.test('should allow DOMElement title and content (html: false)', function (assert) {
+ assert.expect(5)
+ var title = document.createTextNode('@glebm <3 writing tests')
+ var content = $('<i>¯\\_(ツ)_/¯</i>').get(0)
+ var $popover = $('<a href="#" rel="tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapPopover({ title: title, content: content })
+
+ $popover.bootstrapPopover('show')
+
+ assert.notEqual($('.popover').length, 0, 'popover inserted')
+ assert.strictEqual($('.popover .popover-title').text(), '@glebm <3 writing tests', 'title inserted')
+ assert.ok(!$.contains($('.popover').get(0), title), 'title node copied, not moved')
+ assert.strictEqual($('.popover .popover-content').html(), '¯\\_(ツ)_/¯', 'content inserted')
+ assert.ok(!$.contains($('.popover').get(0), content), 'content node copied, not moved')
+ })
+
+
QUnit.test('should not duplicate HTML object', function (assert) {
assert.expect(6)
var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
diff --git a/js/tests/unit/tooltip.js b/js/tests/unit/tooltip.js
index f4deb29f8..934e26b9e 100644
--- a/js/tests/unit/tooltip.js
+++ b/js/tests/unit/tooltip.js
@@ -119,6 +119,35 @@ $(function () {
assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
})
+ QUnit.test('should allow DOMElement title (html: false)', function (assert) {
+ assert.expect(3)
+ var title = document.createTextNode('<3 writing tests')
+ var $tooltip = $('<a href="#" rel="tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ title: title })
+
+ $tooltip.bootstrapTooltip('show')
+
+ assert.notEqual($('.tooltip').length, 0, 'tooltip inserted')
+ assert.strictEqual($('.tooltip').text(), '<3 writing tests', 'title inserted')
+ assert.ok(!$.contains($('.tooltip').get(0), title), 'title node copied, not moved')
+ })
+
+ QUnit.test('should allow DOMElement title (html: true)', function (assert) {
+ assert.expect(3)
+ var title = document.createTextNode('<3 writing tests')
+ var $tooltip = $('<a href="#" rel="tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({ html: true, title: title })
+
+ $tooltip.bootstrapTooltip('show')
+
+ assert.notEqual($('.tooltip').length, 0, 'tooltip inserted')
+ assert.strictEqual($('.tooltip').text(), '<3 writing tests', 'title inserted')
+ assert.ok($.contains($('.tooltip').get(0), title), 'title node moved, not copied')
+ })
+
+
QUnit.test('should respect custom classes', function (assert) {
assert.expect(2)
var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')