|
1 | 1 | from __future__ import absolute_import, division, unicode_literals |
2 | | -from six import with_metaclass |
| 2 | +from six import with_metaclass, viewkeys, PY3 |
3 | 3 |
|
4 | 4 | import types |
5 | 5 |
|
| 6 | +try: |
| 7 | + from collections import OrderedDict |
| 8 | +except ImportError: |
| 9 | + from ordereddict import OrderedDict |
| 10 | + |
6 | 11 | from . import inputstream |
7 | 12 | from . import tokenizer |
8 | 13 |
|
|
17 | 22 | namespaces, |
18 | 23 | htmlIntegrationPointElements, mathmlTextIntegrationPointElements, |
19 | 24 | adjustForeignAttributes as adjustForeignAttributesMap, |
| 25 | + adjustMathMLAttributes, adjustSVGAttributes, |
20 | 26 | E, |
21 | 27 | ReparseException |
22 | 28 | ) |
@@ -273,96 +279,18 @@ def normalizeToken(self, token): |
273 | 279 | """ HTML5 specific normalizations to the token stream """ |
274 | 280 |
|
275 | 281 | if token["type"] == tokenTypes["StartTag"]: |
276 | | - token["data"] = dict(token["data"][::-1]) |
| 282 | + token["data"] = OrderedDict(token['data'][::-1]) |
277 | 283 |
|
278 | 284 | return token |
279 | 285 |
|
280 | 286 | def adjustMathMLAttributes(self, token): |
281 | | - replacements = {"definitionurl": "definitionURL"} |
282 | | - for k, v in replacements.items(): |
283 | | - if k in token["data"]: |
284 | | - token["data"][v] = token["data"][k] |
285 | | - del token["data"][k] |
| 287 | + adjust_attributes(token, adjustMathMLAttributes) |
286 | 288 |
|
287 | 289 | def adjustSVGAttributes(self, token): |
288 | | - replacements = { |
289 | | - "attributename": "attributeName", |
290 | | - "attributetype": "attributeType", |
291 | | - "basefrequency": "baseFrequency", |
292 | | - "baseprofile": "baseProfile", |
293 | | - "calcmode": "calcMode", |
294 | | - "clippathunits": "clipPathUnits", |
295 | | - "contentscripttype": "contentScriptType", |
296 | | - "contentstyletype": "contentStyleType", |
297 | | - "diffuseconstant": "diffuseConstant", |
298 | | - "edgemode": "edgeMode", |
299 | | - "externalresourcesrequired": "externalResourcesRequired", |
300 | | - "filterres": "filterRes", |
301 | | - "filterunits": "filterUnits", |
302 | | - "glyphref": "glyphRef", |
303 | | - "gradienttransform": "gradientTransform", |
304 | | - "gradientunits": "gradientUnits", |
305 | | - "kernelmatrix": "kernelMatrix", |
306 | | - "kernelunitlength": "kernelUnitLength", |
307 | | - "keypoints": "keyPoints", |
308 | | - "keysplines": "keySplines", |
309 | | - "keytimes": "keyTimes", |
310 | | - "lengthadjust": "lengthAdjust", |
311 | | - "limitingconeangle": "limitingConeAngle", |
312 | | - "markerheight": "markerHeight", |
313 | | - "markerunits": "markerUnits", |
314 | | - "markerwidth": "markerWidth", |
315 | | - "maskcontentunits": "maskContentUnits", |
316 | | - "maskunits": "maskUnits", |
317 | | - "numoctaves": "numOctaves", |
318 | | - "pathlength": "pathLength", |
319 | | - "patterncontentunits": "patternContentUnits", |
320 | | - "patterntransform": "patternTransform", |
321 | | - "patternunits": "patternUnits", |
322 | | - "pointsatx": "pointsAtX", |
323 | | - "pointsaty": "pointsAtY", |
324 | | - "pointsatz": "pointsAtZ", |
325 | | - "preservealpha": "preserveAlpha", |
326 | | - "preserveaspectratio": "preserveAspectRatio", |
327 | | - "primitiveunits": "primitiveUnits", |
328 | | - "refx": "refX", |
329 | | - "refy": "refY", |
330 | | - "repeatcount": "repeatCount", |
331 | | - "repeatdur": "repeatDur", |
332 | | - "requiredextensions": "requiredExtensions", |
333 | | - "requiredfeatures": "requiredFeatures", |
334 | | - "specularconstant": "specularConstant", |
335 | | - "specularexponent": "specularExponent", |
336 | | - "spreadmethod": "spreadMethod", |
337 | | - "startoffset": "startOffset", |
338 | | - "stddeviation": "stdDeviation", |
339 | | - "stitchtiles": "stitchTiles", |
340 | | - "surfacescale": "surfaceScale", |
341 | | - "systemlanguage": "systemLanguage", |
342 | | - "tablevalues": "tableValues", |
343 | | - "targetx": "targetX", |
344 | | - "targety": "targetY", |
345 | | - "textlength": "textLength", |
346 | | - "viewbox": "viewBox", |
347 | | - "viewtarget": "viewTarget", |
348 | | - "xchannelselector": "xChannelSelector", |
349 | | - "ychannelselector": "yChannelSelector", |
350 | | - "zoomandpan": "zoomAndPan" |
351 | | - } |
352 | | - for originalName in list(token["data"].keys()): |
353 | | - if originalName in replacements: |
354 | | - svgName = replacements[originalName] |
355 | | - token["data"][svgName] = token["data"][originalName] |
356 | | - del token["data"][originalName] |
| 290 | + adjust_attributes(token, adjustSVGAttributes) |
357 | 291 |
|
358 | 292 | def adjustForeignAttributes(self, token): |
359 | | - replacements = adjustForeignAttributesMap |
360 | | - |
361 | | - for originalName in token["data"].keys(): |
362 | | - if originalName in replacements: |
363 | | - foreignName = replacements[originalName] |
364 | | - token["data"][foreignName] = token["data"][originalName] |
365 | | - del token["data"][originalName] |
| 293 | + adjust_attributes(token, adjustForeignAttributesMap) |
366 | 294 |
|
367 | 295 | def reparseTokenNormal(self, token): |
368 | 296 | # pylint:disable=unused-argument |
@@ -2791,6 +2719,16 @@ def processEndTag(self, token): |
2791 | 2719 | } |
2792 | 2720 |
|
2793 | 2721 |
|
| 2722 | +def adjust_attributes(token, replacements): |
| 2723 | + if PY3 or utils.PY27: |
| 2724 | + needs_adjustment = viewkeys(token['data']) & viewkeys(replacements) |
| 2725 | + else: |
| 2726 | + needs_adjustment = frozenset(token['data']) & frozenset(replacements) |
| 2727 | + if needs_adjustment: |
| 2728 | + token['data'] = OrderedDict((replacements.get(k, k), v) |
| 2729 | + for k, v in token['data'].items()) |
| 2730 | + |
| 2731 | + |
2794 | 2732 | def impliedTagToken(name, type="EndTag", attributes=None, |
2795 | 2733 | selfClosing=False): |
2796 | 2734 | if attributes is None: |
|
0 commit comments