diff --git a/src/component/tooltip/TooltipView.ts b/src/component/tooltip/TooltipView.ts index e585aef9ef..d5bf5d8f21 100644 --- a/src/component/tooltip/TooltipView.ts +++ b/src/component/tooltip/TooltipView.ts @@ -20,7 +20,7 @@ import { bind, each, clone, trim, isString, isFunction, isArray, isObject, exten import env from 'zrender/src/core/env'; import TooltipHTMLContent from './TooltipHTMLContent'; import TooltipRichContent from './TooltipRichContent'; -import { convertToColorString, formatTpl, TooltipMarker } from '../../util/format'; +import { convertToColorString, encodeHTML, formatTpl, TooltipMarker } from '../../util/format'; import { parsePercent } from '../../util/number'; import { Rect } from '../../util/graphic'; import findPointFromSeries from '../axisPointer/findPointFromSeries'; @@ -724,9 +724,11 @@ class TooltipView extends ComponentView { el: ECElement, dispatchAction: ExtensionAPI['dispatchAction'] ) { + const isHTMLRenderMode = this._renderMode === 'html'; const ecData = getECData(el); const tooltipConfig = ecData.tooltipConfig; let tooltipOpt = tooltipConfig.option || {}; + let encodeHTMLContent = tooltipOpt.encodeHTMLContent; if (isString(tooltipOpt)) { const content = tooltipOpt; tooltipOpt = { @@ -734,6 +736,16 @@ class TooltipView extends ComponentView { // Fixed formatter formatter: content }; + // when `tooltipConfig.option` is a string rather than an object, + // we can't know if the content needs to be encoded + // for the sake of security, encode it by default. + encodeHTMLContent = true; + } + + if (encodeHTMLContent && isHTMLRenderMode && tooltipOpt.content) { + // clone might be unnecessary? + tooltipOpt = clone(tooltipOpt); + tooltipOpt.content = encodeHTML(tooltipOpt.content); } const tooltipModelCascade = [tooltipOpt] as TooltipModelOptionCascade[]; diff --git a/src/util/graphic.ts b/src/util/graphic.ts index d98cf674c8..09c84953c4 100644 --- a/src/util/graphic.ts +++ b/src/util/graphic.ts @@ -67,8 +67,6 @@ import { } from 'zrender/src/core/util'; import { getECData } from './innerStore'; import ComponentModel from '../model/Component'; -import { encodeHTML } from 'zrender/src/core/dom'; - import { updateProps, @@ -601,11 +599,11 @@ export function setTooltipConfig(opt: { const ecData = getECData(opt.el); ecData.componentMainType = mainType; ecData.componentIndex = componentIndex; - ecData.tooltipConfig = { name: itemName, option: defaults({ - content: encodeHTML(itemName), + content: itemName, + encodeHTMLContent: true, formatterParams: formatterParams }, itemTooltipOptionObj) }; diff --git a/src/util/types.ts b/src/util/types.ts index 8fd9435013..653b687d91 100644 --- a/src/util/types.ts +++ b/src/util/types.ts @@ -1336,6 +1336,12 @@ export interface CommonTooltipOption { export type ComponentItemTooltipOption = CommonTooltipOption & { // Default content HTML. content?: string; + /** + * Whether to encode HTML content according to `tooltip.renderMode`. + * + * e.g. renderMode 'html' needs to encode but 'richText' does not. + */ + encodeHTMLContent?: boolean; formatterParams?: ComponentItemTooltipLabelFormatterParams; }; export type ComponentItemTooltipLabelFormatterParams = {