@@ -461,6 +461,12 @@ def wrapped(self, *args, **kwargs):
461
461
return function (self , * args , ** kwargs )
462
462
return wrapped
463
463
464
+ def getMetaclass (use_metaclass , metaclass_func ):
465
+ if use_metaclass :
466
+ return method_decorator_metaclass (metaclass_func )
467
+ else :
468
+ return type
469
+
464
470
class Phase (object ):
465
471
"""Base class for helper object that implements each phase of processing
466
472
"""
@@ -475,8 +481,7 @@ class Phase(object):
475
481
# * EndTag
476
482
# - endTag* methods
477
483
478
- if debug_log :
479
- __metaclass__ = method_decorator_metaclass (log )
484
+ __metaclass__ = getMetaclass (debug_log , log )
480
485
481
486
def __init__ (self , parser , tree ):
482
487
self .parser = parser
@@ -851,6 +856,9 @@ def processCharacters(self, token):
851
856
self .anythingElse ()
852
857
self .parser .phase .processCharacters (token )
853
858
859
+ def startTagHtml (self , token ):
860
+ self .parser .phases ["inBody" ].processStartTag (token )
861
+
854
862
def startTagBody (self , token ):
855
863
self .parser .framesetOK = False
856
864
self .tree .insertElement (token )
@@ -956,7 +964,7 @@ def __init__(self, parser, tree):
956
964
(headingElements , self .endTagHeading ),
957
965
(("a" , "b" , "big" , "code" , "em" , "font" , "i" , "nobr" , "s" , "small" ,
958
966
"strike" , "strong" , "tt" , "u" ), self .endTagFormatting ),
959
- (("applet" , "button" , "marquee" , "object" ), self .endTagAppletButtonMarqueeObject ),
967
+ (("applet" , "marquee" , "object" ), self .endTagAppletMarqueeObject ),
960
968
("br" , self .endTagBr ),
961
969
])
962
970
self .endTagHandler .default = self .endTagOther
@@ -1120,7 +1128,6 @@ def startTagButton(self, token):
1120
1128
else :
1121
1129
self .tree .reconstructActiveFormattingElements ()
1122
1130
self .tree .insertElement (token )
1123
- self .tree .activeFormattingElements .append (Marker )
1124
1131
self .parser .framesetOK = False
1125
1132
1126
1133
def startTagAppletMarqueeObject (self , token ):
@@ -1395,10 +1402,9 @@ def endTagFormatting(self, token):
1395
1402
# Step 1 paragraph 1
1396
1403
formattingElement = self .tree .elementInActiveFormattingElements (
1397
1404
token ["name" ])
1398
- if not formattingElement or (formattingElement in
1399
- self .tree .openElements and
1400
- not self .tree .elementInScope (
1401
- formattingElement .name )):
1405
+ if (not formattingElement or
1406
+ (formattingElement in self .tree .openElements and
1407
+ not self .tree .elementInScope (formattingElement .name ))):
1402
1408
self .parser .parseError ("adoption-agency-1.1" , {"name" : token ["name" ]})
1403
1409
return
1404
1410
@@ -1421,7 +1427,6 @@ def endTagFormatting(self, token):
1421
1427
specialElements | scopingElements ):
1422
1428
furthestBlock = element
1423
1429
break
1424
-
1425
1430
# Step 3
1426
1431
if furthestBlock is None :
1427
1432
element = self .tree .openElements .pop ()
@@ -1487,7 +1492,12 @@ def endTagFormatting(self, token):
1487
1492
# lastNode
1488
1493
if lastNode .parent :
1489
1494
lastNode .parent .removeChild (lastNode )
1490
- commonAncestor .appendChild (lastNode )
1495
+
1496
+ if commonAncestor .name in frozenset (("table" , "tbody" , "tfoot" , "thead" , "tr" )):
1497
+ parent , insertBefore = self .tree .getTableMisnestedNodePosition ()
1498
+ parent .insertBefore (lastNode , insertBefore )
1499
+ else :
1500
+ commonAncestor .appendChild (lastNode )
1491
1501
1492
1502
# Step 8
1493
1503
clone = formattingElement .cloneNode ()
@@ -1507,7 +1517,7 @@ def endTagFormatting(self, token):
1507
1517
self .tree .openElements .insert (
1508
1518
self .tree .openElements .index (furthestBlock ) + 1 , clone )
1509
1519
1510
- def endTagAppletButtonMarqueeObject (self , token ):
1520
+ def endTagAppletMarqueeObject (self , token ):
1511
1521
if self .tree .elementInScope (token ["name" ]):
1512
1522
self .tree .generateImpliedEndTags ()
1513
1523
if self .tree .openElements [- 1 ].name != token ["name" ]:
@@ -1532,7 +1542,6 @@ def endTagOther(self, token):
1532
1542
self .tree .generateImpliedEndTags (exclude = token ["name" ])
1533
1543
if self .tree .openElements [- 1 ].name != token ["name" ]:
1534
1544
self .parser .parseError ("unexpected-end-tag" , {"name" : token ["name" ]})
1535
- print self .tree .openElements
1536
1545
while self .tree .openElements .pop () != node :
1537
1546
pass
1538
1547
break
@@ -1957,6 +1966,7 @@ def startTagTableOther(self, token):
1957
1966
self .parser .phase .processStartTag (token )
1958
1967
else :
1959
1968
# innerHTML case
1969
+ assert self .parser .innerHTML
1960
1970
self .parser .parseError ()
1961
1971
1962
1972
def startTagOther (self , token ):
@@ -1981,6 +1991,7 @@ def endTagTable(self, token):
1981
1991
self .parser .phase .processEndTag (token )
1982
1992
else :
1983
1993
# innerHTML case
1994
+ assert self .parser .innerHTML
1984
1995
self .parser .parseError ()
1985
1996
1986
1997
def endTagIgnore (self , token ):
@@ -2072,6 +2083,7 @@ def endTagTableRowGroup(self, token):
2072
2083
self .parser .phase .processEndTag (token )
2073
2084
else :
2074
2085
# innerHTML case
2086
+ assert self .parser .innerHTML
2075
2087
self .parser .parseError ()
2076
2088
2077
2089
def endTagIgnore (self , token ):
@@ -2120,6 +2132,7 @@ def startTagTableOther(self, token):
2120
2132
self .parser .phase .processStartTag (token )
2121
2133
else :
2122
2134
# innerHTML case
2135
+ assert self .parser .innerHTML
2123
2136
self .parser .parseError ()
2124
2137
2125
2138
def startTagOther (self , token ):
@@ -2181,9 +2194,7 @@ def __init__(self, parser, tree):
2181
2194
self .endTagHandler = utils .MethodDispatcher ([
2182
2195
("option" , self .endTagOption ),
2183
2196
("optgroup" , self .endTagOptgroup ),
2184
- ("select" , self .endTagSelect ),
2185
- (("caption" , "table" , "tbody" , "tfoot" , "thead" , "tr" , "td" ,
2186
- "th" ), self .endTagTableElements )
2197
+ ("select" , self .endTagSelect )
2187
2198
])
2188
2199
self .endTagHandler .default = self .endTagOther
2189
2200
@@ -2255,15 +2266,9 @@ def endTagSelect(self, token):
2255
2266
self .parser .resetInsertionMode ()
2256
2267
else :
2257
2268
# innerHTML case
2269
+ assert self .parser .innerHTML
2258
2270
self .parser .parseError ()
2259
2271
2260
- def endTagTableElements (self , token ):
2261
- self .parser .parseError ("unexpected-end-tag-in-select" ,
2262
- {"name" : token ["name" ]})
2263
- if self .tree .elementInScope (token ["name" ], variant = "table" ):
2264
- self .endTagSelect ("select" )
2265
- self .parser .phase .processEndTag (token )
2266
-
2267
2272
def endTagOther (self , token ):
2268
2273
self .parser .parseError ("unexpected-end-tag-in-select" ,
2269
2274
{"name" : token ["name" ]})
@@ -2322,16 +2327,13 @@ def __init__(self, parser, tree):
2322
2327
Phase .__init__ (self , parser , tree )
2323
2328
2324
2329
def nonHTMLElementInScope (self ):
2330
+ rv = False
2325
2331
for element in self .tree .openElements [::- 1 ]:
2326
- if element .namespace == self .tree .defaultNamespace :
2327
- return self .tree .elementInScope (element )
2328
- assert False
2329
- for item in self .tree .openElements [::- 1 ]:
2330
- if item .namespace == self .tree .defaultNamespace :
2331
- return True
2332
- elif item .nameTuple in scopingElements :
2333
- return False
2334
- return False
2332
+ if element .namespace != self .tree .defaultNamespace :
2333
+ rv = self .tree .elementInScope (element .name )
2334
+ if rv :
2335
+ break
2336
+ return rv
2335
2337
2336
2338
def adjustSVGTagNames (self , token ):
2337
2339
replacements = {"altglyph" :"altGlyph" ,
@@ -2383,21 +2385,23 @@ def processEOF(self):
2383
2385
2384
2386
def processStartTag (self , token ):
2385
2387
currentNode = self .tree .openElements [- 1 ]
2386
- if (currentNode .namespace == self .tree .defaultNamespace or
2387
- (currentNode .namespace == namespaces ["mathml" ] and
2388
+ currentNodeNamespace = currentNode .namespace
2389
+ currentNodeName = currentNode .name
2390
+ if (currentNodeNamespace == self .tree .defaultNamespace or
2391
+ (currentNodeNamespace == namespaces ["mathml" ] and
2388
2392
token ["name" ] not in frozenset (["mglyph" , "malignmark" ]) and
2389
- currentNode . name in frozenset (["mi" , "mo" , "mn" ,
2393
+ currentNodeName in frozenset (["mi" , "mo" , "mn" ,
2390
2394
"ms" , "mtext" ])) or
2391
- (currentNode . namespace == namespaces ["mathml" ] and
2392
- currentNode . name == "annotation-xml" and
2395
+ (currentNodeNamespace == namespaces ["mathml" ] and
2396
+ currentNodeName == "annotation-xml" and
2393
2397
token ["name" ] == "svg" ) or
2394
2398
(currentNode .namespace == namespaces ["svg" ] and
2395
2399
currentNode .name in frozenset (["foreignObject" ,
2396
2400
"desc" , "title" ])
2397
2401
)):
2398
2402
assert self .parser .secondaryPhase != self
2399
2403
self .parser .secondaryPhase .processStartTag (token )
2400
- if self .parser .phase == self and self .nonHTMLElementInScope ():
2404
+ if self .parser .phase == self and not self .nonHTMLElementInScope ():
2401
2405
self .parser .phase = self .parser .secondaryPhase
2402
2406
elif token ["name" ] in self .breakoutElements :
2403
2407
self .parser .parseError ("unexpected-html-element-in-foreign-content" ,
@@ -2421,10 +2425,34 @@ def processStartTag(self, token):
2421
2425
token ["selfClosingAcknowledged" ] = True
2422
2426
2423
2427
def processEndTag (self , token ):
2424
- self .adjustSVGTagNames (token )
2425
- self .parser .secondaryPhase .processEndTag (token )
2426
- if self .parser .phase == self and self .nonHTMLElementInScope ():
2427
- self .parser .phase = self .parser .secondaryPhase
2428
+ if self .tree .openElements [- 1 ].namespace != self .tree .defaultNamespace :
2429
+ nodeIndex = len (self .tree .openElements ) - 1
2430
+ node = self .tree .openElements [- 1 ]
2431
+ if node .name != token ["name" ]:
2432
+ self .parser .parseError ("unexpected-end-tag" , token ["name" ])
2433
+
2434
+ while True :
2435
+ if node .name == token ["name" ]:
2436
+ popped = self .tree .openElements .pop ()
2437
+ while popped != node :
2438
+ popped = self .tree .openElements .pop ()
2439
+ assert self .tree .openElements
2440
+ break
2441
+ nodeIndex -= 1
2442
+
2443
+ node = self .tree .openElements [nodeIndex ]
2444
+ if node .namespace == self .tree .defaultNamespace :
2445
+ assert self .parser .secondaryPhase != self
2446
+ self .parser .secondaryPhase .processEndTag (token )
2447
+ if self .parser .phase == self and not self .nonHTMLElementInScope ():
2448
+ self .parser .phase = self .parser .secondaryPhase
2449
+ break
2450
+
2451
+ else :
2452
+ assert self .parser .secondaryPhase != self
2453
+ self .parser .secondaryPhase .processEndTag (token )
2454
+ if self .parser .phase == self and not self .nonHTMLElementInScope ():
2455
+ self .parser .phase = self .parser .secondaryPhase
2428
2456
2429
2457
class AfterBodyPhase (Phase ):
2430
2458
def __init__ (self , parser , tree ):
@@ -2487,8 +2515,7 @@ def __init__(self, parser, tree):
2487
2515
self .startTagHandler .default = self .startTagOther
2488
2516
2489
2517
self .endTagHandler = utils .MethodDispatcher ([
2490
- ("frameset" , self .endTagFrameset ),
2491
- ("noframes" , self .endTagNoframes )
2518
+ ("frameset" , self .endTagFrameset )
2492
2519
])
2493
2520
self .endTagHandler .default = self .endTagOther
2494
2521
@@ -2527,9 +2554,6 @@ def endTagFrameset(self, token):
2527
2554
# "frameset" element (anymore) then switch.
2528
2555
self .parser .phase = self .parser .phases ["afterFrameset" ]
2529
2556
2530
- def endTagNoframes (self , token ):
2531
- self .parser .phases ["inBody" ].processEndTag (token )
2532
-
2533
2557
def endTagOther (self , token ):
2534
2558
self .parser .parseError ("unexpected-end-tag-in-frameset" ,
2535
2559
{"name" : token ["name" ]})
@@ -2632,8 +2656,6 @@ def processSpaceCharacters(self, token):
2632
2656
2633
2657
def processCharacters (self , token ):
2634
2658
self .parser .parseError ("expected-eof-but-got-char" )
2635
- self .parser .phase = self .parser .phases ["inBody" ]
2636
- self .parser .phase .processCharacters (token )
2637
2659
2638
2660
def startTagHtml (self , token ):
2639
2661
self .parser .phases ["inBody" ].processStartTag (token )
@@ -2644,14 +2666,10 @@ def startTagNoFrames(self, token):
2644
2666
def startTagOther (self , token ):
2645
2667
self .parser .parseError ("expected-eof-but-got-start-tag" ,
2646
2668
{"name" : token ["name" ]})
2647
- self .parser .phase = self .parser .phases ["inBody" ]
2648
- self .parser .phase .processStartTag (token )
2649
2669
2650
2670
def processEndTag (self , token ):
2651
2671
self .parser .parseError ("expected-eof-but-got-end-tag" ,
2652
2672
{"name" : token ["name" ]})
2653
- self .parser .phase = self .parser .phases ["inBody" ]
2654
- self .parser .phase .processEndTag (token )
2655
2673
2656
2674
def impliedTagToken (name , type = "EndTag" , attributes = None ,
2657
2675
selfClosing = False ):
0 commit comments