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