Class: HTML5::Phase
- Inherits:
-
Object
show all
- Extended by:
- Forwardable
- Defined in:
- lib/html5/html5parser/phase.rb
Overview
Base class for helper objects that implement each phase of processing.
Handler methods should be in the following order (they can be omitted):
* EOF
* Comment
* Doctype
* SpaceCharacters
* Characters
* StartTag
- startTag* methods
* EndTag
- endTag* methods
Direct Known Subclasses
AfterBodyPhase, AfterFramesetPhase, AfterHeadPhase, BeforeHeadPhase, InBodyPhase, InCaptionPhase, InCellPhase, InColumnGroupPhase, InFramesetPhase, InHeadPhase, InRowPhase, InSelectPhase, InTableBodyPhase, InTablePhase, InitialPhase, RootElementPhase, TrailingEndPhase, XmlElementPhase, XmlRootPhase
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(parser, tree) ⇒ Phase
Returns a new instance of Phase.
82
83
84
|
# File 'lib/html5/html5parser/phase.rb', line 82
def initialize(parser, tree)
@parser, @tree = parser, tree
end
|
Class Method Details
.end_tag_handlers ⇒ Object
72
73
74
|
# File 'lib/html5/html5parser/phase.rb', line 72
def self.end_tag_handlers
@end_tag_handlers ||= Hash.new('endTagOther')
end
|
.handle_end(*tags) ⇒ Object
Declare what end tags this Phase handles. Behaves like handle_start.
78
79
80
|
# File 'lib/html5/html5parser/phase.rb', line 78
def self.handle_end(*tags)
end_tag_handlers.update tag_handlers('endTag', *tags)
end
|
.handle_start(*tags) ⇒ Object
Declare what start tags this Phase handles. Can be called more than once.
Example usage:
handle_start 'html'
handle_start %( base link meta )
handle_start %( li dt dd ) => 'ListItem'
68
69
70
|
# File 'lib/html5/html5parser/phase.rb', line 68
def self.handle_start(*tags)
start_tag_handlers.update tag_handlers('startTag', *tags)
end
|
.start_tag_handlers ⇒ Object
51
52
53
|
# File 'lib/html5/html5parser/phase.rb', line 51
def self.start_tag_handlers
@start_tag_handlers ||= Hash.new('startTagOther')
end
|
.tag_handlers(prefix, *tags) ⇒ Object
The following example call:
tag_handlers('startTag', 'html', %w( base link meta ), %w( li dt dd ) => 'ListItem')
…would return a hash equal to this:
{ 'html' => 'startTagHtml',
'base' => 'startTagBaseLinkMeta',
'link' => 'startTagBaseLinkMeta',
'meta' => 'startTagBaseLinkMeta',
'li' => 'startTagListItem',
'dt' => 'startTagListItem',
'dd' => 'startTagListItem' }
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/html5/html5parser/phase.rb', line 35
def self.tag_handlers(prefix, *tags)
mapping = {}
if tags.last.is_a?(Hash)
tags.pop.each do |names, handler_method_suffix|
handler_method = prefix + handler_method_suffix
Array(names).each {|name| mapping[name] = handler_method }
end
end
tags.each do |names|
names = Array(names)
handler_method = prefix + names.map {|name| name.capitalize }.join
names.each {|name| mapping[name] = handler_method }
end
mapping
end
|
Instance Method Details
#assert(value) ⇒ Object
137
138
139
|
# File 'lib/html5/html5parser/phase.rb', line 137
def assert(value)
throw AssertionError.new unless value
end
|
#in_scope?(*args) ⇒ Boolean
141
142
143
|
# File 'lib/html5/html5parser/phase.rb', line 141
def in_scope?(*args)
@tree.elementInScope(*args)
end
|
#process_eof ⇒ Object
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/html5/html5parser/phase.rb', line 86
def process_eof
@tree.generateImpliedEndTags
if @tree.open_elements.length > 2
parse_error("expected-closing-tag-but-got-eof")
elsif @tree.open_elements.length == 2 and @tree.open_elements[1].name != 'body'
parse_error("expected-closing-tag-but-got-eof")
elsif @parser.inner_html and @tree.open_elements.length > 1
parse_error("eof-in-innerhtml")
end
end
|
101
102
103
104
105
|
# File 'lib/html5/html5parser/phase.rb', line 101
def (data)
@tree.(data, @tree.open_elements.last)
end
|
#processDoctype(name, publicId, systemId, correct) ⇒ Object
107
108
109
|
# File 'lib/html5/html5parser/phase.rb', line 107
def processDoctype(name, publicId, systemId, correct)
parse_error("unexpected-doctype")
end
|
#processEndTag(name) ⇒ Object
133
134
135
|
# File 'lib/html5/html5parser/phase.rb', line 133
def processEndTag(name)
send self.class.end_tag_handlers[name], name
end
|
#processSpaceCharacters(data) ⇒ Object
111
112
113
|
# File 'lib/html5/html5parser/phase.rb', line 111
def processSpaceCharacters(data)
@tree.insertText(data)
end
|
#processStartTag(name, attributes) ⇒ Object
115
116
117
|
# File 'lib/html5/html5parser/phase.rb', line 115
def processStartTag(name, attributes)
send self.class.start_tag_handlers[name], name, attributes
end
|
#remove_open_elements_until(name = nil) ⇒ Object
145
146
147
148
149
150
151
152
|
# File 'lib/html5/html5parser/phase.rb', line 145
def remove_open_elements_until(name=nil)
finished = false
until finished
element = @tree.open_elements.pop
finished = name.nil? ? yield(element) : element.name == name
end
return element
end
|
#startTagHtml(name, attributes) ⇒ Object
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/html5/html5parser/phase.rb', line 119
def startTagHtml(name, attributes)
if @parser.first_start_tag == false and name == 'html'
parse_error("non-html-root")
end
attributes.each do |attr, value|
unless @tree.open_elements.first.attributes.has_key?(attr)
@tree.open_elements.first.attributes[attr] = value
end
end
@parser.first_start_tag = false
end
|