Class | HTML5::InBodyPhase |
In: |
lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb
|
Parent: | Phase |
processSpaceCharacters | -> | processSpaceCharactersNonPre |
processSpaceCharacters | -> | processSpaceCharactersNonPre |
processSpaceCharactersNonPre | -> | processSpaceCharacters |
processSpaceCharactersNonPre | -> | processSpaceCharacters |
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 49 49: def initialize(parser, tree) 50: super(parser, tree) 51: 52: # for special handling of whitespace in <pre> 53: @processSpaceCharactersDropNewline = false 54: if $-w 55: $-w = false 56: alias processSpaceCharactersNonPre processSpaceCharacters 57: $-w = true 58: else 59: alias processSpaceCharactersNonPre processSpaceCharacters 60: end 61: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 365 365: def endTagBlock(name) 366: #Put us back in the right whitespace handling mode 367: @processSpaceCharactersDropNewline = false if name == 'pre' 368: 369: @tree.generateImpliedEndTags if in_scope?(name) 370: 371: unless @tree.open_elements.last.name == name 372: parse_error("end-tag-too-early", {"name" => name}) 373: end 374: 375: if in_scope?(name) 376: remove_open_elements_until(name) 377: end 378: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 343 343: def endTagBody(name) 344: # XXX Need to take open <p> tags into account here. We shouldn't imply 345: # </p> but we should not throw a parse error either. Specification is 346: # likely to be updated. 347: unless @tree.open_elements[1].name == 'body' 348: # inner_html case 349: parse_error 350: return 351: end 352: unless @tree.open_elements.last.name == 'body' 353: parse_error("expected-one-end-tag-but-got-another", 354: {"expectedName" => "body", 355: "gotName" => @tree.open_elements.last.name}) 356: end 357: @parser.phase = @parser.phases[:afterBody] 358: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 554 554: def endTagBr(name) 555: parse_error("unexpected-end-tag-treated-as", 556: {"originalName" => "br", "newName" => "br element"}) 557: @tree.reconstructActiveFormattingElements 558: @tree.insert_element(name, {}) 559: @tree.open_elements.pop() 560: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 535 535: def endTagButtonMarqueeObject(name) 536: @tree.generateImpliedEndTags if in_scope?(name) 537: 538: unless @tree.open_elements.last.name == name 539: parse_error("end-tag-too-early", {"name" => name}) 540: end 541: 542: if in_scope?(name) 543: remove_open_elements_until(name) 544: 545: @tree.clearActiveFormattingElements 546: end 547: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 567 567: def endTagCdataTextAreaXmp(name) 568: if @tree.open_elements.last.name == name 569: @tree.open_elements.pop 570: else 571: parse_error("unexpected-end-tag", {"name" => name}) 572: end 573: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 380 380: def endTagForm(name) 381: if in_scope?(name) 382: @tree.generateImpliedEndTags 383: end 384: if @tree.open_elements.last.name != name 385: parse_error("end-tag-too-early-ignored", {"name" => "form"}) 386: else 387: @tree.open_elements.pop 388: end 389: @tree.formPointer = nil 390: end
The much-feared adoption agency algorithm
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 424 424: def endTagFormatting(name) 425: # http://www.whatwg.org/specs/web-apps/current-work/#adoptionAgency 426: # XXX Better parse_error messages appreciated. 427: while true 428: # Step 1 paragraph 1 429: afeElement = @tree.elementInActiveFormattingElements(name) 430: if !afeElement or (@tree.open_elements.include?(afeElement) && !in_scope?(afeElement.name)) 431: parse_error("adoption-agency-1.1", {"name" => name}) 432: return 433: # Step 1 paragraph 2 434: elsif not @tree.open_elements.include?(afeElement) 435: parse_error("adoption-agency-1.2", {"name" => name}) 436: @tree.activeFormattingElements.delete(afeElement) 437: return 438: end 439: 440: # Step 1 paragraph 3 441: if afeElement != @tree.open_elements.last 442: parse_error("adoption-agency-1.3", {"name" => name}) 443: end 444: 445: # Step 2 446: # Start of the adoption agency algorithm proper 447: afeIndex = @tree.open_elements.index(afeElement) 448: furthestBlock = nil 449: @tree.open_elements[afeIndex..-1].each do |element| 450: if (SPECIAL_ELEMENTS + SCOPING_ELEMENTS).include?(element.name) 451: furthestBlock = element 452: break 453: end 454: end 455: 456: # Step 3 457: if furthestBlock.nil? 458: element = remove_open_elements_until {|element| element == afeElement } 459: @tree.activeFormattingElements.delete(element) 460: return 461: end 462: commonAncestor = @tree.open_elements[afeIndex - 1] 463: 464: # Step 5 465: furthestBlock.parent.removeChild(furthestBlock) if furthestBlock.parent 466: 467: # Step 6 468: # The bookmark is supposed to help us identify where to reinsert 469: # nodes in step 12. We have to ensure that we reinsert nodes after 470: # the node before the active formatting element. Note the bookmark 471: # can move in step 7.4 472: bookmark = @tree.activeFormattingElements.index(afeElement) 473: 474: # Step 7 475: lastNode = node = furthestBlock 476: while true 477: # AT replace this with a function and recursion? 478: # Node is element before node in open elements 479: node = @tree.open_elements[@tree.open_elements.index(node) - 1] 480: until @tree.activeFormattingElements.include?(node) 481: tmpNode = node 482: node = @tree.open_elements[@tree.open_elements.index(node) - 1] 483: @tree.open_elements.delete(tmpNode) 484: end 485: # Step 7.3 486: break if node == afeElement 487: # Step 7.4 488: if lastNode == furthestBlock 489: # XXX should this be index(node) or index(node)+1 490: # Anne: I think +1 is ok. Given x = [2,3,4,5] 491: # x.index(3) gives 1 and then x[1 +1] gives 4... 492: bookmark = @tree.activeFormattingElements.index(node) + 1 493: end 494: # Step 7.5 495: cite = node.parent 496: if node.hasContent 497: clone = node.cloneNode 498: # Replace node with clone 499: @tree.activeFormattingElements[@tree.activeFormattingElements.index(node)] = clone 500: @tree.open_elements[@tree.open_elements.index(node)] = clone 501: node = clone 502: end 503: # Step 7.6 504: # Remove lastNode from its parents, if any 505: lastNode.parent.removeChild(lastNode) if lastNode.parent 506: node.appendChild(lastNode) 507: # Step 7.7 508: lastNode = node 509: # End of inner loop 510: end 511: 512: # Step 8 513: lastNode.parent.removeChild(lastNode) if lastNode.parent 514: commonAncestor.appendChild(lastNode) 515: 516: # Step 9 517: clone = afeElement.cloneNode 518: 519: # Step 10 520: furthestBlock.reparentChildren(clone) 521: 522: # Step 11 523: furthestBlock.appendChild(clone) 524: 525: # Step 12 526: @tree.activeFormattingElements.delete(afeElement) 527: @tree.activeFormattingElements.insert([bookmark,@tree.activeFormattingElements.length].min, clone) 528: 529: # Step 13 530: @tree.open_elements.delete(afeElement) 531: @tree.open_elements.insert(@tree.open_elements.index(furthestBlock) + 1, clone) 532: end 533: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 403 403: def endTagHeading(name) 404: HEADING_ELEMENTS.each do |element| 405: if in_scope?(element) 406: @tree.generateImpliedEndTags 407: break 408: end 409: end 410: 411: unless @tree.open_elements.last.name == name 412: parse_error("end-tag-too-early", {"name" => name}) 413: end 414: 415: HEADING_ELEMENTS.each do |element| 416: if in_scope?(element) 417: remove_open_elements_until {|element| HEADING_ELEMENTS.include?(element.name)} 418: break 419: end 420: end 421: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 360 360: def endTagHtml(name) 361: endTagBody(name) 362: @parser.phase.processEndTag(name) unless @parser.inner_html 363: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 392 392: def endTagListItem(name) 393: # AT Could merge this with the Block case 394: @tree.generateImpliedEndTags(name) if in_scope?(name) 395: 396: unless @tree.open_elements.last.name == name 397: parse_error("end-tag-too-early", {"name" => name}) 398: end 399: 400: remove_open_elements_until(name) if in_scope?(name) 401: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 549 549: def endTagMisplaced(name) 550: # This handles elements with end tags in other insertion modes. 551: parse_error("unexpected-end-tag", {"name" => name}) 552: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 575 575: def endTagNew(name) 576: # New HTML5 elements, "event-source", "section", "nav", 577: # "article", "aside", "header", "footer", "datagrid", "command" 578: # STDERR.puts "Warning: Undefined behaviour for end tag #{name}" 579: endTagOther(name) 580: #raise NotImplementedError 581: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 562 562: def endTagNone(name) 563: # This handles elements with no end tag. 564: parse_error("no-end-tag", {"name" => name}) 565: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 583 583: def endTagOther(name) 584: # XXX This logic should be moved into the treebuilder 585: @tree.open_elements.reverse.each do |node| 586: if node.name == name 587: @tree.generateImpliedEndTags 588: 589: unless @tree.open_elements.last.name == name 590: parse_error("unexpected-end-tag", {"name" => name}) 591: end 592: 593: remove_open_elements_until {|element| element == node } 594: 595: break 596: else 597: if (SPECIAL_ELEMENTS + SCOPING_ELEMENTS).include?(node.name) 598: parse_error("unexpected-end-tag", {"name" => name}) 599: break 600: end 601: end 602: end 603: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 332 332: def endTagP(name) 333: @tree.generateImpliedEndTags('p') if in_scope?('p') 334: parse_error("unexpected-end-tag", {"name" => "p"}) unless @tree.open_elements.last.name == 'p' 335: if in_scope?('p') 336: @tree.open_elements.pop while in_scope?('p') 337: else 338: startTagCloseP('p', {}) 339: endTagP('p') 340: end 341: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 90 90: def processCharacters(data) 91: # XXX The specification says to do this for every character at the 92: # moment, but apparently that doesn't match the real world so we don't 93: # do it for space characters. 94: @tree.reconstructActiveFormattingElements 95: @tree.insertText(data) 96: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 85 85: def processSpaceCharacters(data) 86: @tree.reconstructActiveFormattingElements() 87: @tree.insertText(data) 88: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 63 63: def processSpaceCharactersDropNewline(data) 64: # #Sometimes (start of <pre> blocks) we want to drop leading newlines 65: 66: if $-w 67: $-w = false 68: alias processSpaceCharacters processSpaceCharactersNonPre 69: $-w = true 70: else 71: alias processSpaceCharacters processSpaceCharactersNonPre 72: end 73: 74: if (data.length > 0 and data[0] == ?\n && 75: %w[pre textarea].include?(@tree.open_elements.last.name) && !@tree.open_elements.last.hasContent) 76: data = data[1..-1] 77: end 78: 79: if data.length > 0 80: @tree.reconstructActiveFormattingElements 81: @tree.insertText(data) 82: end 83: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 187 187: def startTagA(name, attributes) 188: if afeAElement = @tree.elementInActiveFormattingElements('a') 189: parse_error("unexpected-start-tag-implies-end-tag", {"startName" => "a", "endName" => "a"}) 190: endTagFormatting('a') 191: @tree.open_elements.delete(afeAElement) if @tree.open_elements.include?(afeAElement) 192: @tree.activeFormattingElements.delete(afeAElement) if @tree.activeFormattingElements.include?(afeAElement) 193: end 194: @tree.reconstructActiveFormattingElements 195: addFormattingElement(name, attributes) 196: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 107 107: def startTagBody(name, attributes) 108: parse_error("unexpected-start-tag", {"name" => "body"}) 109: 110: if @tree.open_elements.length == 1 || @tree.open_elements[1].name != 'body' 111: assert @parser.inner_html 112: else 113: attributes.each do |attr, value| 114: unless @tree.open_elements[1].attributes.has_key?(attr) 115: @tree.open_elements[1].attributes[attr] = value 116: end 117: end 118: end 119: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 214 214: def startTagButton(name, attributes) 215: if in_scope?('button') 216: parse_error("unexpected-start-tag-implies-end-tag", {"startName" => "button", "endName" => "button"}) 217: processEndTag('button') 218: @parser.phase.processStartTag(name, attributes) 219: else 220: @tree.reconstructActiveFormattingElements 221: @tree.insert_element(name, attributes) 222: @tree.activeFormattingElements.push(Marker) 223: end 224: end
iframe, noembed noframes, noscript(if scripting enabled)
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 299 299: def startTagCdata(name, attributes) 300: @tree.insert_element(name, attributes) 301: @parser.tokenizer.content_model_flag = :CDATA 302: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 121 121: def startTagCloseP(name, attributes) 122: endTagP('p') if in_scope?('p') 123: @tree.insert_element(name, attributes) 124: @processSpaceCharactersDropNewline = true if name == 'pre' 125: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 127 127: def startTagForm(name, attributes) 128: if @tree.formPointer 129: parse_error("unexpected-start-tag", {"name" => name}) 130: else 131: endTagP('p') if in_scope?('p') 132: @tree.insert_element(name, attributes) 133: @tree.formPointer = @tree.open_elements.last 134: end 135: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 198 198: def startTagFormatting(name, attributes) 199: @tree.reconstructActiveFormattingElements 200: addFormattingElement(name, attributes) 201: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 169 169: def startTagHeading(name, attributes) 170: endTagP('p') if in_scope?('p') 171: 172: # Uncomment the following for IE7 behavior: 173: # HEADING_ELEMENTS.each do |element| 174: # if in_scope?(element) 175: # parse_error("unexpected-start-tag", {"name" => name}) 176: # 177: # remove_open_elements_until do |element| 178: # HEADING_ELEMENTS.include?(element.name) 179: # end 180: # 181: # break 182: # end 183: # end 184: @tree.insert_element(name, attributes) 185: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 250 250: def startTagHr(name, attributes) 251: endTagP('p') if in_scope?('p') 252: @tree.insert_element(name, attributes) 253: @tree.open_elements.pop 254: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 256 256: def startTagImage(name, attributes) 257: # No really... 258: parse_error("unexpected-start-tag-treated-as", {"originalName" => "image", "newName" => "img"}) 259: processStartTag('img', attributes) 260: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 262 262: def startTagInput(name, attributes) 263: @tree.reconstructActiveFormattingElements 264: @tree.insert_element(name, attributes) 265: if @tree.formPointer 266: # XXX Not exactly sure what to do here 267: # @tree.open_elements[-1].form = @tree.formPointer 268: end 269: @tree.open_elements.pop 270: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 272 272: def startTagIsindex(name, attributes) 273: parse_error("deprecated-tag", {"name" => "isindex"}) 274: return if @tree.formPointer 275: processStartTag('form', {}) 276: processStartTag('hr', {}) 277: processStartTag('p', {}) 278: processStartTag('label', {}) 279: # XXX Localization ... 280: processCharacters('This is a searchable index. Insert your search keywords here: ') 281: attributes['name'] = 'isindex' 282: attrs = attributes.to_a 283: processStartTag('input', attributes) 284: processEndTag('label') 285: processEndTag('p') 286: processStartTag('hr', {}) 287: processEndTag('form') 288: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 137 137: def startTagListItem(name, attributes) 138: endTagP('p') if in_scope?('p') 139: stopNames = {'li' => ['li'], 'dd' => ['dd', 'dt'], 'dt' => ['dd', 'dt']} 140: stopName = stopNames[name] 141: 142: @tree.open_elements.reverse.each_with_index do |node, i| 143: if stopName.include?(node.name) 144: poppedNodes = (0..i).collect { @tree.open_elements.pop } 145: if i >= 1 146: parse_error( 147: i == 1 ? "missing-end-tag" : "missing-end-tags", 148: {"name" => poppedNodes[0..-1].collect{|n| n.name}.join(", ")}) 149: 150: end 151: break 152: end 153: 154: # Phrasing elements are all non special, non scoping, non 155: # formatting elements 156: break if ((SPECIAL_ELEMENTS + SCOPING_ELEMENTS).include?(node.name) && !%w[address div].include?(node.name)) 157: end 158: 159: # Always insert an <li> element. 160: @tree.insert_element(name, attributes) 161: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 226 226: def startTagMarqueeObject(name, attributes) 227: @tree.reconstructActiveFormattingElements 228: @tree.insert_element(name, attributes) 229: @tree.activeFormattingElements.push(Marker) 230: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 310 310: def startTagMisplaced(name, attributes) 311: # Elements that should be children of other elements that have a 312: # different insertion mode; here they are ignored 313: # "caption", "col", "colgroup", "frame", "frameset", "head", 314: # "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", 315: # "tr", "noscript" 316: parse_error("unexpected-start-tag-ignored", {"name" => name}) 317: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 319 319: def startTagNew(name, attributes) 320: # New HTML5 elements, "event-source", "section", "nav", 321: # "article", "aside", "header", "footer", "datagrid", "command" 322: # $stderr.puts("Warning: Undefined behaviour for start tag #{name}") 323: startTagOther(name, attributes) 324: #raise NotImplementedError 325: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 203 203: def startTagNobr(name, attributes) 204: @tree.reconstructActiveFormattingElements 205: if in_scope?('nobr') 206: parse_error("unexpected-start-tag-implies-end-tag", {"startName" => "nobr", "endName" => "nobr"}) 207: processEndTag('nobr') 208: # XXX Need tests that trigger the following 209: @tree.reconstructActiveFormattingElements 210: end 211: addFormattingElement(name, attributes) 212: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 327 327: def startTagOther(name, attributes) 328: @tree.reconstructActiveFormattingElements 329: @tree.insert_element(name, attributes) 330: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 163 163: def startTagPlaintext(name, attributes) 164: endTagP('p') if in_scope?('p') 165: @tree.insert_element(name, attributes) 166: @parser.tokenizer.content_model_flag = :PLAINTEXT 167: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 98 98: def startTagProcessInHead(name, attributes) 99: @parser.phases[:inHead].processStartTag(name, attributes) 100: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 304 304: def startTagSelect(name, attributes) 305: @tree.reconstructActiveFormattingElements 306: @tree.insert_element(name, attributes) 307: @parser.phase = @parser.phases[:inSelect] 308: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 238 238: def startTagTable(name, attributes) 239: processEndTag('p') if in_scope?('p') 240: @tree.insert_element(name, attributes) 241: @parser.phase = @parser.phases[:inTable] 242: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 290 290: def startTagTextarea(name, attributes) 291: # XXX Form element pointer checking here as well... 292: @tree.insert_element(name, attributes) 293: @parser.tokenizer.content_model_flag = :RCDATA 294: @processSpaceCharactersDropNewline = true 295: alias processSpaceCharacters processSpaceCharactersDropNewline 296: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 102 102: def startTagTitle(name, attributes) 103: parse_error("unexpected-start-tag-out-of-my-head", {"name" => name}) 104: @parser.phases[:inHead].processStartTag(name, attributes) 105: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 244 244: def startTagVoidFormatting(name, attributes) 245: @tree.reconstructActiveFormattingElements 246: @tree.insert_element(name, attributes) 247: @tree.open_elements.pop 248: end
# File lib/feed_tools/vendor/html5/lib/html5/html5parser/in_body_phase.rb, line 232 232: def startTagXmp(name, attributes) 233: @tree.reconstructActiveFormattingElements 234: @tree.insert_element(name, attributes) 235: @parser.tokenizer.content_model_flag = :CDATA 236: end