| Class | HTML5::Phase |
| In: |
lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb
|
| Parent: | Object |
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
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 72
72: def self.end_tag_handlers
73: @end_tag_handlers ||= Hash.new('endTagOther')
74: end
Declare what end tags this Phase handles. Behaves like handle_start.
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 78
78: def self.handle_end(*tags)
79: end_tag_handlers.update tag_handlers('endTag', *tags)
80: end
Declare what start tags this Phase handles. Can be called more than once.
Example usage:
handle_start 'html' # html start tags will be handled by a method named 'startTagHtml' handle_start %( base link meta ) # base, link and meta start tags will be handled by a method named 'startTagBaseLinkMeta' handle_start %( li dt dd ) => 'ListItem' # li, dt, and dd start tags will be handled by a method named 'startTagListItem'
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 68
68: def self.handle_start(*tags)
69: start_tag_handlers.update tag_handlers('startTag', *tags)
70: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 82
82: def initialize(parser, tree)
83: @parser, @tree = parser, tree
84: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 51
51: def self.start_tag_handlers
52: @start_tag_handlers ||= Hash.new('startTagOther')
53: end
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' }
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 35
35: def self.tag_handlers(prefix, *tags)
36: mapping = {}
37: if tags.last.is_a?(Hash)
38: tags.pop.each do |names, handler_method_suffix|
39: handler_method = prefix + handler_method_suffix
40: Array(names).each {|name| mapping[name] = handler_method }
41: end
42: end
43: tags.each do |names|
44: names = Array(names)
45: handler_method = prefix + names.map {|name| name.capitalize }.join
46: names.each {|name| mapping[name] = handler_method }
47: end
48: mapping
49: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 137
137: def assert(value)
138: throw AssertionError.new unless value
139: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 141
141: def in_scope?(*args)
142: @tree.elementInScope(*args)
143: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 101
101: def processComment(data)
102: # For most phases the following is correct. Where it's not it will be
103: # overridden.
104: @tree.insert_comment(data, @tree.open_elements.last)
105: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 107
107: def processDoctype(name, publicId, systemId, correct)
108: parse_error("unexpected-doctype")
109: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 133
133: def processEndTag(name)
134: send self.class.end_tag_handlers[name], name
135: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 111
111: def processSpaceCharacters(data)
112: @tree.insertText(data)
113: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 115
115: def processStartTag(name, attributes)
116: send self.class.start_tag_handlers[name], name, attributes
117: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 86
86: def process_eof
87: @tree.generateImpliedEndTags
88:
89: if @tree.open_elements.length > 2
90: parse_error("expected-closing-tag-but-got-eof")
91: elsif @tree.open_elements.length == 2 and @tree.open_elements[1].name != 'body'
92: # This happens for framesets or something?
93: parse_error("expected-closing-tag-but-got-eof")
94: elsif @parser.inner_html and @tree.open_elements.length > 1
95: # XXX This is not what the specification says. Not sure what to do here.
96: parse_error("eof-in-innerhtml")
97: end
98: # Betting ends.
99: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 145
145: def remove_open_elements_until(name=nil)
146: finished = false
147: until finished
148: element = @tree.open_elements.pop
149: finished = name.nil? ? yield(element) : element.name == name
150: end
151: return element
152: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/phase.rb, line 119
119: def startTagHtml(name, attributes)
120: if @parser.first_start_tag == false and name == 'html'
121: parse_error("non-html-root")
122: end
123: # XXX Need a check here to see if the first start tag token emitted is
124: # this token... If it's not, invoke parse_error.
125: attributes.each do |attr, value|
126: unless @tree.open_elements.first.attributes.has_key?(attr)
127: @tree.open_elements.first.attributes[attr] = value
128: end
129: end
130: @parser.first_start_tag = false
131: end