1 | import { TAG_ID as $, NS, ATTRS, getTagID } from './html.js';
|
2 |
|
3 | const MIME_TYPES = {
|
4 | TEXT_HTML: 'text/html',
|
5 | APPLICATION_XML: 'application/xhtml+xml',
|
6 | };
|
7 |
|
8 | const DEFINITION_URL_ATTR = 'definitionurl';
|
9 | const ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL';
|
10 | const SVG_ATTRS_ADJUSTMENT_MAP = new Map([
|
11 | 'attributeName',
|
12 | 'attributeType',
|
13 | 'baseFrequency',
|
14 | 'baseProfile',
|
15 | 'calcMode',
|
16 | 'clipPathUnits',
|
17 | 'diffuseConstant',
|
18 | 'edgeMode',
|
19 | 'filterUnits',
|
20 | 'glyphRef',
|
21 | 'gradientTransform',
|
22 | 'gradientUnits',
|
23 | 'kernelMatrix',
|
24 | 'kernelUnitLength',
|
25 | 'keyPoints',
|
26 | 'keySplines',
|
27 | 'keyTimes',
|
28 | 'lengthAdjust',
|
29 | 'limitingConeAngle',
|
30 | 'markerHeight',
|
31 | 'markerUnits',
|
32 | 'markerWidth',
|
33 | 'maskContentUnits',
|
34 | 'maskUnits',
|
35 | 'numOctaves',
|
36 | 'pathLength',
|
37 | 'patternContentUnits',
|
38 | 'patternTransform',
|
39 | 'patternUnits',
|
40 | 'pointsAtX',
|
41 | 'pointsAtY',
|
42 | 'pointsAtZ',
|
43 | 'preserveAlpha',
|
44 | 'preserveAspectRatio',
|
45 | 'primitiveUnits',
|
46 | 'refX',
|
47 | 'refY',
|
48 | 'repeatCount',
|
49 | 'repeatDur',
|
50 | 'requiredExtensions',
|
51 | 'requiredFeatures',
|
52 | 'specularConstant',
|
53 | 'specularExponent',
|
54 | 'spreadMethod',
|
55 | 'startOffset',
|
56 | 'stdDeviation',
|
57 | 'stitchTiles',
|
58 | 'surfaceScale',
|
59 | 'systemLanguage',
|
60 | 'tableValues',
|
61 | 'targetX',
|
62 | 'targetY',
|
63 | 'textLength',
|
64 | 'viewBox',
|
65 | 'viewTarget',
|
66 | 'xChannelSelector',
|
67 | 'yChannelSelector',
|
68 | 'zoomAndPan',
|
69 | ].map((attr) => [attr.toLowerCase(), attr]));
|
70 | const XML_ATTRS_ADJUSTMENT_MAP = new Map([
|
71 | ['xlink:actuate', { prefix: 'xlink', name: 'actuate', namespace: NS.XLINK }],
|
72 | ['xlink:arcrole', { prefix: 'xlink', name: 'arcrole', namespace: NS.XLINK }],
|
73 | ['xlink:href', { prefix: 'xlink', name: 'href', namespace: NS.XLINK }],
|
74 | ['xlink:role', { prefix: 'xlink', name: 'role', namespace: NS.XLINK }],
|
75 | ['xlink:show', { prefix: 'xlink', name: 'show', namespace: NS.XLINK }],
|
76 | ['xlink:title', { prefix: 'xlink', name: 'title', namespace: NS.XLINK }],
|
77 | ['xlink:type', { prefix: 'xlink', name: 'type', namespace: NS.XLINK }],
|
78 | ['xml:base', { prefix: 'xml', name: 'base', namespace: NS.XML }],
|
79 | ['xml:lang', { prefix: 'xml', name: 'lang', namespace: NS.XML }],
|
80 | ['xml:space', { prefix: 'xml', name: 'space', namespace: NS.XML }],
|
81 | ['xmlns', { prefix: '', name: 'xmlns', namespace: NS.XMLNS }],
|
82 | ['xmlns:xlink', { prefix: 'xmlns', name: 'xlink', namespace: NS.XMLNS }],
|
83 | ]);
|
84 |
|
85 | export const SVG_TAG_NAMES_ADJUSTMENT_MAP = new Map([
|
86 | 'altGlyph',
|
87 | 'altGlyphDef',
|
88 | 'altGlyphItem',
|
89 | 'animateColor',
|
90 | 'animateMotion',
|
91 | 'animateTransform',
|
92 | 'clipPath',
|
93 | 'feBlend',
|
94 | 'feColorMatrix',
|
95 | 'feComponentTransfer',
|
96 | 'feComposite',
|
97 | 'feConvolveMatrix',
|
98 | 'feDiffuseLighting',
|
99 | 'feDisplacementMap',
|
100 | 'feDistantLight',
|
101 | 'feFlood',
|
102 | 'feFuncA',
|
103 | 'feFuncB',
|
104 | 'feFuncG',
|
105 | 'feFuncR',
|
106 | 'feGaussianBlur',
|
107 | 'feImage',
|
108 | 'feMerge',
|
109 | 'feMergeNode',
|
110 | 'feMorphology',
|
111 | 'feOffset',
|
112 | 'fePointLight',
|
113 | 'feSpecularLighting',
|
114 | 'feSpotLight',
|
115 | 'feTile',
|
116 | 'feTurbulence',
|
117 | 'foreignObject',
|
118 | 'glyphRef',
|
119 | 'linearGradient',
|
120 | 'radialGradient',
|
121 | 'textPath',
|
122 | ].map((tn) => [tn.toLowerCase(), tn]));
|
123 |
|
124 | const EXITS_FOREIGN_CONTENT = new Set([
|
125 | $.B,
|
126 | $.BIG,
|
127 | $.BLOCKQUOTE,
|
128 | $.BODY,
|
129 | $.BR,
|
130 | $.CENTER,
|
131 | $.CODE,
|
132 | $.DD,
|
133 | $.DIV,
|
134 | $.DL,
|
135 | $.DT,
|
136 | $.EM,
|
137 | $.EMBED,
|
138 | $.H1,
|
139 | $.H2,
|
140 | $.H3,
|
141 | $.H4,
|
142 | $.H5,
|
143 | $.H6,
|
144 | $.HEAD,
|
145 | $.HR,
|
146 | $.I,
|
147 | $.IMG,
|
148 | $.LI,
|
149 | $.LISTING,
|
150 | $.MENU,
|
151 | $.META,
|
152 | $.NOBR,
|
153 | $.OL,
|
154 | $.P,
|
155 | $.PRE,
|
156 | $.RUBY,
|
157 | $.S,
|
158 | $.SMALL,
|
159 | $.SPAN,
|
160 | $.STRONG,
|
161 | $.STRIKE,
|
162 | $.SUB,
|
163 | $.SUP,
|
164 | $.TABLE,
|
165 | $.TT,
|
166 | $.U,
|
167 | $.UL,
|
168 | $.VAR,
|
169 | ]);
|
170 |
|
171 | export function causesExit(startTagToken) {
|
172 | const tn = startTagToken.tagID;
|
173 | const isFontWithAttrs = tn === $.FONT &&
|
174 | startTagToken.attrs.some(({ name }) => name === ATTRS.COLOR || name === ATTRS.SIZE || name === ATTRS.FACE);
|
175 | return isFontWithAttrs || EXITS_FOREIGN_CONTENT.has(tn);
|
176 | }
|
177 |
|
178 | export function adjustTokenMathMLAttrs(token) {
|
179 | for (let i = 0; i < token.attrs.length; i++) {
|
180 | if (token.attrs[i].name === DEFINITION_URL_ATTR) {
|
181 | token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR;
|
182 | break;
|
183 | }
|
184 | }
|
185 | }
|
186 | export function adjustTokenSVGAttrs(token) {
|
187 | for (let i = 0; i < token.attrs.length; i++) {
|
188 | const adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name);
|
189 | if (adjustedAttrName != null) {
|
190 | token.attrs[i].name = adjustedAttrName;
|
191 | }
|
192 | }
|
193 | }
|
194 | export function adjustTokenXMLAttrs(token) {
|
195 | for (let i = 0; i < token.attrs.length; i++) {
|
196 | const adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name);
|
197 | if (adjustedAttrEntry) {
|
198 | token.attrs[i].prefix = adjustedAttrEntry.prefix;
|
199 | token.attrs[i].name = adjustedAttrEntry.name;
|
200 | token.attrs[i].namespace = adjustedAttrEntry.namespace;
|
201 | }
|
202 | }
|
203 | }
|
204 | export function adjustTokenSVGTagName(token) {
|
205 | const adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP.get(token.tagName);
|
206 | if (adjustedTagName != null) {
|
207 | token.tagName = adjustedTagName;
|
208 | token.tagID = getTagID(token.tagName);
|
209 | }
|
210 | }
|
211 |
|
212 | function isMathMLTextIntegrationPoint(tn, ns) {
|
213 | return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT);
|
214 | }
|
215 | function isHtmlIntegrationPoint(tn, ns, attrs) {
|
216 | if (ns === NS.MATHML && tn === $.ANNOTATION_XML) {
|
217 | for (let i = 0; i < attrs.length; i++) {
|
218 | if (attrs[i].name === ATTRS.ENCODING) {
|
219 | const value = attrs[i].value.toLowerCase();
|
220 | return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML;
|
221 | }
|
222 | }
|
223 | }
|
224 | return ns === NS.SVG && (tn === $.FOREIGN_OBJECT || tn === $.DESC || tn === $.TITLE);
|
225 | }
|
226 | export function isIntegrationPoint(tn, ns, attrs, foreignNS) {
|
227 | return (((!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs)) ||
|
228 | ((!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns)));
|
229 | }
|
230 |
|
\ | No newline at end of file |