diff options
| author | Gleb Mazovetskiy <[email protected]> | 2015-08-31 00:57:16 +0100 |
|---|---|---|
| committer | Gleb Mazovetskiy <[email protected]> | 2015-08-31 01:06:13 +0100 |
| commit | c7d8e7a0777da91df2359655a7132e2b55482c0a (patch) | |
| tree | c953ef46e464dd1556c3b11fab8b10b300bc8b29 /js/src | |
| parent | 8941bdfbda237bed621935cac439520eddc79150 (diff) | |
| download | bootstrap-c7d8e7a0777da91df2359655a7132e2b55482c0a.tar.xz bootstrap-c7d8e7a0777da91df2359655a7132e2b55482c0a.zip | |
Accept elements as the tooltip / popover content
When a DOM node is passed to an HTML tooltip, the `title` node is only
moved if it is not already in the tooltip. Otherwise, `empty()` is used
instead of `detach()` before appending the `title` to avoid memory
leaks. If a DOM node is passed to a plain text tooltip, its text is
copied via jQuery `.text()`.
Replaces `.detach()` with `.empty()`, as `.detach()` is almost never
useful but instead leaks memory. The difference between `empty` and
`detach` is that the latter keeps all the attached jQuery events/data.
However, since we do not return the previous children, the user would
have to keep these themselves, thus they can `detach()` if necessary.
This is a port of https://github.com/twbs/bootstrap/pull/14552 to v4.
Diffstat (limited to 'js/src')
| -rw-r--r-- | js/src/popover.js | 21 | ||||
| -rw-r--r-- | js/src/tooltip.js | 26 |
2 files changed, 25 insertions, 22 deletions
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') |
