~ubuntu-branches/ubuntu/raring/ruby-actionpack-3.2/raring

« back to all changes in this revision

Viewing changes to lib/action_controller/vendor/html-scanner/html/document.rb

  • Committer: Package Import Robot
  • Author(s): Ondřej Surý
  • Date: 2012-04-25 09:14:01 UTC
  • Revision ID: package-import@ubuntu.com-20120425091401-3nkf83btcemhjquo
Tags: upstream-3.2.3
Import upstream version 3.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'html/tokenizer'
 
2
require 'html/node'
 
3
require 'html/selector'
 
4
require 'html/sanitizer'
 
5
 
 
6
module HTML #:nodoc:
 
7
  # A top-level HTML document. You give it a body of text, and it will parse that
 
8
  # text into a tree of nodes.
 
9
  class Document #:nodoc:
 
10
 
 
11
    # The root of the parsed document.
 
12
    attr_reader :root
 
13
 
 
14
    # Create a new Document from the given text.
 
15
    def initialize(text, strict=false, xml=false)
 
16
      tokenizer = Tokenizer.new(text)
 
17
      @root = Node.new(nil)
 
18
      node_stack = [ @root ]
 
19
      while token = tokenizer.next
 
20
        node = Node.parse(node_stack.last, tokenizer.line, tokenizer.position, token, strict)
 
21
 
 
22
        node_stack.last.children << node unless node.tag? && node.closing == :close
 
23
        if node.tag?
 
24
          if node_stack.length > 1 && node.closing == :close
 
25
            if node_stack.last.name == node.name
 
26
              if node_stack.last.children.empty?
 
27
                node_stack.last.children << Text.new(node_stack.last, node.line, node.position, "")
 
28
              end
 
29
              node_stack.pop
 
30
            else
 
31
              open_start = node_stack.last.position - 20
 
32
              open_start = 0 if open_start < 0
 
33
              close_start = node.position - 20
 
34
              close_start = 0 if close_start < 0
 
35
              msg = <<EOF.strip
 
36
ignoring attempt to close #{node_stack.last.name} with #{node.name}
 
37
  opened at byte #{node_stack.last.position}, line #{node_stack.last.line}
 
38
  closed at byte #{node.position}, line #{node.line}
 
39
  attributes at open: #{node_stack.last.attributes.inspect}
 
40
  text around open: #{text[open_start,40].inspect}
 
41
  text around close: #{text[close_start,40].inspect}
 
42
EOF
 
43
              strict ? raise(msg) : warn(msg)
 
44
            end
 
45
          elsif !node.childless?(xml) && node.closing != :close
 
46
            node_stack.push node
 
47
          end
 
48
        end
 
49
      end
 
50
    end
 
51
 
 
52
    # Search the tree for (and return) the first node that matches the given
 
53
    # conditions. The conditions are interpreted differently for different node
 
54
    # types, see HTML::Text#find and HTML::Tag#find.
 
55
    def find(conditions)
 
56
      @root.find(conditions)
 
57
    end
 
58
 
 
59
    # Search the tree for (and return) all nodes that match the given
 
60
    # conditions. The conditions are interpreted differently for different node
 
61
    # types, see HTML::Text#find and HTML::Tag#find.
 
62
    def find_all(conditions)
 
63
      @root.find_all(conditions)
 
64
    end
 
65
 
 
66
  end
 
67
 
 
68
end