123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- 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: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)));
- }
|