spk-html5 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +10 -0
- data/Manifest.txt +73 -0
- data/README +45 -0
- data/Rakefile.rb +33 -0
- data/bin/html5 +7 -0
- data/lib/html5.rb +13 -0
- data/lib/html5/cli.rb +248 -0
- data/lib/html5/constants.rb +1061 -0
- data/lib/html5/filters/base.rb +10 -0
- data/lib/html5/filters/inject_meta_charset.rb +82 -0
- data/lib/html5/filters/iso639codes.rb +755 -0
- data/lib/html5/filters/optionaltags.rb +198 -0
- data/lib/html5/filters/rfc2046.rb +31 -0
- data/lib/html5/filters/rfc3987.rb +91 -0
- data/lib/html5/filters/sanitizer.rb +15 -0
- data/lib/html5/filters/validator.rb +834 -0
- data/lib/html5/filters/whitespace.rb +36 -0
- data/lib/html5/html5parser.rb +247 -0
- data/lib/html5/html5parser/after_after_body_phase.rb +43 -0
- data/lib/html5/html5parser/after_after_frameset_phase.rb +32 -0
- data/lib/html5/html5parser/after_body_phase.rb +46 -0
- data/lib/html5/html5parser/after_frameset_phase.rb +33 -0
- data/lib/html5/html5parser/after_head_phase.rb +55 -0
- data/lib/html5/html5parser/before_head_phase.rb +44 -0
- data/lib/html5/html5parser/before_html_phase.rb +41 -0
- data/lib/html5/html5parser/in_body_phase.rb +636 -0
- data/lib/html5/html5parser/in_caption_phase.rb +69 -0
- data/lib/html5/html5parser/in_cell_phase.rb +78 -0
- data/lib/html5/html5parser/in_column_group_phase.rb +55 -0
- data/lib/html5/html5parser/in_foreign_content_phase.rb +50 -0
- data/lib/html5/html5parser/in_frameset_phase.rb +56 -0
- data/lib/html5/html5parser/in_head_phase.rb +143 -0
- data/lib/html5/html5parser/in_row_phase.rb +96 -0
- data/lib/html5/html5parser/in_select_phase.rb +90 -0
- data/lib/html5/html5parser/in_select_table_phase.rb +35 -0
- data/lib/html5/html5parser/in_table_body_phase.rb +92 -0
- data/lib/html5/html5parser/in_table_phase.rb +177 -0
- data/lib/html5/html5parser/initial_phase.rb +133 -0
- data/lib/html5/html5parser/phase.rb +171 -0
- data/lib/html5/inputstream.rb +735 -0
- data/lib/html5/liberalxmlparser.rb +158 -0
- data/lib/html5/sanitizer.rb +209 -0
- data/lib/html5/serializer.rb +2 -0
- data/lib/html5/serializer/htmlserializer.rb +179 -0
- data/lib/html5/serializer/xhtmlserializer.rb +20 -0
- data/lib/html5/sniffer.rb +45 -0
- data/lib/html5/tokenizer.rb +1059 -0
- data/lib/html5/treebuilders.rb +24 -0
- data/lib/html5/treebuilders/base.rb +339 -0
- data/lib/html5/treebuilders/hpricot.rb +231 -0
- data/lib/html5/treebuilders/rexml.rb +215 -0
- data/lib/html5/treebuilders/simpletree.rb +191 -0
- data/lib/html5/treewalkers.rb +26 -0
- data/lib/html5/treewalkers/base.rb +162 -0
- data/lib/html5/treewalkers/hpricot.rb +48 -0
- data/lib/html5/treewalkers/rexml.rb +48 -0
- data/lib/html5/treewalkers/simpletree.rb +48 -0
- data/lib/html5/version.rb +3 -0
- data/test/preamble.rb +69 -0
- data/test/test_cli.rb +16 -0
- data/test/test_encoding.rb +35 -0
- data/test/test_input_stream.rb +26 -0
- data/test/test_lxp.rb +283 -0
- data/test/test_parser.rb +63 -0
- data/test/test_sanitizer.rb +173 -0
- data/test/test_serializer.rb +67 -0
- data/test/test_sniffer.rb +27 -0
- data/test/test_stream.rb +71 -0
- data/test/test_tokenizer.rb +95 -0
- data/test/test_treewalkers.rb +135 -0
- data/test/test_validator.rb +31 -0
- data/test/tokenizer_test_parser.rb +67 -0
- data/test19.rb +38 -0
- metadata +198 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'html5/html5parser/phase'
|
2
|
+
|
3
|
+
module HTML5
|
4
|
+
class InRowPhase < Phase
|
5
|
+
|
6
|
+
# http://www.whatwg.org/specs/web-apps/current-work/#in-row
|
7
|
+
|
8
|
+
handle_start 'html', %w( td th ) => 'TableCell', %w( caption col colgroup tbody tfoot thead tr ) => 'TableOther'
|
9
|
+
|
10
|
+
handle_end 'tr', 'table', %w( tbody tfoot thead ) => 'TableRowGroup', %w( body caption col colgroup html td th ) => 'Ignore'
|
11
|
+
|
12
|
+
def processCharacters(data)
|
13
|
+
@parser.phases[:inTable].processCharacters(data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def processSpaceCharacters(data)
|
17
|
+
@parser.phases[:inTable].processSpaceCharacters(data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def startTagTableCell(name, attributes)
|
21
|
+
clearStackToTableRowContext
|
22
|
+
@tree.insert_element(name, attributes)
|
23
|
+
@parser.phase = @parser.phases[:inCell]
|
24
|
+
@tree.activeFormattingElements.push(Marker)
|
25
|
+
end
|
26
|
+
|
27
|
+
def startTagTableOther(name, attributes)
|
28
|
+
ignoreEndTag = ignoreEndTagTr
|
29
|
+
endTagTr('tr')
|
30
|
+
# XXX how are we sure it's always ignored in the inner_html case?
|
31
|
+
@parser.phase.processStartTag(name, attributes) unless ignoreEndTag
|
32
|
+
end
|
33
|
+
|
34
|
+
def startTagOther(name, attributes)
|
35
|
+
@parser.phases[:inTable].processStartTag(name, attributes)
|
36
|
+
end
|
37
|
+
|
38
|
+
def endTagTr(name)
|
39
|
+
if ignoreEndTagTr
|
40
|
+
# inner_html case
|
41
|
+
assert @parser.inner_html
|
42
|
+
parse_error "unexpected-end-tag", {:name => name}
|
43
|
+
else
|
44
|
+
clearStackToTableRowContext
|
45
|
+
@tree.open_elements.pop
|
46
|
+
@parser.phase = @parser.phases[:inTableBody]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def endTagTable(name)
|
51
|
+
ignoreEndTag = ignoreEndTagTr
|
52
|
+
endTagTr('tr')
|
53
|
+
# Reprocess the current tag if the tr end tag was not ignored
|
54
|
+
# XXX how are we sure it's always ignored in the inner_html case?
|
55
|
+
@parser.phase.processEndTag(name) unless ignoreEndTag
|
56
|
+
end
|
57
|
+
|
58
|
+
def endTagTableRowGroup(name)
|
59
|
+
if in_scope?(name, true)
|
60
|
+
endTagTr('tr')
|
61
|
+
@parser.phase.processEndTag(name)
|
62
|
+
else
|
63
|
+
# inner_html case
|
64
|
+
parse_error "unexpected-end-tag", {:name => name}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def endTagIgnore(name)
|
69
|
+
parse_error("unexpected-end-tag-in-table-row",
|
70
|
+
{"name" => name})
|
71
|
+
end
|
72
|
+
|
73
|
+
def endTagOther(name)
|
74
|
+
@parser.phases[:inTable].processEndTag(name)
|
75
|
+
end
|
76
|
+
|
77
|
+
def process_eof
|
78
|
+
@parser.phases[:inTable].process_eof
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
# XXX unify this with other table helper methods
|
84
|
+
def clearStackToTableRowContext
|
85
|
+
until %w[tr html].include?(name = @tree.open_elements.last.name)
|
86
|
+
parse_error("unexpected-implied-end-tag-in-table-row", {"name" => @tree.open_elements.last.name})
|
87
|
+
@tree.open_elements.pop
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def ignoreEndTagTr
|
92
|
+
not in_scope?('tr', :tableVariant => true)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'html5/html5parser/phase'
|
2
|
+
|
3
|
+
module HTML5
|
4
|
+
class InSelectPhase < Phase
|
5
|
+
|
6
|
+
# http://www.whatwg.org/specs/web-apps/current-work/#in-select
|
7
|
+
|
8
|
+
handle_start 'html', 'option', 'optgroup', 'select'
|
9
|
+
handle_start 'input'
|
10
|
+
handle_end 'option', 'optgroup', 'select', %w( caption table tbody tfoot thead tr td th ) => 'TableElements'
|
11
|
+
|
12
|
+
def processCharacters(data)
|
13
|
+
@tree.insertText(data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def startTagOption(name, attributes)
|
17
|
+
# We need to imply </option> if <option> is the current node.
|
18
|
+
@tree.open_elements.pop if @tree.open_elements.last.name == 'option'
|
19
|
+
@tree.insert_element(name, attributes)
|
20
|
+
end
|
21
|
+
|
22
|
+
def startTagOptgroup(name, attributes)
|
23
|
+
@tree.open_elements.pop if @tree.open_elements.last.name == 'option'
|
24
|
+
@tree.open_elements.pop if @tree.open_elements.last.name == 'optgroup'
|
25
|
+
@tree.insert_element(name, attributes)
|
26
|
+
end
|
27
|
+
|
28
|
+
def startTagSelect(name, attributes)
|
29
|
+
parse_error("unexpected-select-in-select")
|
30
|
+
endTagSelect('select')
|
31
|
+
end
|
32
|
+
|
33
|
+
def startTagInput(name, attributes)
|
34
|
+
@parser.parse_error("unexpected-input-in-select")
|
35
|
+
endTagSelect("select")
|
36
|
+
@parser.phase.processStartTag(name, attributes)
|
37
|
+
end
|
38
|
+
|
39
|
+
def startTagOther(name, attributes)
|
40
|
+
parse_error("unexpected-start-tag-in-select", {"name" => name})
|
41
|
+
end
|
42
|
+
|
43
|
+
def endTagOption(name)
|
44
|
+
if @tree.open_elements.last.name == 'option'
|
45
|
+
@tree.open_elements.pop
|
46
|
+
else
|
47
|
+
parse_error("unexpected-end-tag-in-select", {"name" => "option"})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def endTagOptgroup(name)
|
52
|
+
# </optgroup> implicitly closes <option>
|
53
|
+
if @tree.open_elements.last.name == 'option' and @tree.open_elements[-2].name == 'optgroup'
|
54
|
+
@tree.open_elements.pop
|
55
|
+
end
|
56
|
+
# It also closes </optgroup>
|
57
|
+
if @tree.open_elements.last.name == 'optgroup'
|
58
|
+
@tree.open_elements.pop
|
59
|
+
# But nothing else
|
60
|
+
else
|
61
|
+
parse_error("unexpected-end-tag-in-select",
|
62
|
+
{"name" => "optgroup"})
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def endTagSelect(name)
|
67
|
+
if in_scope?('select', true)
|
68
|
+
remove_open_elements_until('select')
|
69
|
+
|
70
|
+
@parser.reset_insertion_mode
|
71
|
+
else
|
72
|
+
# inner_html case
|
73
|
+
parse_error
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def endTagTableElements(name)
|
78
|
+
parse_error("unexpected-end-tag-in-select", {"name" => name})
|
79
|
+
|
80
|
+
if in_scope?(name, true)
|
81
|
+
endTagSelect('select')
|
82
|
+
@parser.phase.processEndTag(name)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def endTagOther(name)
|
87
|
+
parse_error("unexpected-end-tag-in-select", {"name" => name})
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'html5/html5parser/phase'
|
2
|
+
|
3
|
+
module HTML5
|
4
|
+
class InSelectInTablePhase < Phase
|
5
|
+
|
6
|
+
handle_start %w(caption table tbody tfoot thead tr td th) => 'Table'
|
7
|
+
handle_end %w(caption table tbody tfoot thead tr td th) => 'Table'
|
8
|
+
|
9
|
+
def processCharacters(data)
|
10
|
+
@parser.phases[:inSelect].processCharacters(data)
|
11
|
+
end
|
12
|
+
|
13
|
+
def startTagTable(name, attributes)
|
14
|
+
@parser.parse_error("unexpected-table-element-start-tag-in-select-in-table", {:name => name})
|
15
|
+
endTagOther("select")
|
16
|
+
@parser.phase.processStartTag(name, attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
def startTagOther(name, attributes)
|
20
|
+
@parser.phases[:inSelect].processStartTag(name, attributes)
|
21
|
+
end
|
22
|
+
|
23
|
+
def endTagTable(name)
|
24
|
+
@parser.parse_error("unexpected-table-element-end-tag-in-select-in-table", {:name => name})
|
25
|
+
if @tree.elementInScope(name, true)
|
26
|
+
endTagOther("select")
|
27
|
+
@parser.phase.processEndTag(name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def endTagOther(name)
|
32
|
+
@parser.phases[:inSelect].processEndTag(name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'html5/html5parser/phase'
|
2
|
+
|
3
|
+
module HTML5
|
4
|
+
class InTableBodyPhase < Phase
|
5
|
+
|
6
|
+
# http://www.whatwg.org/specs/web-apps/current-work/#in-table0
|
7
|
+
|
8
|
+
handle_start 'html', 'tr', %w( td th ) => 'TableCell', %w( caption col colgroup tbody tfoot thead ) => 'TableOther'
|
9
|
+
|
10
|
+
handle_end 'table', %w( tbody tfoot thead ) => 'TableRowGroup', %w( body caption col colgroup html td th tr ) => 'Ignore'
|
11
|
+
|
12
|
+
def processCharacters(data)
|
13
|
+
@parser.phases[:inTable].processCharacters(data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def processSpaceCharacters(data)
|
17
|
+
@parser.phases[:inTable].processSpaceCharacters(data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_eof
|
21
|
+
@parser.phases[:inTable].process_eof
|
22
|
+
end
|
23
|
+
|
24
|
+
def startTagTr(name, attributes)
|
25
|
+
clearStackToTableBodyContext
|
26
|
+
@tree.insert_element(name, attributes)
|
27
|
+
@parser.phase = @parser.phases[:inRow]
|
28
|
+
end
|
29
|
+
|
30
|
+
def startTagTableCell(name, attributes)
|
31
|
+
parse_error("unexpected-cell-in-table-body", {"name" => name})
|
32
|
+
startTagTr('tr', {})
|
33
|
+
@parser.phase.processStartTag(name, attributes)
|
34
|
+
end
|
35
|
+
|
36
|
+
def startTagTableOther(name, attributes)
|
37
|
+
# XXX AT Any ideas on how to share this with endTagTable?
|
38
|
+
if in_scope?('tbody', true) or in_scope?('thead', true) or in_scope?('tfoot', true)
|
39
|
+
clearStackToTableBodyContext
|
40
|
+
endTagTableRowGroup(@tree.open_elements.last.name)
|
41
|
+
@parser.phase.processStartTag(name, attributes)
|
42
|
+
else
|
43
|
+
# inner_html case
|
44
|
+
parse_error "unexpected-start-tag", {:name => name}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def startTagOther(name, attributes)
|
49
|
+
@parser.phases[:inTable].processStartTag(name, attributes)
|
50
|
+
end
|
51
|
+
|
52
|
+
def endTagTableRowGroup(name)
|
53
|
+
if in_scope?(name, true)
|
54
|
+
clearStackToTableBodyContext
|
55
|
+
@tree.open_elements.pop
|
56
|
+
@parser.phase = @parser.phases[:inTable]
|
57
|
+
else
|
58
|
+
parse_error("unexpected-end-tag-in-table-body", {"name" => name})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def endTagTable(name)
|
63
|
+
if in_scope?('tbody', true) or in_scope?('thead', true) or in_scope?('tfoot', true)
|
64
|
+
clearStackToTableBodyContext
|
65
|
+
endTagTableRowGroup(@tree.open_elements.last.name)
|
66
|
+
@parser.phase.processEndTag(name)
|
67
|
+
else
|
68
|
+
# inner_html case
|
69
|
+
parse_error "unexpected-end-tag", {:name => name}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def endTagIgnore(name)
|
74
|
+
parse_error("unexpected-end-tag-in-table-body", {"name" => name})
|
75
|
+
end
|
76
|
+
|
77
|
+
def endTagOther(name)
|
78
|
+
@parser.phases[:inTable].processEndTag(name)
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
def clearStackToTableBodyContext
|
84
|
+
until %w[tbody tfoot thead html].include?(name = @tree.open_elements.last.name)
|
85
|
+
parse_error("unexpected-implied-end-tag-in-table",
|
86
|
+
{"name" => @tree.open_elements.last.name})
|
87
|
+
@tree.open_elements.pop
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'html5/html5parser/phase'
|
2
|
+
|
3
|
+
module HTML5
|
4
|
+
class InTablePhase < Phase
|
5
|
+
|
6
|
+
# http://www.whatwg.org/specs/web-apps/current-work/#in-table
|
7
|
+
|
8
|
+
handle_start 'html', 'caption', 'colgroup', 'col', 'table'
|
9
|
+
|
10
|
+
handle_start %w( tbody tfoot thead ) => 'RowGroup', %w( td th tr ) => 'ImplyTbody'
|
11
|
+
|
12
|
+
handle_start %w(style script)
|
13
|
+
|
14
|
+
handle_start 'input'
|
15
|
+
|
16
|
+
handle_end 'table', %w( body caption col colgroup html tbody td tfoot th thead tr ) => 'Ignore'
|
17
|
+
|
18
|
+
def processSpaceCharacters(data)
|
19
|
+
if !current_table.flags.include?("tainted")
|
20
|
+
@tree.insertText(data)
|
21
|
+
else
|
22
|
+
processCharacters(data)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def processCharacters(data)
|
27
|
+
if ["style", "script"].include?(@tree.open_elements.last.name)
|
28
|
+
@tree.insertText(data)
|
29
|
+
else
|
30
|
+
if !current_table.flags.include?("tainted")
|
31
|
+
@parser.parse_error("unexpected-char-implies-table-voodoo")
|
32
|
+
current_table.flags << "tainted"
|
33
|
+
end
|
34
|
+
# Do the table magic!
|
35
|
+
@tree.insert_from_table = true
|
36
|
+
@parser.phases[:inBody].processCharacters(data)
|
37
|
+
@tree.insert_from_table = false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def process_eof
|
42
|
+
if @tree.open_elements.last.name != "html"
|
43
|
+
@parser.parse_error("eof-in-table")
|
44
|
+
else
|
45
|
+
assert @parser.innerHTML
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def startTagCaption(name, attributes)
|
50
|
+
clear_stack_to_table_context
|
51
|
+
@tree.activeFormattingElements.push(Marker)
|
52
|
+
@tree.insert_element(name, attributes)
|
53
|
+
@parser.phase = @parser.phases[:inCaption]
|
54
|
+
end
|
55
|
+
|
56
|
+
def startTagColgroup(name, attributes)
|
57
|
+
clear_stack_to_table_context
|
58
|
+
@tree.insert_element(name, attributes)
|
59
|
+
@parser.phase = @parser.phases[:inColumnGroup]
|
60
|
+
end
|
61
|
+
|
62
|
+
def startTagCol(name, attributes)
|
63
|
+
startTagColgroup('colgroup', {})
|
64
|
+
@parser.phase.processStartTag(name, attributes)
|
65
|
+
end
|
66
|
+
|
67
|
+
def startTagRowGroup(name, attributes)
|
68
|
+
clear_stack_to_table_context
|
69
|
+
@tree.insert_element(name, attributes)
|
70
|
+
@parser.phase = @parser.phases[:inTableBody]
|
71
|
+
end
|
72
|
+
|
73
|
+
def startTagImplyTbody(name, attributes)
|
74
|
+
startTagRowGroup('tbody', {})
|
75
|
+
@parser.phase.processStartTag(name, attributes)
|
76
|
+
end
|
77
|
+
|
78
|
+
def startTagTable(name, attributes)
|
79
|
+
parse_error("unexpected-start-tag-implies-end-tag",
|
80
|
+
{"startName" => "table", "endName" => "table"})
|
81
|
+
@parser.phase.processEndTag('table')
|
82
|
+
@parser.phase.processStartTag(name, attributes) unless @parser.inner_html
|
83
|
+
end
|
84
|
+
|
85
|
+
def startTagOther(name, attributes)
|
86
|
+
@parser.parse_error("unexpected-start-tag-implies-table-voodoo", {:name => name})
|
87
|
+
if !current_table.flags.include?("tainted")
|
88
|
+
current_table.flags.push("tainted")
|
89
|
+
end
|
90
|
+
@tree.insert_from_table = true
|
91
|
+
# Process the start tag in the "in body" mode
|
92
|
+
@parser.phases[:inBody].processStartTag(name, attributes)
|
93
|
+
@tree.insert_from_table = false
|
94
|
+
end
|
95
|
+
|
96
|
+
def startTagStyleScript(name, attributes)
|
97
|
+
if !current_table.flags.include?("tainted")
|
98
|
+
@parser.phases[:inHead].processStartTag(name, attributes)
|
99
|
+
else
|
100
|
+
startTagOther(name, attributes)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def startTagInput(name, attributes)
|
105
|
+
if attributes.include?("type") &&
|
106
|
+
attributes["type"].downcase == "hidden" &&
|
107
|
+
!current_table.flags.include?("tainted")
|
108
|
+
@parser.parse_error("unpexted-hidden-input-in-table")
|
109
|
+
@tree.insert_element(name, attributes)
|
110
|
+
# XXX associate with form
|
111
|
+
@tree.open_elements.pop
|
112
|
+
else
|
113
|
+
self.startTagOther(name, attributes)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def endTagTable(name)
|
118
|
+
if in_scope?('table', true)
|
119
|
+
@tree.generateImpliedEndTags
|
120
|
+
|
121
|
+
unless @tree.open_elements.last.name == 'table'
|
122
|
+
parse_error("end-tag-too-early-named",
|
123
|
+
{"gotName" => "table",
|
124
|
+
"expectedName" => @tree.open_elements.last.name})
|
125
|
+
end
|
126
|
+
|
127
|
+
remove_open_elements_until('table')
|
128
|
+
|
129
|
+
@parser.reset_insertion_mode
|
130
|
+
else
|
131
|
+
# inner_html case
|
132
|
+
assert @parser.inner_html
|
133
|
+
parse_error "unexpected-end-tag", {:name => name}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def endTagIgnore(name)
|
138
|
+
parse_error("unexpected-end-tag", {"name" => name})
|
139
|
+
end
|
140
|
+
|
141
|
+
def endTagOther(name)
|
142
|
+
parse_error("unexpected-end-tag-implies-table-voodoo", {"name" => name})
|
143
|
+
# Make all the special element rearranging voodoo kick in
|
144
|
+
@tree.insert_from_table = true
|
145
|
+
# Process the end tag in the "in body" mode
|
146
|
+
@parser.phases[:inBody].processEndTag(name)
|
147
|
+
@tree.insert_from_table = false
|
148
|
+
end
|
149
|
+
|
150
|
+
def endStyleScript name
|
151
|
+
if !current_table().flags.include?("tainted")
|
152
|
+
@parser.phases[:inHead].processEndTag(name)
|
153
|
+
else
|
154
|
+
endTagOther(name)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
def clear_stack_to_table_context
|
161
|
+
# "clear the stack back to a table context"
|
162
|
+
until %w[table html].include?(name = @tree.open_elements.last.name)
|
163
|
+
parse_error("unexpected-implied-end-tag-in-table",
|
164
|
+
{"name" => @tree.open_elements.last.name})
|
165
|
+
@tree.open_elements.pop
|
166
|
+
end
|
167
|
+
# When the current node is <html> it's an inner_html case
|
168
|
+
end
|
169
|
+
|
170
|
+
def current_table
|
171
|
+
i = -1
|
172
|
+
i -= 1 while @tree.open_elements[i].name != "table"
|
173
|
+
@tree.open_elements[i]
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|