nokogiri 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (75) hide show
  1. data/.autotest +15 -0
  2. data/{History.ja.txt → CHANGELOG.ja.rdoc} +30 -2
  3. data/{History.txt → CHANGELOG.rdoc} +28 -2
  4. data/Manifest.txt +13 -7
  5. data/{README.ja.txt → README.ja.rdoc} +3 -1
  6. data/{README.txt → README.rdoc} +7 -1
  7. data/Rakefile +8 -25
  8. data/ext/nokogiri/extconf.rb +4 -4
  9. data/ext/nokogiri/html_entity_lookup.c +30 -0
  10. data/ext/nokogiri/html_entity_lookup.h +8 -0
  11. data/ext/nokogiri/native.c +22 -0
  12. data/ext/nokogiri/native.h +27 -4
  13. data/ext/nokogiri/xml_document.c +31 -4
  14. data/ext/nokogiri/xml_document.h +11 -0
  15. data/ext/nokogiri/xml_document_fragment.c +1 -1
  16. data/ext/nokogiri/xml_node.c +71 -58
  17. data/ext/nokogiri/xml_node_set.c +26 -0
  18. data/ext/nokogiri/xml_reader.c +4 -2
  19. data/ext/nokogiri/xml_sax_parser.c +0 -37
  20. data/ext/nokogiri/xml_sax_push_parser.c +2 -2
  21. data/ext/nokogiri/xml_xpath_context.c +34 -7
  22. data/lib/nokogiri.rb +25 -0
  23. data/lib/nokogiri/css/generated_tokenizer.rb +2 -2
  24. data/lib/nokogiri/css/node.rb +2 -0
  25. data/lib/nokogiri/css/parser.rb +3 -2
  26. data/lib/nokogiri/html.rb +9 -52
  27. data/lib/nokogiri/html/document.rb +2 -0
  28. data/lib/nokogiri/html/entity_lookup.rb +11 -0
  29. data/lib/nokogiri/version.rb +1 -1
  30. data/lib/nokogiri/xml.rb +1 -2
  31. data/lib/nokogiri/xml/builder.rb +18 -5
  32. data/lib/nokogiri/xml/document.rb +15 -1
  33. data/lib/nokogiri/xml/fragment_handler.rb +34 -0
  34. data/lib/nokogiri/xml/node.rb +104 -29
  35. data/lib/nokogiri/xml/node_set.rb +12 -10
  36. data/lib/nokogiri/xml/sax/parser.rb +3 -3
  37. data/lib/xsd/xmlparser/nokogiri.rb +53 -0
  38. data/tasks/test.rb +7 -5
  39. data/test/css/test_nthiness.rb +1 -0
  40. data/test/css/test_parser.rb +1 -0
  41. data/test/css/test_tokenizer.rb +1 -0
  42. data/test/css/test_xpath_visitor.rb +1 -0
  43. data/test/helper.rb +4 -0
  44. data/test/hpricot/test_alter.rb +1 -0
  45. data/test/html/sax/test_parser.rb +13 -0
  46. data/test/html/test_builder.rb +21 -0
  47. data/test/html/test_document.rb +36 -0
  48. data/test/html/test_document_encoding.rb +46 -0
  49. data/test/html/test_named_characters.rb +14 -0
  50. data/test/html/test_node.rb +80 -0
  51. data/test/test_convert_xpath.rb +1 -0
  52. data/test/test_css_cache.rb +1 -0
  53. data/test/test_nokogiri.rb +8 -0
  54. data/test/xml/sax/test_parser.rb +6 -0
  55. data/test/xml/sax/test_push_parser.rb +1 -0
  56. data/test/xml/test_builder.rb +9 -0
  57. data/test/xml/test_cdata.rb +1 -0
  58. data/test/xml/test_comment.rb +1 -0
  59. data/test/xml/test_document.rb +58 -0
  60. data/test/xml/test_document_encoding.rb +15 -14
  61. data/test/xml/test_document_fragment.rb +6 -0
  62. data/test/xml/test_dtd.rb +1 -0
  63. data/test/xml/test_dtd_encoding.rb +1 -0
  64. data/test/xml/test_entity_reference.rb +1 -0
  65. data/test/xml/test_node.rb +52 -4
  66. data/test/xml/test_node_encoding.rb +1 -0
  67. data/test/xml/test_node_set.rb +21 -1
  68. data/test/xml/test_processing_instruction.rb +1 -0
  69. data/test/xml/test_reader_encoding.rb +1 -0
  70. data/test/xml/test_unparented_node.rb +381 -0
  71. data/test/xml/test_xpath.rb +1 -0
  72. metadata +34 -16
  73. data/lib/nokogiri/xml/after_handler.rb +0 -18
  74. data/lib/nokogiri/xml/before_handler.rb +0 -33
  75. data/vendor/hoe.rb +0 -1020
@@ -1,8 +1,8 @@
1
- #
1
+ #--
2
2
  # DO NOT MODIFY!!!!
3
3
  # This file is automatically generated by rex 1.0.1
4
4
  # from lexical definition file "lib/nokogiri/css/tokenizer.rex".
5
- #
5
+ #++
6
6
 
7
7
  module Nokogiri
8
8
  module CSS
@@ -11,6 +11,8 @@ module Nokogiri
11
11
  visitor.send(:"visit_#{type.to_s.downcase}", self)
12
12
  end
13
13
 
14
+ ###
15
+ # Convert this CSS node to xpath with +prefix+ using +visitor+
14
16
  def to_xpath prefix = '//', visitor = XPathVisitor.new
15
17
  self.preprocess!
16
18
  prefix + visitor.accept(self)
@@ -52,14 +52,15 @@ module Nokogiri
52
52
  alias :parse :scan_str
53
53
 
54
54
  def xpath_for string, options={}
55
- v = self.class[string]
55
+ key = string + options[:ns].to_s
56
+ v = self.class[key]
56
57
  return v if v
57
58
 
58
59
  args = [
59
60
  options[:prefix] || '//',
60
61
  options[:visitor] || XPathVisitor.new
61
62
  ]
62
- self.class[string] = parse(string).map { |ast|
63
+ self.class[key] = parse(string).map { |ast|
63
64
  ast.to_xpath(*args)
64
65
  }
65
66
  end
@@ -1,3 +1,4 @@
1
+ require 'nokogiri/html/entity_lookup'
1
2
  require 'nokogiri/html/document'
2
3
  require 'nokogiri/html/sax/parser'
3
4
 
@@ -28,6 +29,10 @@ module Nokogiri
28
29
  ###
29
30
  # Parse HTML. See Nokogiri.HTML.
30
31
  def parse string_or_io, url = nil, encoding = nil, options = 2145
32
+ if string_or_io.respond_to?(:encoding)
33
+ encoding ||= string_or_io.encoding.name
34
+ end
35
+
31
36
  if string_or_io.respond_to?(:read)
32
37
  url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
33
38
  return Document.read_io(string_or_io, url, encoding, options)
@@ -43,6 +48,9 @@ module Nokogiri
43
48
  fragment = XML::DocumentFragment.new(doc)
44
49
  finder = lambda { |c, f|
45
50
  c.each do |child|
51
+ if string == child.content && child.name == 'text'
52
+ fragment.add_child(child)
53
+ end
46
54
  fragment.add_child(child) if string =~ /<#{child.name}/
47
55
  end
48
56
  return fragment if fragment.children.length > 0
@@ -55,57 +63,6 @@ module Nokogiri
55
63
  fragment
56
64
  end
57
65
  end
58
-
59
- NamedCharacters =
60
- {"AElig"=>198, "Aacute"=>193, "Acirc"=>194, "Agrave"=>192, "Alpha"=>913,
61
- "Aring"=>197, "Atilde"=>195, "Auml"=>196, "Beta"=>914, "Ccedil"=>199,
62
- "Chi"=>935, "Dagger"=>8225, "Delta"=>916, "ETH"=>208, "Eacute"=>201,
63
- "Ecirc"=>202, "Egrave"=>200, "Epsilon"=>917, "Eta"=>919, "Euml"=>203,
64
- "Gamma"=>915, "Iacute"=>205, "Icirc"=>206, "Igrave"=>204, "Iota"=>921,
65
- "Iuml"=>207, "Kappa"=>922, "Lambda"=>923, "Mu"=>924, "Ntilde"=>209, "Nu"=>925,
66
- "OElig"=>338, "Oacute"=>211, "Ocirc"=>212, "Ograve"=>210, "Omega"=>937,
67
- "Omicron"=>927, "Oslash"=>216, "Otilde"=>213, "Ouml"=>214, "Phi"=>934,
68
- "Pi"=>928, "Prime"=>8243, "Psi"=>936, "Rho"=>929, "Scaron"=>352, "Sigma"=>931,
69
- "THORN"=>222, "Tau"=>932, "Theta"=>920, "Uacute"=>218, "Ucirc"=>219,
70
- "Ugrave"=>217, "Upsilon"=>933, "Uuml"=>220, "Xi"=>926, "Yacute"=>221,
71
- "Yuml"=>376, "Zeta"=>918, "aacute"=>225, "acirc"=>226, "acute"=>180,
72
- "aelig"=>230, "agrave"=>224, "alefsym"=>8501, "alpha"=>945, "amp"=>38,
73
- "and"=>8743, "ang"=>8736, "apos"=>39, "aring"=>229, "asymp"=>8776,
74
- "atilde"=>227, "auml"=>228, "bdquo"=>8222, "beta"=>946, "brvbar"=>166,
75
- "bull"=>8226, "cap"=>8745, "ccedil"=>231, "cedil"=>184, "cent"=>162,
76
- "chi"=>967, "circ"=>710, "clubs"=>9827, "cong"=>8773, "copy"=>169,
77
- "crarr"=>8629, "cup"=>8746, "curren"=>164, "dArr"=>8659, "dagger"=>8224,
78
- "darr"=>8595, "deg"=>176, "delta"=>948, "diams"=>9830, "divide"=>247,
79
- "eacute"=>233, "ecirc"=>234, "egrave"=>232, "empty"=>8709, "emsp"=>8195,
80
- "ensp"=>8194, "epsilon"=>949, "equiv"=>8801, "eta"=>951, "eth"=>240,
81
- "euml"=>235, "euro"=>8364, "exist"=>8707, "fnof"=>402, "forall"=>8704,
82
- "frac12"=>189, "frac14"=>188, "frac34"=>190, "frasl"=>8260, "gamma"=>947,
83
- "ge"=>8805, "gt"=>62, "hArr"=>8660, "harr"=>8596, "hearts"=>9829,
84
- "hellip"=>8230, "iacute"=>237, "icirc"=>238, "iexcl"=>161, "igrave"=>236,
85
- "image"=>8465, "infin"=>8734, "int"=>8747, "iota"=>953, "iquest"=>191,
86
- "isin"=>8712, "iuml"=>239, "kappa"=>954, "lArr"=>8656, "lambda"=>955,
87
- "lang"=>9001, "laquo"=>171, "larr"=>8592, "lceil"=>8968, "ldquo"=>8220,
88
- "le"=>8804, "lfloor"=>8970, "lowast"=>8727, "loz"=>9674, "lrm"=>8206,
89
- "lsaquo"=>8249, "lsquo"=>8216, "lt"=>60, "macr"=>175, "mdash"=>8212,
90
- "micro"=>181, "middot"=>183, "minus"=>8722, "mu"=>956, "nabla"=>8711,
91
- "nbsp"=>160, "ndash"=>8211, "ne"=>8800, "ni"=>8715, "not"=>172, "notin"=>8713,
92
- "nsub"=>8836, "ntilde"=>241, "nu"=>957, "oacute"=>243, "ocirc"=>244,
93
- "oelig"=>339, "ograve"=>242, "oline"=>8254, "omega"=>969, "omicron"=>959,
94
- "oplus"=>8853, "or"=>8744, "ordf"=>170, "ordm"=>186, "oslash"=>248,
95
- "otilde"=>245, "otimes"=>8855, "ouml"=>246, "para"=>182, "part"=>8706,
96
- "permil"=>8240, "perp"=>8869, "phi"=>966, "pi"=>960, "piv"=>982,
97
- "plusmn"=>177, "pound"=>163, "prime"=>8242, "prod"=>8719, "prop"=>8733,
98
- "psi"=>968, "quot"=>34, "rArr"=>8658, "radic"=>8730, "rang"=>9002,
99
- "raquo"=>187, "rarr"=>8594, "rceil"=>8969, "rdquo"=>8221, "real"=>8476,
100
- "reg"=>174, "rfloor"=>8971, "rho"=>961, "rlm"=>8207, "rsaquo"=>8250,
101
- "rsquo"=>8217, "sbquo"=>8218, "scaron"=>353, "sdot"=>8901, "sect"=>167,
102
- "shy"=>173, "sigma"=>963, "sigmaf"=>962, "sim"=>8764, "spades"=>9824,
103
- "sub"=>8834, "sube"=>8838, "sum"=>8721, "sup"=>8835, "sup1"=>185, "sup2"=>178,
104
- "sup3"=>179, "supe"=>8839, "szlig"=>223, "tau"=>964, "there4"=>8756,
105
- "theta"=>952, "thetasym"=>977, "thinsp"=>8201, "thorn"=>254, "tilde"=>732,
106
- "times"=>215, "trade"=>8482, "uArr"=>8657, "uacute"=>250, "uarr"=>8593,
107
- "ucirc"=>251, "ugrave"=>249, "uml"=>168, "upsih"=>978, "upsilon"=>965,
108
- "uuml"=>252, "weierp"=>8472, "xi"=>958, "yacute"=>253, "yen"=>165,
109
- "yuml"=>255, "zeta"=>950, "zwj"=>8205, "zwnj"=>8204}
66
+ NamedCharacters = EntityLookup.new
110
67
  end
111
68
  end
@@ -1,6 +1,8 @@
1
1
  module Nokogiri
2
2
  module HTML
3
3
  class Document < XML::Document
4
+ ####
5
+ # Serialize this Document with +encoding+ using +options+
4
6
  def serialize encoding = nil, options = XML::Node::SaveOptions::FORMAT |
5
7
  XML::Node::SaveOptions::AS_HTML |
6
8
  XML::Node::SaveOptions::NO_DECLARATION |
@@ -0,0 +1,11 @@
1
+ module Nokogiri
2
+ module HTML
3
+ class EntityDescription < Struct.new(:value, :name, :description); end
4
+
5
+ class EntityLookup
6
+ def [] name
7
+ (val = get(name)) && val.value
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
1
  module Nokogiri
2
2
  # The version of Nokogiri you are using
3
- VERSION = '1.2.1'
3
+ VERSION = '1.2.2'
4
4
  end
@@ -1,6 +1,5 @@
1
1
  require 'nokogiri/xml/sax'
2
- require 'nokogiri/xml/before_handler'
3
- require 'nokogiri/xml/after_handler'
2
+ require 'nokogiri/xml/fragment_handler'
4
3
  require 'nokogiri/xml/node'
5
4
  require 'nokogiri/xml/attr'
6
5
  require 'nokogiri/xml/dtd'
@@ -1,14 +1,17 @@
1
1
  module Nokogiri
2
2
  module XML
3
3
  class Builder
4
- attr_accessor :doc, :parent
4
+ attr_accessor :doc, :parent, :context
5
5
  def initialize(&block)
6
6
  namespace = self.class.name.split('::')
7
7
  namespace[-1] = 'Document'
8
8
  @doc = eval(namespace.join('::')).new
9
9
  @parent = @doc
10
- @context = eval('self', block.binding)
11
- instance_eval(&block)
10
+ @context = nil
11
+ if block_given?
12
+ @context = eval('self', block.binding)
13
+ end
14
+ instance_eval(&block) if block_given?
12
15
  @parent = @doc
13
16
  end
14
17
 
@@ -27,7 +30,7 @@ module Nokogiri
27
30
  end
28
31
 
29
32
  def method_missing(method, *args, &block)
30
- if @context.respond_to?(method)
33
+ if @context && @context.respond_to?(method)
31
34
  @context.send(method, *args, &block)
32
35
  else
33
36
  node = Nokogiri::XML::Node.new(method.to_s, @doc) { |n|
@@ -61,6 +64,7 @@ module Nokogiri
61
64
  end
62
65
 
63
66
  def method_missing(method, *args, &block)
67
+ opts = args.last.is_a?(Hash) ? args.pop : {}
64
68
  case method.to_s
65
69
  when /^(.*)!$/
66
70
  @node['id'] = $1
@@ -72,9 +76,18 @@ module Nokogiri
72
76
  ((@node['class'] || '').split(/\s/) + [method.to_s]).join(' ')
73
77
  @node.content = args.first if args.first
74
78
  end
79
+
80
+ # Assign any extra options
81
+ opts.each do |k,v|
82
+ @node[k.to_s] = ((@node[k.to_s] || '').split(/\s/) + [v]).join(' ')
83
+ end
84
+
75
85
  if block_given?
86
+ old_parent = @doc_builder.parent
76
87
  @doc_builder.parent = @node
77
- return @doc_builder.instance_eval(&block)
88
+ value = @doc_builder.instance_eval(&block)
89
+ @doc_builder.parent = old_parent
90
+ return value
78
91
  end
79
92
  self
80
93
  end
@@ -1,16 +1,27 @@
1
1
  module Nokogiri
2
2
  module XML
3
+ ####
4
+ # Nokogiri::XML::Document is the main entry point for dealing with
5
+ # XML documents. The Document is created by parsing an XML document.
6
+ # See Nokogiri.XML()
7
+ #
8
+ # For searching a Document, see Nokogiri::XML::Node#css and
9
+ # Nokogiri::XML::Node#xpath
3
10
  class Document < Node
11
+ # A list of Nokogiri::XML::SyntaxError found when parsing a document
4
12
  attr_accessor :errors
5
13
 
14
+ # The name of this document. Always returns "document"
6
15
  def name
7
16
  'document'
8
17
  end
9
18
 
19
+ # A reference to +self+
10
20
  def document
11
21
  self
12
22
  end
13
23
 
24
+ # Get the list of decorators given +key+
14
25
  def decorators(key)
15
26
  @decorators ||= Hash.new
16
27
  @decorators[key] ||= []
@@ -37,16 +48,19 @@ module Nokogiri
37
48
  }
38
49
  end
39
50
 
40
- def node_cache
51
+ def node_cache # :nodoc:
41
52
  @node_cache ||= {}
42
53
  end
43
54
 
44
55
  alias :to_xml :serialize
45
56
  alias :inner_html :serialize
46
57
 
58
+ # Get the hash of namespaces on the root Nokogiri::XML::Node
47
59
  def namespaces
48
60
  root ? root.collect_namespaces : {}
49
61
  end
62
+
63
+ undef_method :swap, :parent, :namespace
50
64
  end
51
65
  end
52
66
  end
@@ -0,0 +1,34 @@
1
+ module Nokogiri
2
+ module XML
3
+ class FragmentHandler < Nokogiri::XML::SAX::Document # :nodoc:
4
+ def initialize node, original_html
5
+ @doc_started = false
6
+ @original_html = original_html
7
+ @document = node.document
8
+ @stack = [node]
9
+ end
10
+
11
+ def start_element name, attrs = []
12
+ @doc_started = true if @original_html =~ /^<#{name}/
13
+ return unless @doc_started
14
+
15
+ node = Node.new(name, @document)
16
+ Hash[*attrs].each do |k,v|
17
+ node[k] = v
18
+ end
19
+ @stack.last << node
20
+ @stack << node
21
+ end
22
+
23
+ def characters string
24
+ @doc_started = true if @original_html =~ /^\s*#{string}/
25
+ @stack.last << Nokogiri::XML::Text.new(string, @document)
26
+ end
27
+
28
+ def end_element name
29
+ return unless @stack.last.name == name
30
+ @stack.pop
31
+ end
32
+ end
33
+ end
34
+ end
@@ -3,6 +3,36 @@ require 'nokogiri/xml/node/save_options'
3
3
 
4
4
  module Nokogiri
5
5
  module XML
6
+ ####
7
+ # Nokogiri::XML::Node is your window to the fun filled world of dealing
8
+ # with XML and HTML tags. A Nokogiri::XML::Node may be treated similarly
9
+ # to a hash with regard to attributes. For example (from irb):
10
+ #
11
+ # irb(main):004:0> node
12
+ # => <a href="#foo" id="link">link</a>
13
+ # irb(main):005:0> node['href']
14
+ # => "#foo"
15
+ # irb(main):006:0> node.keys
16
+ # => ["href", "id"]
17
+ # irb(main):007:0> node.values
18
+ # => ["#foo", "link"]
19
+ # irb(main):008:0> node['class'] = 'green'
20
+ # => "green"
21
+ # irb(main):009:0> node
22
+ # => <a href="#foo" id="link" class="green">link</a>
23
+ # irb(main):010:0>
24
+ #
25
+ # See Nokogiri::XML::Node#[] and Nokogiri::XML#[]= for more information.
26
+ #
27
+ # Nokogiri::XML::Node also has methods that let you move around your
28
+ # tree. For navigating your tree, see:
29
+ #
30
+ # * Nokogiri::XML::Node#parent
31
+ # * Nokogiri::XML::Node#children
32
+ # * Nokogiri::XML::Node#next
33
+ # * Nokogiri::XML::Node#previous
34
+ #
35
+ # You may search this node's subtree using Node#xpath and Node#css
6
36
  class Node
7
37
  ELEMENT_NODE = 1
8
38
  ATTRIBUTE_NODE = 2
@@ -56,10 +86,15 @@ module Nokogiri
56
86
  # optional hash of namespaces may be appended.
57
87
  # See Node#xpath and Node#css.
58
88
  def search *paths
59
- ns = paths.last.is_a?(Hash) ? paths.pop : {}
89
+ ns = paths.last.is_a?(Hash) ? paths.pop :
90
+ (document.root ? document.root.namespaces : {})
60
91
  xpath(*(paths.map { |path|
61
92
  path = path.to_s
62
- path =~ /^(\.\/|\/)/ ? path : CSS.xpath_for(path, :prefix => ".//")
93
+ path =~ /^(\.\/|\/)/ ? path : CSS.xpath_for(
94
+ path,
95
+ :prefix => ".//",
96
+ :ns => ns
97
+ )
63
98
  }.flatten.uniq) + [ns])
64
99
  end
65
100
  alias :/ :search
@@ -88,9 +123,10 @@ module Nokogiri
88
123
  Hash, String, Symbol
89
124
  ].include?(paths.last.class) ? paths.pop : nil
90
125
 
91
- ns = paths.last.is_a?(Hash) ? paths.pop : document.root.namespaces
126
+ ns = paths.last.is_a?(Hash) ? paths.pop :
127
+ (document.root ? document.root.namespaces : {})
92
128
 
93
- return NodeSet.new(document) unless document.root
129
+ return NodeSet.new(document) unless document
94
130
 
95
131
  sets = paths.map { |path|
96
132
  ctx = XPathContext.new(self)
@@ -138,7 +174,8 @@ module Nokogiri
138
174
  Hash, String, Symbol
139
175
  ].include?(rules.last.class) ? rules.pop : nil
140
176
 
141
- ns = rules.last.is_a?(Hash) ? rules.pop : document.root.namespaces
177
+ ns = rules.last.is_a?(Hash) ? rules.pop :
178
+ (document.root ? document.root.namespaces : {})
142
179
 
143
180
  rules = rules.map { |rule|
144
181
  CSS.xpath_for(rule, :prefix => ".//", :ns => ns)
@@ -150,15 +187,15 @@ module Nokogiri
150
187
  ###
151
188
  # Search for the first occurrence of +path+.
152
189
  # Returns nil if nothing is found, otherwise a Node.
153
- def at path, ns = document.root.namespaces
190
+ def at path, ns = document.root ? document.root.namespaces : {}
154
191
  search(path, ns).first
155
192
  end
156
193
 
157
194
  ###
158
195
  # Get the attribute value for the attribute +name+
159
- def [](name)
160
- return nil unless key?(name)
161
- get(name)
196
+ def [] name
197
+ return nil unless key?(name.to_s)
198
+ get(name.to_s)
162
199
  end
163
200
 
164
201
  alias :next :next_sibling
@@ -215,32 +252,59 @@ module Nokogiri
215
252
  # Create nodes from +data+ and insert them before this node
216
253
  # (as a sibling).
217
254
  def before data
218
- classes = document.class.name.split('::')
219
- classes[-1] = 'SAX::Parser'
220
-
221
- parser = eval(classes.join('::')).new(BeforeHandler.new(self, data))
222
- parser.parse(data)
255
+ fragment(data).children.each do |node|
256
+ add_previous_sibling node
257
+ end
258
+ self
223
259
  end
224
260
 
225
261
  ####
226
262
  # Create nodes from +data+ and insert them after this node
227
263
  # (as a sibling).
228
264
  def after data
265
+ fragment(data).children.to_a.reverse.each do |node|
266
+ add_next_sibling node
267
+ end
268
+ self
269
+ end
270
+
271
+ ####
272
+ # Swap this Node for new nodes made from +data+
273
+ def swap data
274
+ before(data)
275
+ remove
276
+ self
277
+ end
278
+
279
+ ####
280
+ # Set the inner_html for this Node to +tags+
281
+ def inner_html= tags
282
+ children.each { |x| x.remove}
283
+
284
+ fragment(tags).children.to_a.reverse.each do |node|
285
+ add_child node
286
+ end
287
+ self
288
+ end
289
+
290
+ ####
291
+ # Create a Nokogiri::XML::DocumentFragment from +tags+
292
+ def fragment tags
229
293
  classes = document.class.name.split('::')
230
294
  classes[-1] = 'SAX::Parser'
231
295
 
232
- handler = AfterHandler.new(self, data)
233
- parser = eval(classes.join('::')).new(handler)
234
- parser.parse(data)
235
- handler.after_nodes.reverse.each do |sibling|
236
- self.add_next_sibling sibling
237
- end
296
+
297
+ fragment = DocumentFragment.new(self.document)
298
+ parser = eval(classes.join('::')).new(
299
+ FragmentHandler.new(fragment, tags)
300
+ )
301
+ parser.parse(tags)
302
+ fragment
238
303
  end
239
304
 
240
305
  ####
241
306
  # Set the content to +string+.
242
- # If +encode+, encode any special characters first.
243
- def content= string, encode = true
307
+ def content= string
244
308
  self.native_content = encode_special_chars(string)
245
309
  end
246
310
 
@@ -251,22 +315,27 @@ module Nokogiri
251
315
  parent_node
252
316
  end
253
317
 
318
+ # Returns true if this is a Comment
254
319
  def comment?
255
320
  type == COMMENT_NODE
256
321
  end
257
322
 
323
+ # Returns true if this is a CDATA
258
324
  def cdata?
259
325
  type == CDATA_SECTION_NODE
260
326
  end
261
327
 
328
+ # Returns true if this is an XML::Document node
262
329
  def xml?
263
330
  type == DOCUMENT_NODE
264
331
  end
265
332
 
333
+ # Returns true if this is an HTML::Document node
266
334
  def html?
267
335
  type == HTML_DOCUMENT_NODE
268
336
  end
269
337
 
338
+ # Returns true if this is a Text node
270
339
  def text?
271
340
  type == TEXT_NODE
272
341
  end
@@ -276,6 +345,7 @@ module Nokogiri
276
345
  [NOTATION_NODE, ENTITY_NODE, ENTITY_DECL].include?(type)
277
346
  end
278
347
 
348
+ # Returns true if this is an Element node
279
349
  def element?
280
350
  type == ELEMENT_NODE
281
351
  end
@@ -289,6 +359,7 @@ module Nokogiri
289
359
  children.map { |x| x.to_html }.join
290
360
  end
291
361
 
362
+ # Get the path to this node as a CSS expression
292
363
  def css_path
293
364
  path.split(/\//).map { |part|
294
365
  part.length == 0 ? nil : part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)')
@@ -306,13 +377,12 @@ module Nokogiri
306
377
  ###
307
378
  # Get a list of ancestor Node for this Node
308
379
  def ancestors
309
- parents = []
380
+ return [] unless respond_to?(:parent)
310
381
 
311
- this_parent = self.parent
382
+ parents = [parent]
312
383
 
313
- while this_parent != nil
314
- parents << this_parent
315
- this_parent = this_parent.parent
384
+ while parents.last.respond_to?(:parent)
385
+ parents << parents.last.parent
316
386
  end
317
387
  parents
318
388
  end
@@ -327,7 +397,7 @@ module Nokogiri
327
397
  ####
328
398
  # replace node with the new node in the document.
329
399
  def replace(new_node)
330
- if new_node.is_a?(Document)
400
+ if new_node.is_a?(Document) || !new_node.is_a?(XML::Node)
331
401
  raise ArgumentError, <<-EOERR
332
402
  Node.replace requires a Node argument, and cannot accept a Document.
333
403
  (You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
@@ -428,8 +498,13 @@ Node.replace requires a Node argument, and cannot accept a Document.
428
498
  write_to io, encoding, SaveOptions::FORMAT | SaveOptions::AS_XML
429
499
  end
430
500
 
501
+ # Create a new node from +string+
502
+ #
503
+ # THIS METHOD IS DEPRECATED
504
+ # This method is deprecated and will be removed in 1.3.0 or by
505
+ # March 1, 2009. Instead, use Nokogiri::XML::Node#fragment()
431
506
  def self.new_from_str string
432
- $stderr.puts("This method is deprecated and will be removed in 1.2.0 or by March 1, 2009. Instead, use Nokogiri::HTML.fragment()")
507
+ $stderr.puts("This method is deprecated and will be removed in 1.3.0 or by March 1, 2009. Instead, use Nokogiri::XML::Node#fragment")
433
508
  Nokogiri::HTML.fragment(string).first
434
509
  end
435
510
  end