0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-11-29 11:24:18 +01:00

Merge pull request #17402 from twbs/pr-14552-v4

Accept elements as the tooltip / popover content
This commit is contained in:
Gleb Mazovetskiy 2015-08-31 13:03:09 +01:00
commit 33a510c63c
6 changed files with 93 additions and 25 deletions

View File

@ -193,7 +193,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
</tr> </tr>
<tr> <tr>
<td>content</td> <td>content</td>
<td>string | function</td> <td>string | element | function</td>
<td>''</td> <td>''</td>
<td> <td>
<p>Default content value if <code>data-content</code> attribute isn't present.</p> <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>
<tr> <tr>
<td>title</td> <td>title</td>
<td>string | function</td> <td>string | element | function</td>
<td>''</td> <td>''</td>
<td> <td>
<p>Default title value if <code>title</code> attribute isn't present.</p> <p>Default title value if <code>title</code> attribute isn't present.</p>

View File

@ -203,7 +203,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
</tr> </tr>
<tr> <tr>
<td>title</td> <td>title</td>
<td>string | function</td> <td>string | element | function</td>
<td>''</td> <td>''</td>
<td> <td>
<p>Default title value if <code>title</code> attribute isn't present.</p> <p>Default title value if <code>title</code> attribute isn't present.</p>

View File

@ -34,7 +34,7 @@ const Popover = (($) => {
}) })
const DefaultType = $.extend({}, Tooltip.DefaultType, { const DefaultType = $.extend({}, Tooltip.DefaultType, {
content : '(string|function)' content : '(string|element|function)'
}) })
const ClassName = { const ClassName = {
@ -113,24 +113,13 @@ const Popover = (($) => {
} }
setContent() { setContent() {
let tip = this.getTipElement() 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)
}
// we use append for html objects to maintain js events // we use append for html objects to maintain js events
$(tip).find(Selector.CONTENT).children().detach().end()[ this.setElementContent($tip.find(Selector.TITLE), this.getTitle())
this.config.html ? this.setElementContent($tip.find(Selector.CONTENT), this._getContent())
(typeof content === 'string' ? 'html' : 'append') : 'text'
](content)
$(tip) $tip
.removeClass(ClassName.FADE) .removeClass(ClassName.FADE)
.removeClass(ClassName.IN) .removeClass(ClassName.IN)

View File

@ -43,7 +43,7 @@ const Tooltip = (($) => {
const DefaultType = { const DefaultType = {
animation : 'boolean', animation : 'boolean',
template : 'string', template : 'string',
title : '(string|function)', title : '(string|element|function)',
trigger : 'string', trigger : 'string',
delay : '(number|object)', delay : '(number|object)',
html : 'boolean', html : 'boolean',
@ -356,19 +356,33 @@ const Tooltip = (($) => {
} }
setContent() { setContent() {
let tip = this.getTipElement() let $tip = $(this.getTipElement())
let title = this.getTitle()
let method = this.config.html ? 'html' : 'text'
$(tip).find(Selector.TOOLTIP_INNER)[method](title) this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle())
$(tip) $tip
.removeClass(ClassName.FADE) .removeClass(ClassName.FADE)
.removeClass(ClassName.IN) .removeClass(ClassName.IN)
this.cleanupTether() 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() { getTitle() {
let title = this.element.getAttribute('data-original-title') let title = this.element.getAttribute('data-original-title')

View File

@ -86,6 +86,42 @@ $(function () {
assert.strictEqual($('.popover').length, 0, 'popover was removed') 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) { QUnit.test('should not duplicate HTML object', function (assert) {
assert.expect(6) assert.expect(6)
var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻') var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')

View File

@ -119,6 +119,35 @@ $(function () {
assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed') 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) { QUnit.test('should respect custom classes', function (assert) {
assert.expect(2) assert.expect(2)
var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')