nokogiri 1.5.0.beta.2 → 1.5.0.beta.3

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 (107) hide show
  1. data/CHANGELOG.ja.rdoc +63 -0
  2. data/CHANGELOG.rdoc +44 -1
  3. data/Manifest.txt +3 -3
  4. data/README.ja.rdoc +4 -4
  5. data/README.rdoc +4 -4
  6. data/Rakefile +3 -0
  7. data/bin/nokogiri +6 -1
  8. data/ext/java/nokogiri/EncodingHandler.java +32 -0
  9. data/ext/java/nokogiri/HtmlDocument.java +36 -0
  10. data/ext/java/nokogiri/HtmlElementDescription.java +34 -0
  11. data/ext/java/nokogiri/HtmlEntityLookup.java +34 -0
  12. data/ext/java/nokogiri/HtmlSaxParserContext.java +41 -3
  13. data/ext/java/nokogiri/NokogiriService.java +109 -13
  14. data/ext/java/nokogiri/XmlAttr.java +40 -4
  15. data/ext/java/nokogiri/XmlAttributeDecl.java +32 -0
  16. data/ext/java/nokogiri/XmlCdata.java +41 -2
  17. data/ext/java/nokogiri/XmlComment.java +38 -1
  18. data/ext/java/nokogiri/XmlDocument.java +56 -11
  19. data/ext/java/nokogiri/XmlDocumentFragment.java +39 -30
  20. data/ext/java/nokogiri/XmlDtd.java +37 -0
  21. data/ext/java/nokogiri/XmlElement.java +51 -2
  22. data/ext/java/nokogiri/XmlElementContent.java +32 -0
  23. data/ext/java/nokogiri/XmlElementDecl.java +32 -0
  24. data/ext/java/nokogiri/XmlEntityDecl.java +32 -0
  25. data/ext/java/nokogiri/XmlEntityReference.java +35 -2
  26. data/ext/java/nokogiri/XmlNamespace.java +55 -5
  27. data/ext/java/nokogiri/XmlNode.java +129 -136
  28. data/ext/java/nokogiri/XmlNodeSet.java +36 -0
  29. data/ext/java/nokogiri/XmlProcessingInstruction.java +34 -1
  30. data/ext/java/nokogiri/XmlReader.java +36 -0
  31. data/ext/java/nokogiri/XmlRelaxng.java +34 -1
  32. data/ext/java/nokogiri/XmlSaxParserContext.java +52 -7
  33. data/ext/java/nokogiri/XmlSaxPushParser.java +36 -0
  34. data/ext/java/nokogiri/XmlSchema.java +34 -1
  35. data/ext/java/nokogiri/XmlSyntaxError.java +48 -18
  36. data/ext/java/nokogiri/XmlText.java +45 -6
  37. data/ext/java/nokogiri/XmlXpathContext.java +45 -0
  38. data/ext/java/nokogiri/XsltStylesheet.java +58 -3
  39. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +50 -26
  40. data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +35 -1
  41. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +51 -13
  42. data/ext/java/nokogiri/internals/NokogiriHandler.java +70 -21
  43. data/ext/java/nokogiri/internals/NokogiriHelpers.java +95 -38
  44. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +37 -3
  45. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +39 -1
  46. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +43 -7
  47. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +77 -10
  48. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +49 -20
  49. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +34 -2
  50. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +34 -1
  51. data/ext/java/nokogiri/internals/ParserContext.java +32 -0
  52. data/ext/java/nokogiri/internals/PushInputStream.java +33 -3
  53. data/ext/java/nokogiri/internals/ReaderNode.java +50 -8
  54. data/ext/java/nokogiri/internals/SaveContext.java +35 -2
  55. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +34 -1
  56. data/ext/java/nokogiri/internals/XmlDeclHandler.java +32 -0
  57. data/ext/java/nokogiri/internals/XmlDomParser.java +32 -0
  58. data/ext/java/nokogiri/internals/XmlDomParserContext.java +43 -11
  59. data/ext/java/nokogiri/internals/XmlSaxParser.java +32 -0
  60. data/ext/java/nokogiri/internals/XsltExtensionFunction.java +72 -0
  61. data/ext/nokogiri/depend +358 -32
  62. data/ext/nokogiri/extconf.rb +1 -3
  63. data/ext/nokogiri/nokogiri.c +2 -0
  64. data/ext/nokogiri/nokogiri.h +7 -0
  65. data/ext/nokogiri/xml_dtd.c +2 -2
  66. data/ext/nokogiri/xml_io.c +2 -2
  67. data/ext/nokogiri/xml_node.c +31 -6
  68. data/ext/nokogiri/xml_node_set.c +1 -1
  69. data/ext/nokogiri/xml_sax_parser.c +1 -1
  70. data/ext/nokogiri/xml_sax_parser_context.c +40 -0
  71. data/ext/nokogiri/xml_xpath_context.c +33 -2
  72. data/ext/nokogiri/xslt_stylesheet.c +122 -6
  73. data/lib/nokogiri.rb +12 -5
  74. data/lib/nokogiri/css/generated_tokenizer.rb +1 -2
  75. data/lib/nokogiri/css/xpath_visitor.rb +15 -7
  76. data/lib/nokogiri/decorators/slop.rb +5 -3
  77. data/lib/nokogiri/html/document.rb +3 -3
  78. data/lib/nokogiri/html/document_fragment.rb +19 -17
  79. data/lib/nokogiri/version.rb +1 -1
  80. data/lib/nokogiri/xml/document.rb +26 -1
  81. data/lib/nokogiri/xml/document_fragment.rb +2 -2
  82. data/lib/nokogiri/xml/dtd.rb +11 -0
  83. data/lib/nokogiri/xml/node.rb +156 -45
  84. data/lib/nokogiri/xml/node_set.rb +2 -2
  85. data/lib/nokogiri/xml/reader.rb +36 -0
  86. data/lib/nokogiri/xml/sax/document.rb +4 -2
  87. data/lib/nokogiri/xslt.rb +9 -5
  88. data/lib/nokogiri/xslt/stylesheet.rb +1 -1
  89. data/tasks/cross_compile.rb +27 -8
  90. data/test/css/test_parser.rb +29 -18
  91. data/test/decorators/test_slop.rb +16 -0
  92. data/test/html/test_document_fragment.rb +46 -3
  93. data/test/html/test_node.rb +9 -0
  94. data/test/xml/sax/test_parser.rb +11 -3
  95. data/test/xml/sax/test_parser_context.rb +50 -0
  96. data/test/xml/sax/test_push_parser.rb +18 -1
  97. data/test/xml/test_document_fragment.rb +15 -8
  98. data/test/xml/test_dtd.rb +15 -0
  99. data/test/xml/test_node.rb +31 -2
  100. data/test/xml/test_node_reparenting.rb +59 -31
  101. data/test/xml/test_node_set.rb +13 -0
  102. data/test/xml/test_xpath.rb +32 -0
  103. data/test/xslt/test_custom_functions.rb +94 -0
  104. metadata +83 -81
  105. data/lib/nokogiri/nokogiri.jar +0 -0
  106. data/spec/helper.rb +0 -3
  107. data/spec/xml/reader_spec.rb +0 -307
@@ -1,3 +1,35 @@
1
+ /**
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008 - 2010:
5
+ *
6
+ * * {Aaron Patterson}[http://tenderlovemaking.com]
7
+ * * {Mike Dalessio}[http://mike.daless.io]
8
+ * * {Charles Nutter}[http://blog.headius.com]
9
+ * * {Sergio Arbeo}[http://www.serabe.com]
10
+ * * {Patrick Mahoney}[http://polycrystal.org]
11
+ * * {Yoko Harada}[http://yokolet.blogspot.com]
12
+ *
13
+ * Permission is hereby granted, free of charge, to any person obtaining
14
+ * a copy of this software and associated documentation files (the
15
+ * 'Software'), to deal in the Software without restriction, including
16
+ * without limitation the rights to use, copy, modify, merge, publish,
17
+ * distribute, sublicense, and/or sell copies of the Software, and to
18
+ * permit persons to whom the Software is furnished to do so, subject to
19
+ * the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be
22
+ * included in all copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ */
32
+
1
33
  package nokogiri;
2
34
 
3
35
  import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
@@ -1,3 +1,35 @@
1
+ /**
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008 - 2010:
5
+ *
6
+ * * {Aaron Patterson}[http://tenderlovemaking.com]
7
+ * * {Mike Dalessio}[http://mike.daless.io]
8
+ * * {Charles Nutter}[http://blog.headius.com]
9
+ * * {Sergio Arbeo}[http://www.serabe.com]
10
+ * * {Patrick Mahoney}[http://polycrystal.org]
11
+ * * {Yoko Harada}[http://yokolet.blogspot.com]
12
+ *
13
+ * Permission is hereby granted, free of charge, to any person obtaining
14
+ * a copy of this software and associated documentation files (the
15
+ * 'Software'), to deal in the Software without restriction, including
16
+ * without limitation the rights to use, copy, modify, merge, publish,
17
+ * distribute, sublicense, and/or sell copies of the Software, and to
18
+ * permit persons to whom the Software is furnished to do so, subject to
19
+ * the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be
22
+ * included in all copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ */
32
+
1
33
  package nokogiri;
2
34
 
3
35
  import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
@@ -11,7 +43,8 @@ import org.w3c.dom.Document;
11
43
  import org.w3c.dom.Node;
12
44
 
13
45
  /**
14
- *
46
+ * Class for Nokogiri::XML::EntityReference
47
+ *
15
48
  * @author sergio
16
49
  * @author Patrick Mahoney <pat@polycrystal.org>
17
50
  */
@@ -36,7 +69,7 @@ public class XmlEntityReference extends XmlNode{
36
69
 
37
70
  Document document = ((XmlNode) doc).getOwnerDocument();
38
71
  Node node = document.createEntityReference(rubyStringToString(name));
39
- setNode(node);
72
+ setNode(context, node);
40
73
  }
41
74
 
42
75
  }
@@ -1,3 +1,35 @@
1
+ /**
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008 - 2010:
5
+ *
6
+ * * {Aaron Patterson}[http://tenderlovemaking.com]
7
+ * * {Mike Dalessio}[http://mike.daless.io]
8
+ * * {Charles Nutter}[http://blog.headius.com]
9
+ * * {Sergio Arbeo}[http://www.serabe.com]
10
+ * * {Patrick Mahoney}[http://polycrystal.org]
11
+ * * {Yoko Harada}[http://yokolet.blogspot.com]
12
+ *
13
+ * Permission is hereby granted, free of charge, to any person obtaining
14
+ * a copy of this software and associated documentation files (the
15
+ * 'Software'), to deal in the Software without restriction, including
16
+ * without limitation the rights to use, copy, modify, merge, publish,
17
+ * distribute, sublicense, and/or sell copies of the Software, and to
18
+ * permit persons to whom the Software is furnished to do so, subject to
19
+ * the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be
22
+ * included in all copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ */
32
+
1
33
  package nokogiri;
2
34
 
3
35
  import static nokogiri.internals.NokogiriHelpers.getLocalNameForNamespace;
@@ -7,6 +39,7 @@ import nokogiri.internals.SaveContext;
7
39
  import org.jruby.Ruby;
8
40
  import org.jruby.RubyClass;
9
41
  import org.jruby.RubyObject;
42
+ import org.jruby.RubyString;
10
43
  import org.jruby.anno.JRubyClass;
11
44
  import org.jruby.anno.JRubyMethod;
12
45
  import org.jruby.runtime.ThreadContext;
@@ -14,7 +47,8 @@ import org.jruby.runtime.builtin.IRubyObject;
14
47
  import org.w3c.dom.Node;
15
48
 
16
49
  /**
17
- *
50
+ * Class for Nokogiri::XML::Namespace
51
+ *
18
52
  * @author serabe
19
53
  */
20
54
  @JRubyClass(name="Nokogiri::XML::Namespace")
@@ -33,8 +67,8 @@ public class XmlNamespace extends RubyObject {
33
67
 
34
68
  public XmlNamespace(Ruby ruby, RubyClass klazz, String prefix, String href) {
35
69
  super(ruby, klazz);
36
- this.prefix = (prefix == null) ? ruby.getNil() : ruby.newString(prefix);
37
- this.href = (href == null) ? ruby.getNil() : ruby.newString(href);
70
+ this.prefix = (prefix == null) ? ruby.getNil() : RubyString.newString(ruby, prefix);
71
+ this.href = (href == null) ? ruby.getNil() : RubyString.newString(ruby, href);
38
72
  }
39
73
 
40
74
  public XmlNamespace(Ruby ruby, IRubyObject prefix, IRubyObject href) {
@@ -46,11 +80,27 @@ public class XmlNamespace extends RubyObject {
46
80
  this.prefix = prefix;
47
81
  this.href = href;
48
82
  }
83
+
84
+ public void setDefinition(Ruby runtime, String prefix, String href) {
85
+ this.prefix = (prefix == null) ? runtime.getNil() : RubyString.newString(runtime, prefix);
86
+ this.href = (href == null) ? runtime.getNil() : RubyString.newString(runtime, href);
87
+ }
88
+
89
+ /**
90
+ * Create and return a copy of this object.
91
+ *
92
+ * @return a clone of this object
93
+ */
94
+ @Override
95
+ public Object clone() throws CloneNotSupportedException {
96
+ return super.clone();
97
+ }
49
98
 
50
99
  public static XmlNamespace fromNode(Ruby ruby, Node node) {
51
100
  String localName = getLocalNameForNamespace(node.getNodeName());
52
-
53
- return new XmlNamespace(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Namespace"), localName, node.getNodeValue());
101
+ XmlNamespace namespace = (XmlNamespace) getNokogiriClass(ruby, "Nokogiri::XML::Namespace").allocate();
102
+ namespace.setDefinition(ruby, localName, node.getNodeValue());
103
+ return namespace;
54
104
  }
55
105
 
56
106
  public boolean isEmpty() {
@@ -1,3 +1,35 @@
1
+ /**
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008 - 2010:
5
+ *
6
+ * * {Aaron Patterson}[http://tenderlovemaking.com]
7
+ * * {Mike Dalessio}[http://mike.daless.io]
8
+ * * {Charles Nutter}[http://blog.headius.com]
9
+ * * {Sergio Arbeo}[http://www.serabe.com]
10
+ * * {Patrick Mahoney}[http://polycrystal.org]
11
+ * * {Yoko Harada}[http://yokolet.blogspot.com]
12
+ *
13
+ * Permission is hereby granted, free of charge, to any person obtaining
14
+ * a copy of this software and associated documentation files (the
15
+ * 'Software'), to deal in the Software without restriction, including
16
+ * without limitation the rights to use, copy, modify, merge, publish,
17
+ * distribute, sublicense, and/or sell copies of the Software, and to
18
+ * permit persons to whom the Software is furnished to do so, subject to
19
+ * the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be
22
+ * included in all copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ */
32
+
1
33
  package nokogiri;
2
34
 
3
35
  import static java.lang.Math.max;
@@ -12,17 +44,16 @@ import java.io.ByteArrayInputStream;
12
44
  import java.io.InputStream;
13
45
  import java.util.ArrayList;
14
46
  import java.util.List;
15
- import java.util.regex.Matcher;
16
47
 
17
48
  import nokogiri.internals.HtmlDomParserContext;
18
49
  import nokogiri.internals.NokogiriHelpers;
19
50
  import nokogiri.internals.NokogiriNamespaceCache;
20
- import nokogiri.internals.NokogiriNamespaceContext;
21
51
  import nokogiri.internals.SaveContext;
22
52
  import nokogiri.internals.XmlDomParserContext;
23
53
 
24
54
  import org.jruby.Ruby;
25
55
  import org.jruby.RubyArray;
56
+ import org.jruby.RubyBoolean;
26
57
  import org.jruby.RubyClass;
27
58
  import org.jruby.RubyFixnum;
28
59
  import org.jruby.RubyModule;
@@ -30,7 +61,6 @@ import org.jruby.RubyObject;
30
61
  import org.jruby.RubyString;
31
62
  import org.jruby.anno.JRubyClass;
32
63
  import org.jruby.anno.JRubyMethod;
33
- import org.jruby.javasupport.JavaUtil;
34
64
  import org.jruby.javasupport.util.RuntimeHelpers;
35
65
  import org.jruby.runtime.Block;
36
66
  import org.jruby.runtime.ThreadContext;
@@ -44,6 +74,10 @@ import org.w3c.dom.Node;
44
74
  import org.w3c.dom.NodeList;
45
75
  import org.w3c.dom.Text;
46
76
 
77
+ /**
78
+ * Class for Nokogiri::XML::Node
79
+ *
80
+ */
47
81
  @JRubyClass(name="Nokogiri::XML::Node")
48
82
  public class XmlNode extends RubyObject {
49
83
 
@@ -156,7 +190,7 @@ public class XmlNode extends RubyObject {
156
190
  * called from Ruby code.
157
191
  */
158
192
  public XmlNode(Ruby ruby, RubyClass cls) {
159
- this(ruby, cls, null);
193
+ super(ruby, cls);
160
194
  }
161
195
 
162
196
  /**
@@ -178,9 +212,20 @@ public class XmlNode extends RubyObject {
178
212
  }
179
213
  }
180
214
  }
215
+
216
+ }
217
+
218
+ /**
219
+ * Create and return a copy of this object.
220
+ *
221
+ * @return a clone of this object
222
+ */
223
+ @Override
224
+ public Object clone() throws CloneNotSupportedException {
225
+ return super.clone();
181
226
  }
182
227
 
183
- private void resetCache() {
228
+ protected void resetCache() {
184
229
  node.setUserData(NokogiriHelpers.CACHED_NODE, this, null);
185
230
  }
186
231
 
@@ -231,12 +276,12 @@ public class XmlNode extends RubyObject {
231
276
  klazz = getNokogiriClass(ruby, "Nokogiri::XML::Element");
232
277
  }
233
278
 
234
- XmlNode node = (XmlNode) klazz.allocate();
235
- node.init(context, args);
236
- node.callInit(args, block);
237
- if (node.node == null) System.out.println("NODE IS NULL");
238
- if (block.isGiven()) block.call(context, node);
239
- return node;
279
+ XmlNode xmlNode = (XmlNode) klazz.allocate();
280
+ xmlNode.init(context, args);
281
+ xmlNode.callInit(args, block);
282
+ if (xmlNode.node == null) context.getRuntime().newRuntimeError("NODE IS NULL");
283
+ if (block.isGiven()) block.call(context, xmlNode);
284
+ return xmlNode;
240
285
  }
241
286
 
242
287
  /**
@@ -266,14 +311,9 @@ public class XmlNode extends RubyObject {
266
311
  if (document == null) {
267
312
  throw getRuntime().newArgumentError("node must have owner document");
268
313
  }
269
- XmlDocument xmlDoc =
270
- (XmlDocument) getCachedNodeOrCreate(getRuntime(), document);
271
314
 
272
- Element element =
273
- document.createElementNS(null, rubyStringToString(name));
274
- setNode(element);
275
- setDocument(xmlDoc);
276
- RuntimeHelpers.invoke(context, xmlDoc, "decorate", this);
315
+ Element element = document.createElementNS(null, rubyStringToString(name));
316
+ setNode(context, element);
277
317
  }
278
318
 
279
319
  /**
@@ -313,7 +353,7 @@ public class XmlNode extends RubyObject {
313
353
 
314
354
  String curLine;
315
355
  boolean closingTag = false;
316
- String indentString = (String)indentStringObject.toJava(String.class);
356
+ String indentString = rubyStringToString(indentStringObject);
317
357
  int lengthInd = indentString.length();
318
358
  StringBuffer curInd = new StringBuffer();
319
359
 
@@ -394,25 +434,35 @@ public class XmlNode extends RubyObject {
394
434
  this.name = name;
395
435
  }
396
436
 
397
- public void setDocument(IRubyObject doc) {
437
+ public void setDocument(ThreadContext context, IRubyObject doc) {
398
438
  this.doc = doc;
439
+ setInstanceVariable("@document", doc);
440
+ if (doc != null) {
441
+ RuntimeHelpers.invoke(context, doc, "decorate", this);
442
+ }
399
443
  }
400
444
 
401
- protected void setNode(Node node) {
445
+ public void setNode(ThreadContext context, Node node) {
402
446
  this.node = node;
403
- resetCache();
447
+
448
+ if (node != null) {
449
+ resetCache();
450
+ if (node.getNodeType() != Node.DOCUMENT_NODE) {
451
+ doc = document(context);
452
+ }
453
+ }
404
454
  }
405
455
 
406
456
  public void updateNodeNamespaceIfNecessary(ThreadContext context, XmlNamespace ns) {
407
457
  String oldPrefix = this.node.getPrefix();
408
- String uri = (String)ns.href(context).toJava(String.class);
458
+ String uri = rubyStringToString(ns.href(context));
409
459
 
410
460
  /*
411
461
  * Update if both prefixes are null or equal
412
462
  */
413
463
  boolean update = (oldPrefix == null && ns.prefix(context).isNil()) ||
414
464
  (oldPrefix != null && !ns.prefix(context).isNil()
415
- && oldPrefix.equals((String)ns.prefix(context).toJava(String.class)));
465
+ && oldPrefix.equals(rubyStringToString(ns.prefix(context))));
416
466
 
417
467
  if(update) {
418
468
  this.node.getOwnerDocument().renameNode(this.node, uri, this.node.getNodeName());
@@ -428,7 +478,7 @@ public class XmlNode extends RubyObject {
428
478
  str = NokogiriHelpers.getLocalPart(str);
429
479
  }
430
480
  if (str == null) str = "";
431
- name = JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), str);
481
+ name = context.getRuntime().newString(str);
432
482
  return name;
433
483
  }
434
484
 
@@ -488,7 +538,7 @@ public class XmlNode extends RubyObject {
488
538
  @JRubyMethod(name = {"attribute", "attr"})
489
539
  public IRubyObject attribute(ThreadContext context, IRubyObject name){
490
540
  NamedNodeMap attrs = this.node.getAttributes();
491
- Node attr = attrs.getNamedItem((String)name.toJava(String.class));
541
+ Node attr = attrs.getNamedItem(rubyStringToString(name));
492
542
  if(attr == null) {
493
543
  return context.getRuntime().newString(ERR_INSECURE_SET_INST_VAR);
494
544
  }
@@ -517,8 +567,8 @@ public class XmlNode extends RubyObject {
517
567
 
518
568
  @JRubyMethod
519
569
  public IRubyObject attribute_with_ns(ThreadContext context, IRubyObject name, IRubyObject namespace) {
520
- String namej = (String)name.toJava(String.class);
521
- String nsj = (namespace.isNil()) ? null : (String)namespace.toJava(String.class);
570
+ String namej = rubyStringToString(name);
571
+ String nsj = (namespace.isNil()) ? null : rubyStringToString(namespace);
522
572
 
523
573
  Node el = this.node.getAttributes().getNamedItemNS(nsj, namej);
524
574
 
@@ -581,7 +631,6 @@ public class XmlNode extends RubyObject {
581
631
  nodes.add(child);
582
632
  if (isFirstOnly) return;
583
633
  }
584
- addElements(child, nodes, isFirstOnly);
585
634
  }
586
635
  }
587
636
 
@@ -626,7 +675,7 @@ public class XmlNode extends RubyObject {
626
675
  * 'in_context' is supposed to do. Also should take
627
676
  * <code>options</code> into account.
628
677
  */
629
- @JRubyMethod(visibility=Visibility.PRIVATE)
678
+ @JRubyMethod(required = 2, visibility = Visibility.PRIVATE)
630
679
  public IRubyObject in_context(ThreadContext context,
631
680
  IRubyObject str,
632
681
  IRubyObject options) {
@@ -636,94 +685,76 @@ public class XmlNode extends RubyObject {
636
685
  XmlDocument document;
637
686
 
638
687
  IRubyObject d = document(context);
688
+ Ruby runtime = context.getRuntime();
639
689
  if (d != null && d instanceof XmlDocument) {
640
690
  document = (XmlDocument)d;
641
691
  } else {
642
- return context.getRuntime().getNil();
692
+ return runtime.getNil();
643
693
  }
644
694
 
645
695
  if (document instanceof HtmlDocument) {
646
- klass = getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::Document");
647
- ctx = new HtmlDomParserContext(context.getRuntime(), options);
696
+ klass = getNokogiriClass(runtime, "Nokogiri::HTML::Document");
697
+ ctx = new HtmlDomParserContext(runtime, options);
648
698
  ((HtmlDomParserContext)ctx).enableDocumentFragment();
649
- istream = new ByteArrayInputStream(((String)str.toJava(String.class)).getBytes());
699
+ istream = new ByteArrayInputStream((rubyStringToString(str)).getBytes());
650
700
  } else if (document instanceof XmlDocument) {
651
- klass = getNokogiriClass(context.getRuntime(), "Nokogiri::XML::Document");
652
- ctx = new XmlDomParserContext(context.getRuntime(), options);
653
- String input = addTemporaryRootTagIfNecessary(context, (String)str.toJava(String.class));
701
+ klass = getNokogiriClass(runtime, "Nokogiri::XML::Document");
702
+ ctx = new XmlDomParserContext(runtime, options);
703
+ String input = rubyStringToString(str);
654
704
  istream = new ByteArrayInputStream(input.getBytes());
655
705
  } else {
656
- return context.getRuntime().getNil();
706
+ return runtime.getNil();
657
707
  }
658
708
 
659
709
  ctx.setInputSource(istream);
660
- XmlDocument doc = ctx.parse(context, klass, getRuntime().getNil());
710
+ XmlDocument doc = ctx.parse(context, klass, runtime.getNil());
711
+
712
+ RubyArray documentErrors = getErrorArray(document);
713
+ RubyArray docErrors = getErrorArray(doc);
714
+ if (isErrorIncreated(documentErrors, docErrors)) {
715
+ for (int i = 0; i < docErrors.getLength(); i++) {
716
+ documentErrors.add(docErrors.get(i));
717
+ }
718
+ document.setInstanceVariable("@errors", documentErrors);
719
+ return new XmlNodeSet(getRuntime(), RubyArray.newArray(runtime));
720
+ }
661
721
 
662
- if (isErrorIncreated(document, doc)) {
663
- saveErrorsOfCreatedDocument(document, doc);
664
- return new XmlNodeSet(getRuntime(), RubyArray.newArray(context.getRuntime()));
722
+ // The first child might be document type node (dtd declaration).
723
+ // XmlNodeSet to be return should not have dtd decl in its list.
724
+ Node first;
725
+ if (doc.node.getFirstChild().getNodeType() == Node.DOCUMENT_TYPE_NODE) {
726
+ first = doc.node.getFirstChild().getNextSibling();
727
+ } else {
728
+ first = doc.node.getFirstChild();
665
729
  }
666
- NodeList childNodes = removeTemporaryRootIfNecessary(doc.node.getChildNodes());
667
- XmlNodeSet nodes = new XmlNodeSet(getRuntime(), childNodes);
730
+ RubyArray nodeArray = RubyArray.newArray(runtime);
731
+ nodeArray.add(NokogiriHelpers.getCachedNodeOrCreate(runtime, first));
732
+
733
+ NokogiriHelpers.nodeListToRubyArray(runtime, first.getChildNodes(), nodeArray);
734
+ XmlNodeSet nodes = new XmlNodeSet(getRuntime(), nodeArray);
668
735
  return nodes;
669
736
  }
670
737
 
671
- private int getErrorNumbers(XmlDocument document) {
738
+ private RubyArray getErrorArray(XmlDocument document) {
672
739
  IRubyObject obj = document.getInstanceVariable("@errors");
673
740
  if (obj != null && obj instanceof RubyArray) {
674
- return ((RubyArray)obj).getLength();
741
+ return (RubyArray)obj;
675
742
  }
676
- return 0;
743
+ return RubyArray.newArray(document.getRuntime());
677
744
  }
678
-
679
- private boolean isErrorIncreated(XmlDocument base, XmlDocument created) {
680
- int baseDocumentErrors = getErrorNumbers(base);
681
- int createdDocumentErrors = getErrorNumbers(created);
682
- return createdDocumentErrors > baseDocumentErrors;
683
- }
684
-
685
- private void saveErrorsOfCreatedDocument(XmlDocument base, XmlDocument created) {
686
- RubyArray newErrors = (RubyArray)created.getInstanceVariable("@errors");
687
- RubyArray existingErrors = null;
688
- IRubyObject obj = base.getInstanceVariable("@errors");
689
- if (obj != null && obj instanceof RubyArray) {
690
- existingErrors = (RubyArray)obj;
691
- } else {
692
- existingErrors = RubyArray.newArray(base.getRuntime());
693
- }
694
- for (int i=0; i<newErrors.getLength(); i++) {
695
- existingErrors.add(newErrors.get(i));
696
- }
697
- base.setInstanceVariable("@errors", existingErrors);
698
- }
699
-
700
- private String addTemporaryRootTagIfNecessary(ThreadContext context, String tags) {
701
- Matcher matcher = XmlDocumentFragment.wellformed_pattern.matcher(tags);
702
- while(matcher.find()) {
703
- if (matcher.start() == 0 && matcher.end() == tags.length()) return tags;
704
- break;
705
- }
706
- tags = "<"+ NokogiriNamespaceContext.NOKOGIRI_TEMPORARY_ROOT_TAG + ">" + tags + "</" + NokogiriNamespaceContext.NOKOGIRI_TEMPORARY_ROOT_TAG + ">";
707
- return tags;
708
- }
709
-
710
- private NodeList removeTemporaryRootIfNecessary(NodeList nodes) {
711
- if (nodes != null && nodes.getLength() > 0) {
712
- Node n = nodes.item(0);
713
- if (n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().equals(NokogiriNamespaceContext.NOKOGIRI_TEMPORARY_ROOT_TAG)) {
714
- return n.getChildNodes();
715
- }
716
- }
717
- return nodes;
745
+
746
+ private boolean isErrorIncreated(RubyArray baseErrors, RubyArray createdErrors) {
747
+ RubyBoolean result = baseErrors.compare(baseErrors.getRuntime().getCurrentContext(), "eql?", createdErrors, null);
748
+ return result.isFalse();
718
749
  }
719
750
 
720
751
  @JRubyMethod(name = {"content", "text", "inner_text"})
721
752
  public IRubyObject content(ThreadContext context) {
722
753
  if (content != null && content.isNil()) return content;
723
754
  String textContent;
724
- if (content != null) textContent = (String)content.toJava(String.class);
755
+ if (content != null) textContent = rubyStringToString(content);
725
756
  else if (this instanceof XmlDocument) {
726
- textContent = this.node.getChildNodes().item(0).getTextContent();
757
+ textContent = ((Document)this.node).getDocumentElement().getTextContent().trim();
727
758
  } else {
728
759
  textContent = this.node.getTextContent();
729
760
  }
@@ -759,7 +790,7 @@ public class XmlNode extends RubyObject {
759
790
  } catch (CloneNotSupportedException e) {
760
791
  throw context.getRuntime().newRuntimeError(e.toString());
761
792
  }
762
- if (node == null) throw getRuntime().newRuntimeError("FFFFFFFFFUUUUUUU");
793
+ if (node == null) throw context.getRuntime().newRuntimeError("FFFFFFFFFUUUUUUU");
763
794
  Node newNode = node.cloneNode(deep);
764
795
  clone.node = newNode;
765
796
  return clone;
@@ -767,7 +798,7 @@ public class XmlNode extends RubyObject {
767
798
 
768
799
  public static IRubyObject encode_special_chars(ThreadContext context,
769
800
  IRubyObject string) {
770
- String s = (String)string.toJava(String.class);
801
+ String s = rubyStringToString(string);
771
802
  String enc = NokogiriHelpers.encodeJavaString(s);
772
803
  return context.getRuntime().newString(enc);
773
804
  }
@@ -945,7 +976,7 @@ public class XmlNode extends RubyObject {
945
976
 
946
977
  protected void setContent(IRubyObject content) {
947
978
  this.content = content;
948
- this.node.setTextContent((String)content.toJava(String.class));
979
+ this.node.setTextContent(rubyStringToString(content));
949
980
  }
950
981
 
951
982
  private void setContent(String content) {
@@ -974,10 +1005,10 @@ public class XmlNode extends RubyObject {
974
1005
  IRubyObject indentString = args[2];
975
1006
  IRubyObject options = args[3];
976
1007
 
977
- String encString = encoding.isNil() ? null : (String)encoding.toJava(String.class);
1008
+ String encString = encoding.isNil() ? null : rubyStringToString(encoding);
978
1009
 
979
1010
  SaveContext ctx = new SaveContext(context, (Integer)options.toJava(Integer.class),
980
- (String)indentString.toJava(String.class),
1011
+ rubyStringToString(indentString),
981
1012
  encString);
982
1013
 
983
1014
  saveContent(context, ctx);
@@ -1012,7 +1043,7 @@ public class XmlNode extends RubyObject {
1012
1043
 
1013
1044
  @JRubyMethod(name = {"node_name=", "name="})
1014
1045
  public IRubyObject node_name_set(ThreadContext context, IRubyObject nodeName) {
1015
- String newName = (String)nodeName.toJava(String.class);
1046
+ String newName = rubyStringToString(nodeName);
1016
1047
  getOwnerDocument().renameNode(node, null, newName);
1017
1048
  setName(nodeName);
1018
1049
  return this;
@@ -1064,8 +1095,8 @@ public class XmlNode extends RubyObject {
1064
1095
  }
1065
1096
  } else {
1066
1097
  XmlNamespace ns = (XmlNamespace) namespace;
1067
- String prefix = (String)ns.prefix(context).toJava(String.class);
1068
- String href = (String)ns.href(context).toJava(String.class);
1098
+ String prefix = rubyStringToString(ns.prefix(context));
1099
+ String href = rubyStringToString(ns.href(context));
1069
1100
 
1070
1101
  // Assigning node = ...renameNode() or not seems to make no
1071
1102
  // difference. Why not? -pmahoney
@@ -1191,7 +1222,7 @@ public class XmlNode extends RubyObject {
1191
1222
  XmlNode other = asXmlNode(context, other_);
1192
1223
  // this.doc might be null since this node can be empty node.
1193
1224
  if (this.doc != null) {
1194
- other.doc = this.doc;
1225
+ other.setDocument(context, this.doc);
1195
1226
  }
1196
1227
  IRubyObject nodeOrTags = other;
1197
1228
  Node thisNode = node;
@@ -1243,10 +1274,6 @@ public class XmlNode extends RubyObject {
1243
1274
 
1244
1275
  protected Node[] adoptAsChild(ThreadContext context, Node parent,
1245
1276
  Node otherNode) {
1246
- if (hasTemporaryRoot(parent, otherNode)) {
1247
- return adoptRealChildrenAsChild(context, parent, otherNode);
1248
- }
1249
-
1250
1277
  /*
1251
1278
  * This is a bit of a hack. C-Nokogiri allows adding a bare
1252
1279
  * text node as the root element. Java (and XML spec?) does
@@ -1264,40 +1291,6 @@ public class XmlNode extends RubyObject {
1264
1291
  nodes[0] = otherNode;
1265
1292
  return nodes;
1266
1293
  }
1267
-
1268
- private boolean hasTemporaryRoot(Node parent, Node child) {
1269
- if (parent.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE
1270
- && child.getNodeName().equals(NokogiriNamespaceContext.NOKOGIRI_TEMPORARY_ROOT_TAG)) {
1271
- return true;
1272
- }
1273
- return false;
1274
- }
1275
-
1276
- private Node[] adoptRealChildrenAsChild(ThreadContext context, Node parent, Node otherNode) {
1277
- NodeList children = otherNode.getChildNodes();
1278
- int length = children.getLength();
1279
- List<Node> nodes = new ArrayList<Node>();
1280
- for (int i=0; i < length; i++) {
1281
- nodes.add(children.item(i).cloneNode(true));
1282
- }
1283
- //cut out leading and trailing whitespaces
1284
- if (nodes.get(0).getNodeType() == Node.TEXT_NODE && nodes.get(0).getTextContent().trim().length() == 0) {
1285
- nodes.remove(0);
1286
- }
1287
- int lastIndex = nodes.size() - 1;
1288
- if (nodes.get(lastIndex).getNodeType() == Node.TEXT_NODE && nodes.get(lastIndex).getTextContent().trim().length() == 0) {
1289
- nodes.remove(lastIndex);
1290
- }
1291
-
1292
- Node[] nodeArray = new Node[nodes.size()];
1293
- for (int i=0; i < nodeArray.length; i++) {
1294
- Node child = nodes.get(i);
1295
- addNamespaceURIIfNeeded(child);
1296
- parent.appendChild(child);
1297
- nodeArray[i] = child;
1298
- }
1299
- return nodeArray;
1300
- }
1301
1294
 
1302
1295
  private void addNamespaceURIIfNeeded(Node child) {
1303
1296
  if (this instanceof XmlDocumentFragment && ((XmlDocumentFragment)this).getFragmentContext() != null) {