You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
6.3 KiB
230 lines
6.3 KiB
import { TAG_ID as $, NS, ATTRS, getTagID } from './html.js'; |
|
//MIME types |
|
const MIME_TYPES = { |
|
TEXT_HTML: 'text/html', |
|
APPLICATION_XML: 'application/xhtml+xml', |
|
}; |
|
//Attributes |
|
const DEFINITION_URL_ATTR = 'definitionurl'; |
|
const ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL'; |
|
const SVG_ATTRS_ADJUSTMENT_MAP = new Map([ |
|
'attributeName', |
|
'attributeType', |
|
'baseFrequency', |
|
'baseProfile', |
|
'calcMode', |
|
'clipPathUnits', |
|
'diffuseConstant', |
|
'edgeMode', |
|
'filterUnits', |
|
'glyphRef', |
|
'gradientTransform', |
|
'gradientUnits', |
|
'kernelMatrix', |
|
'kernelUnitLength', |
|
'keyPoints', |
|
'keySplines', |
|
'keyTimes', |
|
'lengthAdjust', |
|
'limitingConeAngle', |
|
'markerHeight', |
|
'markerUnits', |
|
'markerWidth', |
|
'maskContentUnits', |
|
'maskUnits', |
|
'numOctaves', |
|
'pathLength', |
|
'patternContentUnits', |
|
'patternTransform', |
|
'patternUnits', |
|
'pointsAtX', |
|
'pointsAtY', |
|
'pointsAtZ', |
|
'preserveAlpha', |
|
'preserveAspectRatio', |
|
'primitiveUnits', |
|
'refX', |
|
'refY', |
|
'repeatCount', |
|
'repeatDur', |
|
'requiredExtensions', |
|
'requiredFeatures', |
|
'specularConstant', |
|
'specularExponent', |
|
'spreadMethod', |
|
'startOffset', |
|
'stdDeviation', |
|
'stitchTiles', |
|
'surfaceScale', |
|
'systemLanguage', |
|
'tableValues', |
|
'targetX', |
|
'targetY', |
|
'textLength', |
|
'viewBox', |
|
'viewTarget', |
|
'xChannelSelector', |
|
'yChannelSelector', |
|
'zoomAndPan', |
|
].map((attr) => [attr.toLowerCase(), attr])); |
|
const XML_ATTRS_ADJUSTMENT_MAP = new Map([ |
|
['xlink:actuate', { prefix: 'xlink', name: 'actuate', namespace: NS.XLINK }], |
|
['xlink:arcrole', { prefix: 'xlink', name: 'arcrole', namespace: NS.XLINK }], |
|
['xlink:href', { prefix: 'xlink', name: 'href', namespace: NS.XLINK }], |
|
['xlink:role', { prefix: 'xlink', name: 'role', namespace: NS.XLINK }], |
|
['xlink:show', { prefix: 'xlink', name: 'show', namespace: NS.XLINK }], |
|
['xlink:title', { prefix: 'xlink', name: 'title', namespace: NS.XLINK }], |
|
['xlink:type', { prefix: 'xlink', name: 'type', namespace: NS.XLINK }], |
|
['xml:base', { prefix: 'xml', name: 'base', namespace: NS.XML }], |
|
['xml:lang', { prefix: 'xml', name: 'lang', namespace: NS.XML }], |
|
['xml:space', { prefix: 'xml', name: 'space', namespace: NS.XML }], |
|
['xmlns', { prefix: '', name: 'xmlns', namespace: NS.XMLNS }], |
|
['xmlns:xlink', { prefix: 'xmlns', name: 'xlink', namespace: NS.XMLNS }], |
|
]); |
|
//SVG tag names adjustment map |
|
export const SVG_TAG_NAMES_ADJUSTMENT_MAP = new Map([ |
|
'altGlyph', |
|
'altGlyphDef', |
|
'altGlyphItem', |
|
'animateColor', |
|
'animateMotion', |
|
'animateTransform', |
|
'clipPath', |
|
'feBlend', |
|
'feColorMatrix', |
|
'feComponentTransfer', |
|
'feComposite', |
|
'feConvolveMatrix', |
|
'feDiffuseLighting', |
|
'feDisplacementMap', |
|
'feDistantLight', |
|
'feFlood', |
|
'feFuncA', |
|
'feFuncB', |
|
'feFuncG', |
|
'feFuncR', |
|
'feGaussianBlur', |
|
'feImage', |
|
'feMerge', |
|
'feMergeNode', |
|
'feMorphology', |
|
'feOffset', |
|
'fePointLight', |
|
'feSpecularLighting', |
|
'feSpotLight', |
|
'feTile', |
|
'feTurbulence', |
|
'foreignObject', |
|
'glyphRef', |
|
'linearGradient', |
|
'radialGradient', |
|
'textPath', |
|
].map((tn) => [tn.toLowerCase(), tn])); |
|
//Tags that causes exit from foreign content |
|
const EXITS_FOREIGN_CONTENT = new Set([ |
|
$.B, |
|
$.BIG, |
|
$.BLOCKQUOTE, |
|
$.BODY, |
|
$.BR, |
|
$.CENTER, |
|
$.CODE, |
|
$.DD, |
|
$.DIV, |
|
$.DL, |
|
$.DT, |
|
$.EM, |
|
$.EMBED, |
|
$.H1, |
|
$.H2, |
|
$.H3, |
|
$.H4, |
|
$.H5, |
|
$.H6, |
|
$.HEAD, |
|
$.HR, |
|
$.I, |
|
$.IMG, |
|
$.LI, |
|
$.LISTING, |
|
$.MENU, |
|
$.META, |
|
$.NOBR, |
|
$.OL, |
|
$.P, |
|
$.PRE, |
|
$.RUBY, |
|
$.S, |
|
$.SMALL, |
|
$.SPAN, |
|
$.STRONG, |
|
$.STRIKE, |
|
$.SUB, |
|
$.SUP, |
|
$.TABLE, |
|
$.TT, |
|
$.U, |
|
$.UL, |
|
$.VAR, |
|
]); |
|
//Check exit from foreign content |
|
export function causesExit(startTagToken) { |
|
const tn = startTagToken.tagID; |
|
const isFontWithAttrs = tn === $.FONT && |
|
startTagToken.attrs.some(({ name }) => name === ATTRS.COLOR || name === ATTRS.SIZE || name === ATTRS.FACE); |
|
return isFontWithAttrs || EXITS_FOREIGN_CONTENT.has(tn); |
|
} |
|
//Token adjustments |
|
export function adjustTokenMathMLAttrs(token) { |
|
for (let i = 0; i < token.attrs.length; i++) { |
|
if (token.attrs[i].name === DEFINITION_URL_ATTR) { |
|
token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR; |
|
break; |
|
} |
|
} |
|
} |
|
export function adjustTokenSVGAttrs(token) { |
|
for (let i = 0; i < token.attrs.length; i++) { |
|
const adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name); |
|
if (adjustedAttrName != null) { |
|
token.attrs[i].name = adjustedAttrName; |
|
} |
|
} |
|
} |
|
export function adjustTokenXMLAttrs(token) { |
|
for (let i = 0; i < token.attrs.length; i++) { |
|
const adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name); |
|
if (adjustedAttrEntry) { |
|
token.attrs[i].prefix = adjustedAttrEntry.prefix; |
|
token.attrs[i].name = adjustedAttrEntry.name; |
|
token.attrs[i].namespace = adjustedAttrEntry.namespace; |
|
} |
|
} |
|
} |
|
export function adjustTokenSVGTagName(token) { |
|
const adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP.get(token.tagName); |
|
if (adjustedTagName != null) { |
|
token.tagName = adjustedTagName; |
|
token.tagID = getTagID(token.tagName); |
|
} |
|
} |
|
//Integration points |
|
function isMathMLTextIntegrationPoint(tn, ns) { |
|
return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT); |
|
} |
|
function isHtmlIntegrationPoint(tn, ns, attrs) { |
|
if (ns === NS.MATHML && tn === $.ANNOTATION_XML) { |
|
for (let i = 0; i < attrs.length; i++) { |
|
if (attrs[i].name === ATTRS.ENCODING) { |
|
const value = attrs[i].value.toLowerCase(); |
|
return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML; |
|
} |
|
} |
|
} |
|
return ns === NS.SVG && (tn === $.FOREIGN_OBJECT || tn === $.DESC || tn === $.TITLE); |
|
} |
|
export function isIntegrationPoint(tn, ns, attrs, foreignNS) { |
|
return (((!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs)) || |
|
((!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns))); |
|
} |
|
//# sourceMappingURL=foreign-content.js.map
|