nokogiri 1.6.7.2-java → 1.6.8-java
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.
- checksums.yaml +4 -4
- data/.cross_rubies +2 -0
- data/.travis.yml +19 -9
- data/CHANGELOG.rdoc +73 -5
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +10 -9
- data/LICENSE.txt +1 -1
- data/Manifest.txt +7 -2
- data/README.md +23 -27
- data/ROADMAP.md +11 -1
- data/Rakefile +36 -17
- data/bin/nokogiri +2 -2
- data/dependencies.yml +29 -4
- data/ext/java/nokogiri/HtmlElementDescription.java +5 -2
- data/ext/java/nokogiri/NokogiriService.java +19 -0
- data/ext/java/nokogiri/XmlAttr.java +3 -1
- data/ext/java/nokogiri/XmlDocumentFragment.java +0 -14
- data/ext/java/nokogiri/XmlNode.java +106 -63
- data/ext/java/nokogiri/XmlXpathContext.java +12 -12
- data/ext/java/nokogiri/XsltStylesheet.java +11 -4
- data/ext/java/nokogiri/internals/HtmlDomParserContext.java +8 -1
- data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +1 -2
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +7 -7
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +1 -1
- data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +0 -1
- data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +3 -3
- data/ext/java/nokogiri/internals/ParserContext.java +4 -0
- data/ext/java/nokogiri/internals/SaveContextVisitor.java +18 -13
- data/ext/nokogiri/extconf.rb +163 -79
- data/ext/nokogiri/html_document.c +6 -6
- data/ext/nokogiri/html_element_description.c +1 -1
- data/ext/nokogiri/html_entity_lookup.c +1 -1
- data/ext/nokogiri/html_sax_parser_context.c +4 -4
- data/ext/nokogiri/html_sax_push_parser.c +2 -2
- data/ext/nokogiri/nokogiri.c +0 -7
- data/ext/nokogiri/nokogiri.h +1 -34
- data/ext/nokogiri/xml_attr.c +2 -2
- data/ext/nokogiri/xml_comment.c +1 -1
- data/ext/nokogiri/xml_document.c +20 -22
- data/ext/nokogiri/xml_encoding_handler.c +3 -3
- data/ext/nokogiri/xml_entity_reference.c +1 -1
- data/ext/nokogiri/xml_namespace.c +56 -17
- data/ext/nokogiri/xml_node.c +73 -67
- data/ext/nokogiri/xml_node_set.c +164 -146
- data/ext/nokogiri/xml_node_set.h +3 -4
- data/ext/nokogiri/xml_processing_instruction.c +2 -2
- data/ext/nokogiri/xml_reader.c +5 -18
- data/ext/nokogiri/xml_sax_parser.c +9 -12
- data/ext/nokogiri/xml_sax_parser_context.c +1 -1
- data/ext/nokogiri/xml_sax_push_parser.c +1 -1
- data/ext/nokogiri/xml_schema.c +1 -1
- data/ext/nokogiri/xml_syntax_error.c +0 -4
- data/ext/nokogiri/xml_syntax_error.h +0 -1
- data/ext/nokogiri/xml_text.c +1 -1
- data/ext/nokogiri/xml_xpath_context.c +15 -24
- data/ext/nokogiri/xslt_stylesheet.c +6 -6
- data/lib/nekohtml.jar +0 -0
- data/lib/nokogiri.rb +14 -7
- data/lib/nokogiri/css/parser.rb +8 -2
- data/lib/nokogiri/css/parser.y +7 -2
- data/lib/nokogiri/html/document.rb +4 -2
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml/document.rb +7 -1
- data/lib/nokogiri/xml/dtd.rb +4 -4
- data/lib/nokogiri/xml/node.rb +6 -10
- data/lib/nokogiri/xml/node_set.rb +3 -3
- data/lib/nokogiri/xml/parse_options.rb +22 -0
- data/lib/serializer.jar +0 -0
- data/lib/xalan.jar +0 -0
- data/lib/xercesImpl.jar +0 -0
- data/lib/xml-apis.jar +0 -0
- data/tasks/test.rb +5 -0
- data/test/css/test_parser.rb +7 -1
- data/test/files/GH_1042.html +18 -0
- data/test/files/namespace_pressure_test.xml +1684 -0
- data/test/files/tlm.html +2 -1
- data/test/helper.rb +4 -0
- data/test/html/sax/test_parser.rb +2 -2
- data/test/html/test_document.rb +47 -11
- data/test/html/test_document_encoding.rb +55 -58
- data/test/html/test_document_fragment.rb +27 -23
- data/test/html/test_node.rb +16 -0
- data/test/html/test_node_encoding.rb +71 -13
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +14 -0
- data/test/test_css_cache.rb +1 -1
- data/test/test_encoding_handler.rb +2 -0
- data/test/test_xslt_transforms.rb +38 -3
- data/test/xml/sax/test_parser.rb +54 -53
- data/test/xml/test_document.rb +7 -2
- data/test/xml/test_document_encoding.rb +19 -16
- data/test/xml/test_document_fragment.rb +12 -0
- data/test/xml/test_dtd_encoding.rb +0 -2
- data/test/xml/test_namespace.rb +2 -2
- data/test/xml/test_node.rb +15 -4
- data/test/xml/test_node_attributes.rb +6 -0
- data/test/xml/test_node_encoding.rb +49 -87
- data/test/xml/test_node_reparenting.rb +193 -18
- data/test/xml/test_node_set.rb +1 -1
- data/test/xml/test_reader.rb +589 -0
- data/test/xml/test_reader_encoding.rb +100 -102
- data/test/xml/test_unparented_node.rb +14 -1
- data/test/xslt/test_exception_handling.rb +1 -1
- data/test_all +47 -33
- metadata +38 -36
- data/CHANGELOG.ja.rdoc +0 -1057
- data/test/test_reader.rb +0 -558
data/bin/nokogiri
CHANGED
@@ -41,9 +41,9 @@ opts = OptionParser.new do |opts|
|
|
41
41
|
opts.define_head "Usage: nokogiri <uri|path> [options]"
|
42
42
|
opts.separator ""
|
43
43
|
opts.separator "Examples:"
|
44
|
-
opts.separator " nokogiri
|
44
|
+
opts.separator " nokogiri https://www.ruby-lang.org/"
|
45
45
|
opts.separator " nokogiri ./public/index.html"
|
46
|
-
opts.separator " curl -s http://nokogiri.org | nokogiri -e'p $_.css(\"h1\").length'"
|
46
|
+
opts.separator " curl -s http://www.nokogiri.org | nokogiri -e'p $_.css(\"h1\").length'"
|
47
47
|
opts.separator ""
|
48
48
|
opts.separator "Options:"
|
49
49
|
|
data/dependencies.yml
CHANGED
@@ -1,4 +1,29 @@
|
|
1
|
-
libxml2:
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
libxml2:
|
2
|
+
version: "2.9.4"
|
3
|
+
md5: "ae249165c173b1ff386ee8ad676815f5" # manually confirmed via `gpg --verify`
|
4
|
+
# gpg: Signature made Mon 23 May 2016 04:02:13 AM EDT using DSA key ID DE95BC1F
|
5
|
+
# gpg: Good signature from "Daniel Veillard (Red Hat work email) <veillard@redhat.com>"
|
6
|
+
# gpg: aka "Daniel Veillard <Daniel.Veillard@w3.org>"
|
7
|
+
# gpg: WARNING: This key is not certified with a trusted signature!
|
8
|
+
# gpg: There is no indication that the signature belongs to the owner.
|
9
|
+
# Primary key fingerprint: C744 15BA 7C9C 7F78 F02E 1DC3 4606 B8A5 DE95 BC1F
|
10
|
+
|
11
|
+
libxslt:
|
12
|
+
version: "1.1.29"
|
13
|
+
md5: "a129d3c44c022de3b9dcf6d6f288d72e"
|
14
|
+
# gpg: Signature made Mon 23 May 2016 09:58:52 PM EDT using DSA key ID DE95BC1F
|
15
|
+
# gpg: Good signature from "Daniel Veillard (Red Hat work email) <veillard@redhat.com>"
|
16
|
+
# gpg: aka "Daniel Veillard <Daniel.Veillard@w3.org>"
|
17
|
+
# gpg: WARNING: This key is not certified with a trusted signature!
|
18
|
+
# gpg: There is no indication that the signature belongs to the owner.
|
19
|
+
# Primary key fingerprint: C744 15BA 7C9C 7F78 F02E 1DC3 4606 B8A5 DE95 BC1F
|
20
|
+
|
21
|
+
zlib:
|
22
|
+
version: "1.2.8"
|
23
|
+
md5: "44d667c142d7cda120332623eab69f40"
|
24
|
+
|
25
|
+
libiconv:
|
26
|
+
version: "1.14"
|
27
|
+
md5: "e34509b1623cec449dfeb73d7ce9c6c6"
|
28
|
+
# gpg: Signature made Sun 07 Aug 2011 01:58:18 PM EDT using DSA key ID F059B1D1
|
29
|
+
# gpg: BAD signature from "Bruno Haible (Open Source Development) <bruno@clisp.org>"
|
@@ -105,9 +105,12 @@ public class HtmlElementDescription extends RubyObject {
|
|
105
105
|
public static IRubyObject get(ThreadContext context,
|
106
106
|
IRubyObject klazz, IRubyObject name) {
|
107
107
|
|
108
|
-
|
108
|
+
// nekohtml will return an element even for invalid names, see
|
109
|
+
// http://sourceforge.net/p/nekohtml/code/HEAD/tree/trunk/src/org/cyberneko/html/HTMLElements.java#l514
|
110
|
+
// which breaks `test_fetch_nonexistent'
|
111
|
+
HTMLElements.Element elem = HTMLElements.getElement(name.asJavaString(), HTMLElements.NO_SUCH_ELEMENT);
|
109
112
|
if (elem == HTMLElements.NO_SUCH_ELEMENT)
|
110
|
-
return context.
|
113
|
+
return context.nil;
|
111
114
|
|
112
115
|
HtmlElementDescription desc =
|
113
116
|
new HtmlElementDescription(context.getRuntime(), (RubyClass)klazz);
|
@@ -36,6 +36,7 @@ import java.util.Collections;
|
|
36
36
|
import java.util.HashMap;
|
37
37
|
import java.util.Map;
|
38
38
|
|
39
|
+
import org.cyberneko.html.HTMLElements;
|
39
40
|
import org.jruby.Ruby;
|
40
41
|
import org.jruby.RubyArray;
|
41
42
|
import org.jruby.RubyClass;
|
@@ -53,6 +54,24 @@ import org.jruby.runtime.load.BasicLibraryService;
|
|
53
54
|
* @author Yoko Harada <yokolet@gmail.com>
|
54
55
|
*/
|
55
56
|
public class NokogiriService implements BasicLibraryService {
|
57
|
+
|
58
|
+
// nekohtml from version 1.9.13 they autocomplete tbody around
|
59
|
+
// tr tags of a table - http://sourceforge.net/p/nekohtml/code/241/
|
60
|
+
// this monkey patch undoes this autocompletion
|
61
|
+
static class MonkeyPatchHTMLElements extends HTMLElements {
|
62
|
+
static void patchIt() {
|
63
|
+
Element[] array = ELEMENTS_ARRAY['T'-'A'];
|
64
|
+
for(int i = 0; i < array.length; i++) {
|
65
|
+
if (array[i].name.equals("TR")) {
|
66
|
+
array[i] = new Element(TR, "TR", Element.BLOCK, TABLE, new short[]{TD,TH,TR,COLGROUP,DIV});
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
static {
|
72
|
+
MonkeyPatchHTMLElements.patchIt();
|
73
|
+
}
|
74
|
+
|
56
75
|
public static final String nokogiriClassCacheGvarName = "$NOKOGIRI_CLASS_CACHE";
|
57
76
|
|
58
77
|
public boolean basicLoad(Ruby ruby) {
|
@@ -164,7 +164,9 @@ public class XmlAttr extends XmlNode{
|
|
164
164
|
protected IRubyObject getNodeName(ThreadContext context) {
|
165
165
|
if (name != null) return name;
|
166
166
|
String attrName = ((Attr)node).getName();
|
167
|
-
if (!(doc instanceof HtmlDocument)
|
167
|
+
if (!(doc instanceof HtmlDocument) && node.getNamespaceURI() != null) {
|
168
|
+
attrName = NokogiriHelpers.getLocalPart(attrName);
|
169
|
+
}
|
168
170
|
return attrName == null ? context.getRuntime().getNil() : RubyString.newString(context.getRuntime(), attrName);
|
169
171
|
}
|
170
172
|
|
@@ -54,7 +54,6 @@ import org.jruby.javasupport.util.RuntimeHelpers;
|
|
54
54
|
import org.jruby.runtime.ThreadContext;
|
55
55
|
import org.jruby.runtime.builtin.IRubyObject;
|
56
56
|
import org.w3c.dom.Attr;
|
57
|
-
import org.w3c.dom.Document;
|
58
57
|
import org.w3c.dom.NamedNodeMap;
|
59
58
|
|
60
59
|
/**
|
@@ -90,7 +89,6 @@ public class XmlDocumentFragment extends XmlNode {
|
|
90
89
|
|
91
90
|
// make wellformed fragment, ignore invalid namespace, or add appropriate namespace to parse
|
92
91
|
if (args.length > 1 && args[1] instanceof RubyString) {
|
93
|
-
args[1] = trim(context, doc, (RubyString)args[1]);
|
94
92
|
if (XmlDocumentFragment.isTag((RubyString)args[1])) {
|
95
93
|
args[1] = RubyString.newString(context.getRuntime(), addNamespaceDeclIfNeeded(doc, rubyStringToString(args[1])));
|
96
94
|
}
|
@@ -107,18 +105,6 @@ public class XmlDocumentFragment extends XmlNode {
|
|
107
105
|
RuntimeHelpers.invoke(context, fragment, "initialize", args);
|
108
106
|
return fragment;
|
109
107
|
}
|
110
|
-
|
111
|
-
private static IRubyObject trim(ThreadContext context, XmlDocument xmlDocument, RubyString str) {
|
112
|
-
// checks whether schema is given. if exists, allows whitespace processing to a parser
|
113
|
-
Document document = (Document)xmlDocument.node;
|
114
|
-
if (document.getDoctype() != null) return str;
|
115
|
-
// strips trailing \n off forcefully
|
116
|
-
// not to return new object in case of no chomp needed, chomp! is used here.
|
117
|
-
IRubyObject result;
|
118
|
-
if (context.getRuntime().is1_9()) result = str.chomp_bang19(context);
|
119
|
-
else result = str.chomp_bang(context);
|
120
|
-
return result.isNil() ? str : result;
|
121
|
-
}
|
122
108
|
|
123
109
|
private static boolean isTag(RubyString ruby_string) {
|
124
110
|
String str = rubyStringToString(ruby_string);
|
@@ -333,15 +333,11 @@ public class XmlNode extends RubyObject {
|
|
333
333
|
Element element = null;
|
334
334
|
String node_name = rubyStringToString(name);
|
335
335
|
String prefix = NokogiriHelpers.getPrefix(node_name);
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
String namespace_uri = null;
|
340
|
-
if (document.getDocumentElement() != null) {
|
341
|
-
namespace_uri = document.getDocumentElement().lookupNamespaceURI(prefix);
|
342
|
-
}
|
343
|
-
element = document.createElementNS(namespace_uri, node_name);
|
336
|
+
String namespace_uri = null;
|
337
|
+
if (document.getDocumentElement() != null) {
|
338
|
+
namespace_uri = document.getDocumentElement().lookupNamespaceURI(prefix);
|
344
339
|
}
|
340
|
+
element = document.createElementNS(namespace_uri, node_name);
|
345
341
|
setNode(context, element);
|
346
342
|
}
|
347
343
|
|
@@ -454,57 +450,77 @@ public class XmlNode extends RubyObject {
|
|
454
450
|
public void post_add_child(ThreadContext context, XmlNode current, XmlNode child) {
|
455
451
|
}
|
456
452
|
|
453
|
+
/**
|
454
|
+
* This method should be called after a node has been adopted in a new
|
455
|
+
* document. This method will ensure that the node is renamed with the
|
456
|
+
* appriopriate NS uri. First the prefix of the node is extracted, then is
|
457
|
+
* used to lookup the namespace uri in the new document starting at the
|
458
|
+
* current node and traversing the ancestors. If the namespace uri wasn't
|
459
|
+
* empty (or null) all children and the node has attributes and/or children
|
460
|
+
* then the algorithm is recursively applied to the children.
|
461
|
+
*/
|
457
462
|
public void relink_namespace(ThreadContext context) {
|
458
|
-
if (node instanceof Element) {
|
459
|
-
|
460
|
-
|
461
|
-
String prefix = e.getPrefix();
|
462
|
-
String currentNS = e.getNamespaceURI();
|
463
|
-
if (prefix == null && currentNS == null) {
|
464
|
-
prefix = NokogiriHelpers.getPrefix(e.getNodeName());
|
465
|
-
} else if (currentNS != null) {
|
466
|
-
prefix = e.lookupPrefix(currentNS);
|
467
|
-
}
|
468
|
-
e.getOwnerDocument().setStrictErrorChecking(false);
|
469
|
-
String nsURI = e.lookupNamespaceURI(prefix);
|
470
|
-
this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName());
|
471
|
-
|
472
|
-
if (e.hasAttributes()) {
|
473
|
-
NamedNodeMap attrs = e.getAttributes();
|
474
|
-
|
475
|
-
for (int i = 0; i < attrs.getLength(); i++) {
|
476
|
-
Attr attr = (Attr) attrs.item(i);
|
477
|
-
String nsUri = "";
|
478
|
-
String attrPrefix = attr.getPrefix();
|
479
|
-
if (attrPrefix == null) {
|
480
|
-
attrPrefix = NokogiriHelpers.getPrefix(attr.getNodeName());
|
481
|
-
}
|
482
|
-
String nodeName = attr.getNodeName();
|
483
|
-
if ("xml".equals(attrPrefix)) {
|
484
|
-
nsUri = "http://www.w3.org/XML/1998/namespace";
|
485
|
-
} else if ("xmlns".equals(attrPrefix) || nodeName.equals("xmlns")) {
|
486
|
-
nsUri = "http://www.w3.org/2000/xmlns/";
|
487
|
-
} else {
|
488
|
-
nsUri = attr.lookupNamespaceURI(attrPrefix);
|
489
|
-
}
|
463
|
+
if (!(node instanceof Element)) {
|
464
|
+
return;
|
465
|
+
}
|
490
466
|
|
491
|
-
|
492
|
-
|
493
|
-
|
467
|
+
// TODO: this feels kind of weird, why are we clearing the XmlNode
|
468
|
+
// cache here !!!
|
469
|
+
clearCachedNode(node);
|
470
|
+
Element e = (Element) node;
|
494
471
|
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
472
|
+
// disable error checking to prevent lines like the following
|
473
|
+
// from throwing a `NAMESPACE_ERR' exception:
|
474
|
+
// Nokogiri::XML::DocumentFragment.parse("<o:div>a</o:div>")
|
475
|
+
// since the `o' prefix isn't defined anywhere.
|
476
|
+
e.getOwnerDocument().setStrictErrorChecking(false);
|
477
|
+
|
478
|
+
String prefix = e.getPrefix();
|
479
|
+
String nsURI = e.lookupNamespaceURI(prefix);
|
480
|
+
this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName());
|
481
|
+
|
482
|
+
if (nsURI == null || nsURI == "") {
|
483
|
+
return;
|
484
|
+
}
|
485
|
+
|
486
|
+
if (e.hasAttributes()) {
|
487
|
+
NamedNodeMap attrs = e.getAttributes();
|
488
|
+
|
489
|
+
for (int i = 0; i < attrs.getLength(); i++) {
|
490
|
+
Attr attr = (Attr) attrs.item(i);
|
491
|
+
String nsUri = "";
|
492
|
+
String attrPrefix = attr.getPrefix();
|
493
|
+
if (attrPrefix == null) {
|
494
|
+
attrPrefix = NokogiriHelpers.getPrefix(attr.getNodeName());
|
495
|
+
}
|
496
|
+
String nodeName = attr.getNodeName();
|
497
|
+
if ("xml".equals(attrPrefix)) {
|
498
|
+
nsUri = "http://www.w3.org/XML/1998/namespace";
|
499
|
+
} else if ("xmlns".equals(attrPrefix) || nodeName.equals("xmlns")) {
|
500
|
+
nsUri = "http://www.w3.org/2000/xmlns/";
|
501
|
+
} else {
|
502
|
+
nsUri = attr.lookupNamespaceURI(attrPrefix);
|
500
503
|
}
|
501
|
-
}
|
502
504
|
|
503
|
-
|
504
|
-
|
505
|
-
|
505
|
+
if (nsUri == e.getNamespaceURI()) {
|
506
|
+
nsUri = null;
|
507
|
+
}
|
508
|
+
|
509
|
+
if (!(nsUri == null || "".equals(nsUri) || "http://www.w3.org/XML/1998/namespace".equals(nsUri))) {
|
510
|
+
// Create a new namespace object and add it to the document
|
511
|
+
// namespace cache.
|
512
|
+
// TODO: why do we need the namespace cache ?
|
513
|
+
XmlNamespace.createFromAttr(context.getRuntime(), attr);
|
514
|
+
}
|
515
|
+
clearCachedNode(attr);
|
516
|
+
NokogiriHelpers.renameNode(attr, nsUri, nodeName);
|
506
517
|
}
|
507
518
|
}
|
519
|
+
|
520
|
+
if (this.node.hasChildNodes()) {
|
521
|
+
XmlNodeSet nodeSet = (XmlNodeSet)(children(context));
|
522
|
+
nodeSet.relink_namespace(context);
|
523
|
+
}
|
508
524
|
}
|
509
525
|
|
510
526
|
// Users might extend XmlNode. This method works for such a case.
|
@@ -605,6 +621,7 @@ public class XmlNode extends RubyObject {
|
|
605
621
|
|
606
622
|
NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(node);
|
607
623
|
XmlNamespace cachedNamespace = nsCache.get(prefixString, hrefString);
|
624
|
+
|
608
625
|
if (cachedNamespace != null) return cachedNamespace;
|
609
626
|
|
610
627
|
Node namespaceOwner;
|
@@ -615,12 +632,14 @@ public class XmlNode extends RubyObject {
|
|
615
632
|
final String uri = "http://www.w3.org/2000/xmlns/";
|
616
633
|
String qName =
|
617
634
|
prefix.isNil() ? "xmlns" : "xmlns:" + prefixString;
|
635
|
+
|
618
636
|
element.setAttributeNS(uri, qName, hrefString);
|
619
637
|
}
|
620
638
|
else if (node.getNodeType() == Node.ATTRIBUTE_NODE) namespaceOwner = ((Attr)node).getOwnerElement();
|
621
639
|
else namespaceOwner = node.getParentNode();
|
622
640
|
XmlNamespace ns = XmlNamespace.createFromPrefixAndHref(namespaceOwner, prefix, href);
|
623
641
|
if (node != namespaceOwner) {
|
642
|
+
|
624
643
|
this.node = NokogiriHelpers.renameNode(node, ns.getHref(), ns.getPrefix() + ":" + node.getLocalName());
|
625
644
|
}
|
626
645
|
updateNodeNamespaceIfNecessary(context, ns);
|
@@ -806,6 +825,13 @@ public class XmlNode extends RubyObject {
|
|
806
825
|
}
|
807
826
|
|
808
827
|
ctx.setInputSource(istream);
|
828
|
+
// TODO: for some reason, document.getEncoding() can be null or nil (don't know why)
|
829
|
+
// run `test_parse_with_unparented_html_text_context_node' few times to see this happen
|
830
|
+
if (document instanceof HtmlDocument && !(document.getEncoding() == null || document.getEncoding().isNil())) {
|
831
|
+
HtmlDomParserContext htmlCtx= (HtmlDomParserContext) ctx;
|
832
|
+
htmlCtx.setEncoding(document.getEncoding().asJavaString());
|
833
|
+
}
|
834
|
+
|
809
835
|
XmlDocument doc = ctx.parse(context, klass, runtime.getNil());
|
810
836
|
|
811
837
|
RubyArray documentErrors = getErrorArray(document);
|
@@ -904,6 +930,10 @@ public class XmlNode extends RubyObject {
|
|
904
930
|
return doc;
|
905
931
|
}
|
906
932
|
|
933
|
+
public IRubyObject dup() {
|
934
|
+
return this.dup_implementation(getMetaClass().getClassRuntime(), true);
|
935
|
+
}
|
936
|
+
|
907
937
|
@JRubyMethod
|
908
938
|
public IRubyObject dup(ThreadContext context) {
|
909
939
|
return this.dup_implementation(context, true);
|
@@ -917,13 +947,17 @@ public class XmlNode extends RubyObject {
|
|
917
947
|
}
|
918
948
|
|
919
949
|
protected IRubyObject dup_implementation(ThreadContext context, boolean deep) {
|
950
|
+
return dup_implementation(context.getRuntime(), deep);
|
951
|
+
}
|
952
|
+
|
953
|
+
protected IRubyObject dup_implementation(Ruby runtime, boolean deep) {
|
920
954
|
XmlNode clone;
|
921
955
|
try {
|
922
956
|
clone = (XmlNode) clone();
|
923
957
|
} catch (CloneNotSupportedException e) {
|
924
|
-
throw
|
958
|
+
throw runtime.newRuntimeError(e.toString());
|
925
959
|
}
|
926
|
-
if (node == null) throw
|
960
|
+
if (node == null) throw runtime.newRuntimeError("FFFFFFFFFUUUUUUU");
|
927
961
|
Node newNode = node.cloneNode(deep);
|
928
962
|
clone.node = newNode;
|
929
963
|
return clone;
|
@@ -1074,12 +1108,24 @@ public class XmlNode extends RubyObject {
|
|
1074
1108
|
|
1075
1109
|
@JRubyMethod
|
1076
1110
|
public IRubyObject namespace(ThreadContext context) {
|
1077
|
-
|
1111
|
+
Ruby runtime = context.getRuntime();
|
1112
|
+
if (doc instanceof HtmlDocument) return runtime.getNil();
|
1078
1113
|
NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(node);
|
1114
|
+
String namespaceURI = node.getNamespaceURI();
|
1115
|
+
if (namespaceURI == null || namespaceURI == "") {
|
1116
|
+
return runtime.getNil();
|
1117
|
+
}
|
1118
|
+
|
1079
1119
|
String prefix = node.getPrefix();
|
1080
|
-
XmlNamespace namespace = nsCache.get(prefix == null ? "" : prefix,
|
1120
|
+
XmlNamespace namespace = nsCache.get(prefix == null ? "" : prefix, namespaceURI);
|
1081
1121
|
if (namespace == null || namespace.isEmpty()) {
|
1082
|
-
|
1122
|
+
// if it's not in the cache, create an unowned, uncached namespace and
|
1123
|
+
// return that. XmlReader can't insert namespaces into the cache, so
|
1124
|
+
// this is necessary for XmlReader to work correctly.
|
1125
|
+
namespace = new XmlNamespace(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Namespace"));
|
1126
|
+
IRubyObject rubyPrefix = NokogiriHelpers.stringOrNil(runtime, prefix);
|
1127
|
+
IRubyObject rubyUri = NokogiriHelpers.stringOrNil(runtime, namespaceURI);
|
1128
|
+
namespace.init(null, rubyPrefix, rubyUri, doc);
|
1083
1129
|
}
|
1084
1130
|
|
1085
1131
|
return namespace;
|
@@ -1296,7 +1342,7 @@ public class XmlNode extends RubyObject {
|
|
1296
1342
|
} else if (prefix.equals("xmlns")) {
|
1297
1343
|
uri = "http://www.w3.org/2000/xmlns/";
|
1298
1344
|
} else {
|
1299
|
-
uri =
|
1345
|
+
uri = node.lookupNamespaceURI(prefix);
|
1300
1346
|
}
|
1301
1347
|
}
|
1302
1348
|
|
@@ -1386,13 +1432,10 @@ public class XmlNode extends RubyObject {
|
|
1386
1432
|
|
1387
1433
|
@JRubyMethod(name = {"unlink", "remove"})
|
1388
1434
|
public IRubyObject unlink(ThreadContext context) {
|
1389
|
-
if(node.getParentNode()
|
1390
|
-
throw context.getRuntime().newRuntimeError("TYPE: " + node.getNodeType()+ " PARENT NULL");
|
1391
|
-
} else {
|
1435
|
+
if (node.getParentNode() != null) {
|
1392
1436
|
clearXpathContext(node.getParentNode());
|
1393
1437
|
node.getParentNode().removeChild(node);
|
1394
1438
|
}
|
1395
|
-
|
1396
1439
|
return this;
|
1397
1440
|
}
|
1398
1441
|
|
@@ -1555,7 +1598,7 @@ public class XmlNode extends RubyObject {
|
|
1555
1598
|
((XmlDocument) this).resetNamespaceCache(context);
|
1556
1599
|
}
|
1557
1600
|
|
1558
|
-
relink_namespace(context);
|
1601
|
+
other.relink_namespace(context);
|
1559
1602
|
// post_add_child(context, this, other);
|
1560
1603
|
|
1561
1604
|
return nodeOrTags;
|
@@ -17,10 +17,10 @@
|
|
17
17
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
18
18
|
* permit persons to whom the Software is furnished to do so, subject to
|
19
19
|
* the following conditions:
|
20
|
-
*
|
20
|
+
*
|
21
21
|
* The above copyright notice and this permission notice shall be
|
22
22
|
* included in all copies or substantial portions of the Software.
|
23
|
-
*
|
23
|
+
*
|
24
24
|
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
25
25
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
26
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
@@ -58,13 +58,13 @@ import org.jruby.runtime.builtin.IRubyObject;
|
|
58
58
|
import org.w3c.dom.Node;
|
59
59
|
import org.w3c.dom.NodeList;
|
60
60
|
|
61
|
-
import
|
62
|
-
import
|
63
|
-
import
|
64
|
-
import
|
65
|
-
import
|
66
|
-
import
|
67
|
-
import
|
61
|
+
import org.apache.xml.dtm.DTM;
|
62
|
+
import org.apache.xml.utils.PrefixResolver;
|
63
|
+
import org.apache.xpath.XPathContext;
|
64
|
+
import org.apache.xpath.jaxp.JAXPExtensionsProvider;
|
65
|
+
import org.apache.xpath.jaxp.JAXPPrefixResolver;
|
66
|
+
import org.apache.xpath.jaxp.JAXPVariableStack;
|
67
|
+
import org.apache.xpath.objects.XObject;
|
68
68
|
|
69
69
|
/**
|
70
70
|
* Class for Nokogiri::XML::XpathContext
|
@@ -110,7 +110,7 @@ public class XmlXpathContext extends RubyObject {
|
|
110
110
|
}
|
111
111
|
|
112
112
|
private JAXPExtensionsProvider getProviderInstance() throws ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
113
|
-
Class<?> clazz = Class.forName("
|
113
|
+
Class<?> clazz = Class.forName("org.apache.xpath.jaxp.JAXPExtensionsProvider");
|
114
114
|
Constructor[] constructors = clazz.getDeclaredConstructors();
|
115
115
|
for (int i = 0; i < constructors.length; i++) {
|
116
116
|
Class[] parameterTypes = constructors[i].getParameterTypes();
|
@@ -184,8 +184,8 @@ public class XmlXpathContext extends RubyObject {
|
|
184
184
|
Node contextNode = context.node;
|
185
185
|
|
186
186
|
try {
|
187
|
-
|
188
|
-
prefixResolver,
|
187
|
+
org.apache.xpath.XPath xpathInternal = new org.apache.xpath.XPath (expr, null,
|
188
|
+
prefixResolver, org.apache.xpath.XPath.SELECT );
|
189
189
|
|
190
190
|
// We always need to have a ContextNode with Xalan XPath implementation
|
191
191
|
// To allow simple expression evaluation like 1+1 we are setting
|