|
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