nokogiri 1.13.6 → 1.14.1
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/Gemfile +39 -0
- data/LICENSE-DEPENDENCIES.md +830 -509
- data/LICENSE.md +1 -1
- data/README.md +18 -11
- data/dependencies.yml +33 -15
- data/ext/nokogiri/extconf.rb +100 -24
- data/ext/nokogiri/gumbo.c +21 -11
- data/ext/nokogiri/html4_document.c +2 -2
- data/ext/nokogiri/html4_element_description.c +1 -1
- data/ext/nokogiri/html4_entity_lookup.c +2 -2
- data/ext/nokogiri/html4_sax_parser_context.c +1 -6
- data/ext/nokogiri/html4_sax_push_parser.c +1 -1
- data/ext/nokogiri/nokogiri.c +38 -51
- data/ext/nokogiri/nokogiri.h +26 -14
- data/ext/nokogiri/test_global_handlers.c +1 -1
- data/ext/nokogiri/xml_attr.c +3 -3
- data/ext/nokogiri/xml_attribute_decl.c +5 -5
- data/ext/nokogiri/xml_cdata.c +3 -3
- data/ext/nokogiri/xml_comment.c +1 -1
- data/ext/nokogiri/xml_document.c +23 -14
- data/ext/nokogiri/xml_document_fragment.c +1 -1
- data/ext/nokogiri/xml_dtd.c +9 -9
- data/ext/nokogiri/xml_element_content.c +3 -3
- data/ext/nokogiri/xml_element_decl.c +5 -5
- data/ext/nokogiri/xml_encoding_handler.c +3 -3
- data/ext/nokogiri/xml_entity_decl.c +6 -6
- data/ext/nokogiri/xml_entity_reference.c +1 -1
- data/ext/nokogiri/xml_namespace.c +80 -14
- data/ext/nokogiri/xml_node.c +363 -82
- data/ext/nokogiri/xml_node_set.c +4 -6
- data/ext/nokogiri/xml_processing_instruction.c +1 -1
- data/ext/nokogiri/xml_reader.c +97 -22
- data/ext/nokogiri/xml_relax_ng.c +1 -3
- data/ext/nokogiri/xml_sax_parser.c +23 -17
- data/ext/nokogiri/xml_sax_parser_context.c +1 -6
- data/ext/nokogiri/xml_sax_push_parser.c +1 -3
- data/ext/nokogiri/xml_schema.c +4 -6
- data/ext/nokogiri/xml_syntax_error.c +1 -1
- data/ext/nokogiri/xml_text.c +2 -2
- data/ext/nokogiri/xml_xpath_context.c +91 -84
- data/ext/nokogiri/xslt_stylesheet.c +15 -14
- data/gumbo-parser/Makefile +10 -0
- data/gumbo-parser/src/attribute.h +1 -1
- data/gumbo-parser/src/error.c +2 -2
- data/gumbo-parser/src/error.h +1 -1
- data/gumbo-parser/src/foreign_attrs.c +2 -2
- data/gumbo-parser/src/{gumbo.h → nokogiri_gumbo.h} +1 -0
- data/gumbo-parser/src/parser.c +8 -5
- data/gumbo-parser/src/replacement.h +1 -1
- data/gumbo-parser/src/string_buffer.h +1 -1
- data/gumbo-parser/src/string_piece.c +1 -1
- data/gumbo-parser/src/svg_attrs.c +2 -2
- data/gumbo-parser/src/svg_tags.c +2 -2
- data/gumbo-parser/src/tag.c +2 -1
- data/gumbo-parser/src/tag_lookup.c +7 -7
- data/gumbo-parser/src/tag_lookup.gperf +1 -0
- data/gumbo-parser/src/tag_lookup.h +1 -1
- data/gumbo-parser/src/token_buffer.h +1 -1
- data/gumbo-parser/src/tokenizer.c +1 -1
- data/gumbo-parser/src/tokenizer.h +1 -1
- data/gumbo-parser/src/utf8.c +1 -1
- data/gumbo-parser/src/utf8.h +1 -1
- data/gumbo-parser/src/util.c +1 -3
- data/gumbo-parser/src/util.h +4 -0
- data/gumbo-parser/src/vector.h +1 -1
- data/lib/nokogiri/css/node.rb +2 -2
- data/lib/nokogiri/css/xpath_visitor.rb +5 -3
- data/lib/nokogiri/css.rb +6 -0
- data/lib/nokogiri/decorators/slop.rb +1 -1
- data/lib/nokogiri/encoding_handler.rb +57 -0
- data/lib/nokogiri/extension.rb +3 -2
- data/lib/nokogiri/html4/document.rb +2 -121
- data/lib/nokogiri/html4/element_description_defaults.rb +6 -12
- data/lib/nokogiri/html4/encoding_reader.rb +121 -0
- data/lib/nokogiri/html4.rb +1 -0
- data/lib/nokogiri/html5/document.rb +113 -36
- data/lib/nokogiri/html5/document_fragment.rb +9 -2
- data/lib/nokogiri/html5/node.rb +3 -5
- data/lib/nokogiri/html5.rb +127 -216
- data/lib/nokogiri/jruby/dependencies.rb +1 -19
- data/lib/nokogiri/jruby/nokogiri_jars.rb +43 -0
- data/lib/nokogiri/version/constant.rb +1 -1
- data/lib/nokogiri/version/info.rb +11 -10
- data/lib/nokogiri/xml/attr.rb +49 -0
- data/lib/nokogiri/xml/builder.rb +1 -1
- data/lib/nokogiri/xml/document.rb +103 -55
- data/lib/nokogiri/xml/document_fragment.rb +49 -6
- data/lib/nokogiri/xml/namespace.rb +42 -0
- data/lib/nokogiri/xml/node/save_options.rb +6 -4
- data/lib/nokogiri/xml/node.rb +190 -35
- data/lib/nokogiri/xml/node_set.rb +87 -9
- data/lib/nokogiri/xml/parse_options.rb +129 -50
- data/lib/nokogiri/xml/pp/node.rb +6 -4
- data/lib/nokogiri/xml/processing_instruction.rb +2 -1
- data/lib/nokogiri/xml/reader.rb +6 -8
- data/lib/nokogiri/xml/sax/parser.rb +2 -3
- data/lib/nokogiri/xslt.rb +1 -1
- data/lib/nokogiri.rb +3 -11
- data/lib/xsd/xmlparser/nokogiri.rb +3 -1
- data/ports/archives/libxml2-2.10.3.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.37.tar.xz +0 -0
- metadata +11 -242
- data/patches/libxml2/0004-use-glibc-strlen.patch +0 -53
- data/patches/libxml2/0005-avoid-isnan-isinf.patch +0 -81
- data/patches/libxml2/0006-update-automake-files-for-arm64.patch +0 -3040
- data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +0 -61
- data/ports/archives/libxml2-2.9.14.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.35.tar.xz +0 -0
data/ext/nokogiri/xml_node.c
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
#include <nokogiri.h>
|
2
2
|
|
3
|
+
#include <stdbool.h>
|
4
|
+
|
3
5
|
// :stopdoc:
|
4
6
|
|
5
7
|
VALUE cNokogiriXmlNode ;
|
@@ -7,22 +9,15 @@ static ID id_decorate, id_decorate_bang;
|
|
7
9
|
|
8
10
|
typedef xmlNodePtr(*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr);
|
9
11
|
|
10
|
-
|
11
|
-
#ifdef DEBUG
|
12
12
|
static void
|
13
|
-
|
13
|
+
_xml_node_mark(void *ptr)
|
14
14
|
{
|
15
|
-
|
16
|
-
NOKOGIRI_DEBUG_END(x)
|
17
|
-
}
|
18
|
-
#else
|
19
|
-
# define _xml_node_dealloc 0
|
20
|
-
#endif
|
15
|
+
xmlNodePtr node = ptr;
|
21
16
|
|
17
|
+
if (!DOC_RUBY_OBJECT_TEST(node->doc)) {
|
18
|
+
return;
|
19
|
+
}
|
22
20
|
|
23
|
-
static void
|
24
|
-
_xml_node_mark(xmlNodePtr node)
|
25
|
-
{
|
26
21
|
xmlDocPtr doc = node->doc;
|
27
22
|
if (doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
|
28
23
|
if (DOC_RUBY_OBJECT_TEST(doc)) {
|
@@ -33,6 +28,28 @@ _xml_node_mark(xmlNodePtr node)
|
|
33
28
|
}
|
34
29
|
}
|
35
30
|
|
31
|
+
#ifdef HAVE_RB_GC_LOCATION
|
32
|
+
static void
|
33
|
+
_xml_node_update_references(void *ptr)
|
34
|
+
{
|
35
|
+
xmlNodePtr node = ptr;
|
36
|
+
|
37
|
+
if (node->_private) {
|
38
|
+
node->_private = (void *)rb_gc_location((VALUE)node->_private);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
#else
|
42
|
+
# define _xml_node_update_references 0
|
43
|
+
#endif
|
44
|
+
|
45
|
+
static const rb_data_type_t nokogiri_node_type = {
|
46
|
+
"Nokogiri/XMLNode",
|
47
|
+
{_xml_node_mark, 0, 0, _xml_node_update_references},
|
48
|
+
0, 0,
|
49
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
50
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
51
|
+
#endif
|
52
|
+
};
|
36
53
|
|
37
54
|
static void
|
38
55
|
relink_namespace(xmlNodePtr reparented)
|
@@ -198,8 +215,8 @@ reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func
|
|
198
215
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
199
216
|
}
|
200
217
|
|
201
|
-
|
202
|
-
|
218
|
+
Noko_Node_Get_Struct(reparentee_obj, xmlNode, reparentee);
|
219
|
+
Noko_Node_Get_Struct(pivot_obj, xmlNode, pivot);
|
203
220
|
|
204
221
|
/*
|
205
222
|
* Check if nodes given are appropriate to have a parent-child
|
@@ -439,7 +456,7 @@ rb_xml_node_add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_hr
|
|
439
456
|
xmlNsPtr c_namespace;
|
440
457
|
const xmlChar *c_prefix = (const xmlChar *)(NIL_P(rb_prefix) ? NULL : StringValueCStr(rb_prefix));
|
441
458
|
|
442
|
-
|
459
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
443
460
|
element = c_node ;
|
444
461
|
|
445
462
|
c_namespace = xmlSearchNs(c_node->doc, c_node, c_prefix);
|
@@ -506,7 +523,7 @@ rb_xml_node_attribute(VALUE self, VALUE name)
|
|
506
523
|
{
|
507
524
|
xmlNodePtr node;
|
508
525
|
xmlAttrPtr prop;
|
509
|
-
|
526
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
510
527
|
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name));
|
511
528
|
|
512
529
|
if (! prop) { return Qnil; }
|
@@ -557,7 +574,7 @@ rb_xml_node_attribute_nodes(VALUE rb_node)
|
|
557
574
|
{
|
558
575
|
xmlNodePtr c_node;
|
559
576
|
|
560
|
-
|
577
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
561
578
|
|
562
579
|
return noko_xml_node_attrs(c_node);
|
563
580
|
}
|
@@ -609,7 +626,7 @@ rb_xml_node_attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
|
609
626
|
{
|
610
627
|
xmlNodePtr node;
|
611
628
|
xmlAttrPtr prop;
|
612
|
-
|
629
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
613
630
|
prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name),
|
614
631
|
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace));
|
615
632
|
|
@@ -636,7 +653,7 @@ static VALUE
|
|
636
653
|
rb_xml_node_blank_eh(VALUE self)
|
637
654
|
{
|
638
655
|
xmlNodePtr node;
|
639
|
-
|
656
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
640
657
|
return (1 == xmlIsBlankNode(node)) ? Qtrue : Qfalse ;
|
641
658
|
}
|
642
659
|
|
@@ -658,7 +675,7 @@ static VALUE
|
|
658
675
|
rb_xml_node_child(VALUE self)
|
659
676
|
{
|
660
677
|
xmlNodePtr node, child;
|
661
|
-
|
678
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
662
679
|
|
663
680
|
child = node->children;
|
664
681
|
if (!child) { return Qnil; }
|
@@ -683,7 +700,7 @@ rb_xml_node_children(VALUE self)
|
|
683
700
|
VALUE document;
|
684
701
|
VALUE node_set;
|
685
702
|
|
686
|
-
|
703
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
687
704
|
|
688
705
|
child = node->children;
|
689
706
|
set = xmlXPathNodeSetCreate(child);
|
@@ -742,7 +759,7 @@ rb_xml_node_content(VALUE self)
|
|
742
759
|
xmlNodePtr node;
|
743
760
|
xmlChar *content;
|
744
761
|
|
745
|
-
|
762
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
746
763
|
|
747
764
|
content = xmlNodeGetContent(node);
|
748
765
|
if (content) {
|
@@ -765,7 +782,7 @@ static VALUE
|
|
765
782
|
rb_xml_node_document(VALUE self)
|
766
783
|
{
|
767
784
|
xmlNodePtr node;
|
768
|
-
|
785
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
769
786
|
return DOC_RUBY_OBJECT(node->doc);
|
770
787
|
}
|
771
788
|
|
@@ -780,9 +797,9 @@ static VALUE
|
|
780
797
|
rb_xml_node_pointer_id(VALUE self)
|
781
798
|
{
|
782
799
|
xmlNodePtr node;
|
783
|
-
|
800
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
784
801
|
|
785
|
-
return
|
802
|
+
return rb_uint2inum((uintptr_t)(node));
|
786
803
|
}
|
787
804
|
|
788
805
|
/*
|
@@ -797,7 +814,7 @@ encode_special_chars(VALUE self, VALUE string)
|
|
797
814
|
xmlChar *encoded;
|
798
815
|
VALUE encoded_str;
|
799
816
|
|
800
|
-
|
817
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
801
818
|
encoded = xmlEncodeSpecialChars(
|
802
819
|
node->doc,
|
803
820
|
(const xmlChar *)StringValueCStr(string)
|
@@ -828,7 +845,7 @@ create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_i
|
|
828
845
|
xmlDocPtr doc;
|
829
846
|
xmlDtdPtr dtd;
|
830
847
|
|
831
|
-
|
848
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
832
849
|
|
833
850
|
doc = node->doc;
|
834
851
|
|
@@ -861,7 +878,7 @@ create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_i
|
|
861
878
|
xmlDocPtr doc;
|
862
879
|
xmlDtdPtr dtd;
|
863
880
|
|
864
|
-
|
881
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
865
882
|
|
866
883
|
doc = node->doc;
|
867
884
|
|
@@ -894,7 +911,7 @@ external_subset(VALUE self)
|
|
894
911
|
xmlDocPtr doc;
|
895
912
|
xmlDtdPtr dtd;
|
896
913
|
|
897
|
-
|
914
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
898
915
|
|
899
916
|
if (!node->doc) { return Qnil; }
|
900
917
|
|
@@ -919,7 +936,7 @@ internal_subset(VALUE self)
|
|
919
936
|
xmlDocPtr doc;
|
920
937
|
xmlDtdPtr dtd;
|
921
938
|
|
922
|
-
|
939
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
923
940
|
|
924
941
|
if (!node->doc) { return Qnil; }
|
925
942
|
|
@@ -955,7 +972,7 @@ duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
955
972
|
xmlDocPtr new_parent_doc;
|
956
973
|
xmlNodePtr node, dup;
|
957
974
|
|
958
|
-
|
975
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
959
976
|
|
960
977
|
n_args = rb_scan_args(argc, argv, "02", &r_level, &r_new_parent_doc);
|
961
978
|
|
@@ -988,7 +1005,7 @@ static VALUE
|
|
988
1005
|
unlink_node(VALUE self)
|
989
1006
|
{
|
990
1007
|
xmlNodePtr node;
|
991
|
-
|
1008
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
992
1009
|
xmlUnlinkNode(node);
|
993
1010
|
noko_xml_document_pin_node(node);
|
994
1011
|
return self;
|
@@ -1005,7 +1022,7 @@ static VALUE
|
|
1005
1022
|
next_sibling(VALUE self)
|
1006
1023
|
{
|
1007
1024
|
xmlNodePtr node, sibling;
|
1008
|
-
|
1025
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1009
1026
|
|
1010
1027
|
sibling = node->next;
|
1011
1028
|
if (!sibling) { return Qnil; }
|
@@ -1023,7 +1040,7 @@ static VALUE
|
|
1023
1040
|
previous_sibling(VALUE self)
|
1024
1041
|
{
|
1025
1042
|
xmlNodePtr node, sibling;
|
1026
|
-
|
1043
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1027
1044
|
|
1028
1045
|
sibling = node->prev;
|
1029
1046
|
if (!sibling) { return Qnil; }
|
@@ -1041,7 +1058,7 @@ static VALUE
|
|
1041
1058
|
next_element(VALUE self)
|
1042
1059
|
{
|
1043
1060
|
xmlNodePtr node, sibling;
|
1044
|
-
|
1061
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1045
1062
|
|
1046
1063
|
sibling = xmlNextElementSibling(node);
|
1047
1064
|
if (!sibling) { return Qnil; }
|
@@ -1059,7 +1076,7 @@ static VALUE
|
|
1059
1076
|
previous_element(VALUE self)
|
1060
1077
|
{
|
1061
1078
|
xmlNodePtr node, sibling;
|
1062
|
-
|
1079
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1063
1080
|
|
1064
1081
|
/*
|
1065
1082
|
* note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7.
|
@@ -1081,7 +1098,7 @@ replace(VALUE self, VALUE new_node)
|
|
1081
1098
|
VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper);
|
1082
1099
|
|
1083
1100
|
xmlNodePtr pivot;
|
1084
|
-
|
1101
|
+
Noko_Node_Get_Struct(self, xmlNode, pivot);
|
1085
1102
|
noko_xml_document_pin_node(pivot);
|
1086
1103
|
|
1087
1104
|
return reparent;
|
@@ -1116,7 +1133,7 @@ rb_xml_node_element_children(VALUE self)
|
|
1116
1133
|
VALUE document;
|
1117
1134
|
VALUE node_set;
|
1118
1135
|
|
1119
|
-
|
1136
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1120
1137
|
|
1121
1138
|
child = xmlFirstElementChild(node);
|
1122
1139
|
set = xmlXPathNodeSetCreate(child);
|
@@ -1155,7 +1172,7 @@ static VALUE
|
|
1155
1172
|
rb_xml_node_first_element_child(VALUE self)
|
1156
1173
|
{
|
1157
1174
|
xmlNodePtr node, child;
|
1158
|
-
|
1175
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1159
1176
|
|
1160
1177
|
child = xmlFirstElementChild(node);
|
1161
1178
|
if (!child) { return Qnil; }
|
@@ -1182,7 +1199,7 @@ static VALUE
|
|
1182
1199
|
rb_xml_node_last_element_child(VALUE self)
|
1183
1200
|
{
|
1184
1201
|
xmlNodePtr node, child;
|
1185
|
-
|
1202
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1186
1203
|
|
1187
1204
|
child = xmlLastElementChild(node);
|
1188
1205
|
if (!child) { return Qnil; }
|
@@ -1200,7 +1217,7 @@ static VALUE
|
|
1200
1217
|
key_eh(VALUE self, VALUE attribute)
|
1201
1218
|
{
|
1202
1219
|
xmlNodePtr node;
|
1203
|
-
|
1220
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1204
1221
|
if (xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) {
|
1205
1222
|
return Qtrue;
|
1206
1223
|
}
|
@@ -1217,7 +1234,7 @@ static VALUE
|
|
1217
1234
|
namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
1218
1235
|
{
|
1219
1236
|
xmlNodePtr node;
|
1220
|
-
|
1237
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1221
1238
|
if (xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute),
|
1222
1239
|
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) {
|
1223
1240
|
return Qtrue;
|
@@ -1236,7 +1253,7 @@ set(VALUE self, VALUE property, VALUE value)
|
|
1236
1253
|
{
|
1237
1254
|
xmlNodePtr node, cur;
|
1238
1255
|
xmlAttrPtr prop;
|
1239
|
-
|
1256
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1240
1257
|
|
1241
1258
|
/* If a matching attribute node already exists, then xmlSetProp will destroy
|
1242
1259
|
* the existing node's children. However, if Nokogiri has a node object
|
@@ -1281,7 +1298,7 @@ get(VALUE self, VALUE rattribute)
|
|
1281
1298
|
|
1282
1299
|
if (NIL_P(rattribute)) { return Qnil; }
|
1283
1300
|
|
1284
|
-
|
1301
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1285
1302
|
attribute = xmlCharStrdup(StringValueCStr(rattribute));
|
1286
1303
|
|
1287
1304
|
colon = DISCARD_CONST_QUAL_XMLCHAR(xmlStrchr(attribute, (const xmlChar)':'));
|
@@ -1323,10 +1340,10 @@ set_namespace(VALUE self, VALUE namespace)
|
|
1323
1340
|
xmlNodePtr node;
|
1324
1341
|
xmlNsPtr ns = NULL;
|
1325
1342
|
|
1326
|
-
|
1343
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1327
1344
|
|
1328
1345
|
if (!NIL_P(namespace)) {
|
1329
|
-
|
1346
|
+
Noko_Namespace_Get_Struct(namespace, xmlNs, ns);
|
1330
1347
|
}
|
1331
1348
|
|
1332
1349
|
xmlSetNs(node, ns);
|
@@ -1360,7 +1377,7 @@ static VALUE
|
|
1360
1377
|
rb_xml_node_namespace(VALUE rb_node)
|
1361
1378
|
{
|
1362
1379
|
xmlNodePtr c_node ;
|
1363
|
-
|
1380
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1364
1381
|
|
1365
1382
|
if (c_node->ns) {
|
1366
1383
|
return noko_xml_namespace_wrap(c_node->ns, c_node->doc);
|
@@ -1405,7 +1422,7 @@ namespace_definitions(VALUE rb_node)
|
|
1405
1422
|
xmlNsPtr c_namespace;
|
1406
1423
|
VALUE definitions = rb_ary_new();
|
1407
1424
|
|
1408
|
-
|
1425
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1409
1426
|
|
1410
1427
|
c_namespace = c_node->nsDef;
|
1411
1428
|
if (!c_namespace) {
|
@@ -1456,7 +1473,7 @@ rb_xml_node_namespace_scopes(VALUE rb_node)
|
|
1456
1473
|
VALUE scopes = rb_ary_new();
|
1457
1474
|
int j;
|
1458
1475
|
|
1459
|
-
|
1476
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1460
1477
|
|
1461
1478
|
namespaces = xmlGetNsList(c_node->doc, c_node);
|
1462
1479
|
if (!namespaces) {
|
@@ -1481,8 +1498,8 @@ static VALUE
|
|
1481
1498
|
node_type(VALUE self)
|
1482
1499
|
{
|
1483
1500
|
xmlNodePtr node;
|
1484
|
-
|
1485
|
-
return INT2NUM(
|
1501
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1502
|
+
return INT2NUM(node->type);
|
1486
1503
|
}
|
1487
1504
|
|
1488
1505
|
/*
|
@@ -1495,7 +1512,7 @@ static VALUE
|
|
1495
1512
|
set_native_content(VALUE self, VALUE content)
|
1496
1513
|
{
|
1497
1514
|
xmlNodePtr node, child, next ;
|
1498
|
-
|
1515
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1499
1516
|
|
1500
1517
|
child = node->children;
|
1501
1518
|
while (NULL != child) {
|
@@ -1521,7 +1538,7 @@ set_lang(VALUE self_rb, VALUE lang_rb)
|
|
1521
1538
|
xmlNodePtr self ;
|
1522
1539
|
xmlChar *lang ;
|
1523
1540
|
|
1524
|
-
|
1541
|
+
Noko_Node_Get_Struct(self_rb, xmlNode, self);
|
1525
1542
|
lang = (xmlChar *)StringValueCStr(lang_rb);
|
1526
1543
|
|
1527
1544
|
xmlNodeSetLang(self, lang);
|
@@ -1543,7 +1560,7 @@ get_lang(VALUE self_rb)
|
|
1543
1560
|
xmlChar *lang ;
|
1544
1561
|
VALUE lang_rb ;
|
1545
1562
|
|
1546
|
-
|
1563
|
+
Noko_Node_Get_Struct(self_rb, xmlNode, self);
|
1547
1564
|
|
1548
1565
|
lang = xmlNodeGetLang(self);
|
1549
1566
|
if (lang) {
|
@@ -1572,7 +1589,7 @@ static VALUE
|
|
1572
1589
|
get_parent(VALUE self)
|
1573
1590
|
{
|
1574
1591
|
xmlNodePtr node, parent;
|
1575
|
-
|
1592
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1576
1593
|
|
1577
1594
|
parent = node->parent;
|
1578
1595
|
if (!parent) { return Qnil; }
|
@@ -1590,7 +1607,7 @@ static VALUE
|
|
1590
1607
|
set_name(VALUE self, VALUE new_name)
|
1591
1608
|
{
|
1592
1609
|
xmlNodePtr node;
|
1593
|
-
|
1610
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1594
1611
|
xmlNodeSetName(node, (xmlChar *)StringValueCStr(new_name));
|
1595
1612
|
return new_name;
|
1596
1613
|
}
|
@@ -1605,7 +1622,7 @@ static VALUE
|
|
1605
1622
|
get_name(VALUE self)
|
1606
1623
|
{
|
1607
1624
|
xmlNodePtr node;
|
1608
|
-
|
1625
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1609
1626
|
if (node->name) {
|
1610
1627
|
return NOKOGIRI_STR_NEW2(node->name);
|
1611
1628
|
}
|
@@ -1625,7 +1642,7 @@ rb_xml_node_path(VALUE rb_node)
|
|
1625
1642
|
xmlChar *c_path ;
|
1626
1643
|
VALUE rval;
|
1627
1644
|
|
1628
|
-
|
1645
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1629
1646
|
|
1630
1647
|
c_path = xmlGetNodePath(c_node);
|
1631
1648
|
if (c_path == NULL) {
|
@@ -1674,7 +1691,7 @@ native_write_to(
|
|
1674
1691
|
const char *before_indent;
|
1675
1692
|
xmlSaveCtxtPtr savectx;
|
1676
1693
|
|
1677
|
-
|
1694
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1678
1695
|
|
1679
1696
|
xmlIndentTreeOutput = 1;
|
1680
1697
|
|
@@ -1697,6 +1714,269 @@ native_write_to(
|
|
1697
1714
|
return io;
|
1698
1715
|
}
|
1699
1716
|
|
1717
|
+
|
1718
|
+
static inline void
|
1719
|
+
output_partial_string(VALUE out, char const *str, size_t length)
|
1720
|
+
{
|
1721
|
+
if (length) {
|
1722
|
+
rb_enc_str_buf_cat(out, str, (long)length, rb_utf8_encoding());
|
1723
|
+
}
|
1724
|
+
}
|
1725
|
+
|
1726
|
+
static inline void
|
1727
|
+
output_char(VALUE out, char ch)
|
1728
|
+
{
|
1729
|
+
output_partial_string(out, &ch, 1);
|
1730
|
+
}
|
1731
|
+
|
1732
|
+
static inline void
|
1733
|
+
output_string(VALUE out, char const *str)
|
1734
|
+
{
|
1735
|
+
output_partial_string(out, str, strlen(str));
|
1736
|
+
}
|
1737
|
+
|
1738
|
+
static inline void
|
1739
|
+
output_tagname(VALUE out, xmlNodePtr elem)
|
1740
|
+
{
|
1741
|
+
// Elements in the HTML, MathML, and SVG namespaces do not use a namespace
|
1742
|
+
// prefix in the HTML syntax.
|
1743
|
+
char const *name = (char const *)elem->name;
|
1744
|
+
xmlNsPtr ns = elem->ns;
|
1745
|
+
if (ns && ns->href && ns->prefix
|
1746
|
+
&& strcmp((char const *)ns->href, "http://www.w3.org/1999/xhtml")
|
1747
|
+
&& strcmp((char const *)ns->href, "http://www.w3.org/1998/Math/MathML")
|
1748
|
+
&& strcmp((char const *)ns->href, "http://www.w3.org/2000/svg")) {
|
1749
|
+
output_string(out, (char const *)elem->ns->prefix);
|
1750
|
+
output_char(out, ':');
|
1751
|
+
char const *colon = strchr(name, ':');
|
1752
|
+
if (colon) {
|
1753
|
+
name = colon + 1;
|
1754
|
+
}
|
1755
|
+
}
|
1756
|
+
output_string(out, name);
|
1757
|
+
}
|
1758
|
+
|
1759
|
+
static inline void
|
1760
|
+
output_attr_name(VALUE out, xmlAttrPtr attr)
|
1761
|
+
{
|
1762
|
+
xmlNsPtr ns = attr->ns;
|
1763
|
+
char const *name = (char const *)attr->name;
|
1764
|
+
if (ns && ns->href) {
|
1765
|
+
char const *uri = (char const *)ns->href;
|
1766
|
+
char const *localname = strchr(name, ':');
|
1767
|
+
if (localname) {
|
1768
|
+
++localname;
|
1769
|
+
} else {
|
1770
|
+
localname = name;
|
1771
|
+
}
|
1772
|
+
|
1773
|
+
if (!strcmp(uri, "http://www.w3.org/XML/1998/namespace")) {
|
1774
|
+
output_string(out, "xml:");
|
1775
|
+
name = localname;
|
1776
|
+
} else if (!strcmp(uri, "http://www.w3.org/2000/xmlns/")) {
|
1777
|
+
// xmlns:xmlns -> xmlns
|
1778
|
+
// xmlns:foo -> xmlns:foo
|
1779
|
+
if (strcmp(localname, "xmlns")) {
|
1780
|
+
output_string(out, "xmlns:");
|
1781
|
+
}
|
1782
|
+
name = localname;
|
1783
|
+
} else if (!strcmp(uri, "http://www.w3.org/1999/xlink")) {
|
1784
|
+
output_string(out, "xlink:");
|
1785
|
+
name = localname;
|
1786
|
+
} else if (ns->prefix) {
|
1787
|
+
output_string(out, (char const *)ns->prefix);
|
1788
|
+
output_char(out, ':');
|
1789
|
+
name = localname;
|
1790
|
+
}
|
1791
|
+
}
|
1792
|
+
output_string(out, name);
|
1793
|
+
}
|
1794
|
+
|
1795
|
+
static void
|
1796
|
+
output_escaped_string(VALUE out, xmlChar const *start, bool attr)
|
1797
|
+
{
|
1798
|
+
xmlChar const *next = start;
|
1799
|
+
int ch;
|
1800
|
+
|
1801
|
+
while ((ch = *next) != 0) {
|
1802
|
+
char const *replacement = NULL;
|
1803
|
+
size_t replaced_bytes = 1;
|
1804
|
+
if (ch == '&') {
|
1805
|
+
replacement = "&";
|
1806
|
+
} else if (ch == 0xC2 && next[1] == 0xA0) {
|
1807
|
+
// U+00A0 NO-BREAK SPACE has the UTF-8 encoding C2 A0.
|
1808
|
+
replacement = " ";
|
1809
|
+
replaced_bytes = 2;
|
1810
|
+
} else if (attr && ch == '"') {
|
1811
|
+
replacement = """;
|
1812
|
+
} else if (!attr && ch == '<') {
|
1813
|
+
replacement = "<";
|
1814
|
+
} else if (!attr && ch == '>') {
|
1815
|
+
replacement = ">";
|
1816
|
+
} else {
|
1817
|
+
++next;
|
1818
|
+
continue;
|
1819
|
+
}
|
1820
|
+
output_partial_string(out, (char const *)start, next - start);
|
1821
|
+
output_string(out, replacement);
|
1822
|
+
next += replaced_bytes;
|
1823
|
+
start = next;
|
1824
|
+
}
|
1825
|
+
output_partial_string(out, (char const *)start, next - start);
|
1826
|
+
}
|
1827
|
+
|
1828
|
+
static bool
|
1829
|
+
should_prepend_newline(xmlNodePtr node)
|
1830
|
+
{
|
1831
|
+
char const *name = (char const *)node->name;
|
1832
|
+
xmlNodePtr child = node->children;
|
1833
|
+
|
1834
|
+
if (!name || !child || (strcmp(name, "pre") && strcmp(name, "textarea") && strcmp(name, "listing"))) {
|
1835
|
+
return false;
|
1836
|
+
}
|
1837
|
+
|
1838
|
+
return child->type == XML_TEXT_NODE && child->content && child->content[0] == '\n';
|
1839
|
+
}
|
1840
|
+
|
1841
|
+
static VALUE
|
1842
|
+
rb_prepend_newline(VALUE self)
|
1843
|
+
{
|
1844
|
+
xmlNodePtr node;
|
1845
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1846
|
+
return should_prepend_newline(node) ? Qtrue : Qfalse;
|
1847
|
+
}
|
1848
|
+
|
1849
|
+
static bool
|
1850
|
+
is_one_of(xmlNodePtr node, char const *const *tagnames, size_t num_tagnames)
|
1851
|
+
{
|
1852
|
+
char const *name = (char const *)node->name;
|
1853
|
+
if (name == NULL) { // fragments don't have a name
|
1854
|
+
return false;
|
1855
|
+
}
|
1856
|
+
for (size_t idx = 0; idx < num_tagnames; ++idx) {
|
1857
|
+
if (!strcmp(name, tagnames[idx])) {
|
1858
|
+
return true;
|
1859
|
+
}
|
1860
|
+
}
|
1861
|
+
return false;
|
1862
|
+
|
1863
|
+
}
|
1864
|
+
|
1865
|
+
static void
|
1866
|
+
output_node(
|
1867
|
+
VALUE out,
|
1868
|
+
xmlNodePtr node,
|
1869
|
+
bool preserve_newline
|
1870
|
+
)
|
1871
|
+
{
|
1872
|
+
static char const *const VOID_ELEMENTS[] = {
|
1873
|
+
"area", "base", "basefont", "bgsound", "br", "col", "embed", "frame", "hr",
|
1874
|
+
"img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr",
|
1875
|
+
};
|
1876
|
+
|
1877
|
+
static char const *const UNESCAPED_TEXT_ELEMENTS[] = {
|
1878
|
+
"style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript",
|
1879
|
+
};
|
1880
|
+
|
1881
|
+
switch (node->type) {
|
1882
|
+
case XML_ELEMENT_NODE:
|
1883
|
+
// Serialize the start tag.
|
1884
|
+
output_char(out, '<');
|
1885
|
+
output_tagname(out, node);
|
1886
|
+
|
1887
|
+
// Add attributes.
|
1888
|
+
for (xmlAttrPtr attr = node->properties; attr; attr = attr->next) {
|
1889
|
+
output_char(out, ' ');
|
1890
|
+
output_attr_name(out, attr);
|
1891
|
+
if (attr->children) {
|
1892
|
+
output_string(out, "=\"");
|
1893
|
+
xmlChar *value = xmlNodeListGetString(attr->doc, attr->children, 1);
|
1894
|
+
output_escaped_string(out, value, true);
|
1895
|
+
xmlFree(value);
|
1896
|
+
output_char(out, '"');
|
1897
|
+
} else {
|
1898
|
+
// Output name=""
|
1899
|
+
output_string(out, "=\"\"");
|
1900
|
+
}
|
1901
|
+
}
|
1902
|
+
output_char(out, '>');
|
1903
|
+
|
1904
|
+
// Add children and end tag if element is not void.
|
1905
|
+
if (!is_one_of(node, VOID_ELEMENTS, sizeof VOID_ELEMENTS / sizeof VOID_ELEMENTS[0])) {
|
1906
|
+
if (preserve_newline && should_prepend_newline(node)) {
|
1907
|
+
output_char(out, '\n');
|
1908
|
+
}
|
1909
|
+
for (xmlNodePtr child = node->children; child; child = child->next) {
|
1910
|
+
output_node(out, child, preserve_newline);
|
1911
|
+
}
|
1912
|
+
output_string(out, "</");
|
1913
|
+
output_tagname(out, node);
|
1914
|
+
output_char(out, '>');
|
1915
|
+
}
|
1916
|
+
break;
|
1917
|
+
|
1918
|
+
case XML_TEXT_NODE:
|
1919
|
+
if (node->parent
|
1920
|
+
&& is_one_of(node->parent, UNESCAPED_TEXT_ELEMENTS,
|
1921
|
+
sizeof UNESCAPED_TEXT_ELEMENTS / sizeof UNESCAPED_TEXT_ELEMENTS[0])) {
|
1922
|
+
output_string(out, (char const *)node->content);
|
1923
|
+
} else {
|
1924
|
+
output_escaped_string(out, node->content, false);
|
1925
|
+
}
|
1926
|
+
break;
|
1927
|
+
|
1928
|
+
case XML_CDATA_SECTION_NODE:
|
1929
|
+
output_string(out, "<![CDATA[");
|
1930
|
+
output_string(out, (char const *)node->content);
|
1931
|
+
output_string(out, "]]>");
|
1932
|
+
break;
|
1933
|
+
|
1934
|
+
case XML_COMMENT_NODE:
|
1935
|
+
output_string(out, "<!--");
|
1936
|
+
output_string(out, (char const *)node->content);
|
1937
|
+
output_string(out, "-->");
|
1938
|
+
break;
|
1939
|
+
|
1940
|
+
case XML_PI_NODE:
|
1941
|
+
output_string(out, "<?");
|
1942
|
+
output_string(out, (char const *)node->content);
|
1943
|
+
output_char(out, '>');
|
1944
|
+
break;
|
1945
|
+
|
1946
|
+
case XML_DOCUMENT_TYPE_NODE:
|
1947
|
+
case XML_DTD_NODE:
|
1948
|
+
output_string(out, "<!DOCTYPE ");
|
1949
|
+
output_string(out, (char const *)node->name);
|
1950
|
+
output_string(out, ">");
|
1951
|
+
break;
|
1952
|
+
|
1953
|
+
case XML_DOCUMENT_NODE:
|
1954
|
+
case XML_DOCUMENT_FRAG_NODE:
|
1955
|
+
case XML_HTML_DOCUMENT_NODE:
|
1956
|
+
for (xmlNodePtr child = node->children; child; child = child->next) {
|
1957
|
+
output_node(out, child, preserve_newline);
|
1958
|
+
}
|
1959
|
+
break;
|
1960
|
+
|
1961
|
+
default:
|
1962
|
+
rb_raise(rb_eRuntimeError, "Unsupported document node (%d); this is a bug in Nokogiri", node->type);
|
1963
|
+
break;
|
1964
|
+
}
|
1965
|
+
}
|
1966
|
+
|
1967
|
+
static VALUE
|
1968
|
+
html_standard_serialize(
|
1969
|
+
VALUE self,
|
1970
|
+
VALUE preserve_newline
|
1971
|
+
)
|
1972
|
+
{
|
1973
|
+
xmlNodePtr node;
|
1974
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1975
|
+
VALUE output = rb_str_buf_new(4096);
|
1976
|
+
output_node(output, node, RTEST(preserve_newline));
|
1977
|
+
return output;
|
1978
|
+
}
|
1979
|
+
|
1700
1980
|
/*
|
1701
1981
|
* :call-seq:
|
1702
1982
|
* line() → Integer
|
@@ -1728,9 +2008,9 @@ static VALUE
|
|
1728
2008
|
rb_xml_node_line(VALUE rb_node)
|
1729
2009
|
{
|
1730
2010
|
xmlNodePtr c_node;
|
1731
|
-
|
2011
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1732
2012
|
|
1733
|
-
return
|
2013
|
+
return LONG2NUM(xmlGetLineNo(c_node));
|
1734
2014
|
}
|
1735
2015
|
|
1736
2016
|
/*
|
@@ -1745,7 +2025,7 @@ rb_xml_node_line_set(VALUE rb_node, VALUE rb_line_number)
|
|
1745
2025
|
xmlNodePtr c_node;
|
1746
2026
|
int line_number = NUM2INT(rb_line_number);
|
1747
2027
|
|
1748
|
-
|
2028
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1749
2029
|
|
1750
2030
|
// libxml2 optionally uses xmlNode.psvi to store longer line numbers, but only for text nodes.
|
1751
2031
|
// search for "psvi" in SAX2.c and tree.c to learn more.
|
@@ -1779,9 +2059,9 @@ rb_xml_node_new(int argc, VALUE *argv, VALUE klass)
|
|
1779
2059
|
}
|
1780
2060
|
if (!rb_obj_is_kind_of(rb_document_node, cNokogiriXmlDocument)) {
|
1781
2061
|
// TODO: deprecate allowing Node
|
1782
|
-
|
2062
|
+
NOKO_WARN_DEPRECATION("Passing a Node as the second parameter to Node.new is deprecated. Please pass a Document instead, or prefer an alternative constructor like Node#add_child. This will become an error in a future release of Nokogiri.");
|
1783
2063
|
}
|
1784
|
-
|
2064
|
+
Noko_Node_Get_Struct(rb_document_node, xmlNode, c_document_node);
|
1785
2065
|
|
1786
2066
|
c_node = xmlNewNode(NULL, (xmlChar *)StringValueCStr(rb_name));
|
1787
2067
|
c_node->doc = c_document_node->doc;
|
@@ -1811,7 +2091,7 @@ dump_html(VALUE self)
|
|
1811
2091
|
xmlNodePtr node ;
|
1812
2092
|
VALUE html;
|
1813
2093
|
|
1814
|
-
|
2094
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1815
2095
|
|
1816
2096
|
buf = xmlBufferCreate() ;
|
1817
2097
|
htmlNodeDump(buf, node->doc, node);
|
@@ -1830,10 +2110,10 @@ static VALUE
|
|
1830
2110
|
compare(VALUE self, VALUE _other)
|
1831
2111
|
{
|
1832
2112
|
xmlNodePtr node, other;
|
1833
|
-
|
1834
|
-
|
2113
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
2114
|
+
Noko_Node_Get_Struct(_other, xmlNode, other);
|
1835
2115
|
|
1836
|
-
return INT2NUM(
|
2116
|
+
return INT2NUM(xmlXPathCmpNodes(other, node));
|
1837
2117
|
}
|
1838
2118
|
|
1839
2119
|
|
@@ -1851,7 +2131,7 @@ process_xincludes(VALUE self, VALUE options)
|
|
1851
2131
|
xmlNodePtr node;
|
1852
2132
|
VALUE error_list = rb_ary_new();
|
1853
2133
|
|
1854
|
-
|
2134
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1855
2135
|
|
1856
2136
|
xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
|
1857
2137
|
rcode = xmlXIncludeProcessTreeFlags(node, (int)NUM2INT(options));
|
@@ -1882,7 +2162,7 @@ in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1882
2162
|
VALUE doc, err;
|
1883
2163
|
int doc_is_empty;
|
1884
2164
|
|
1885
|
-
|
2165
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1886
2166
|
|
1887
2167
|
doc = DOC_RUBY_OBJECT(node->doc);
|
1888
2168
|
err = rb_iv_get(doc, "@errors");
|
@@ -1933,12 +2213,17 @@ in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1933
2213
|
|
1934
2214
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
1935
2215
|
|
1936
|
-
/*
|
2216
|
+
/*
|
2217
|
+
* Workaround for a libxml2 bug where a parsing error may leave a broken
|
1937
2218
|
* node reference in node->doc->children.
|
2219
|
+
*
|
2220
|
+
* https://bugzilla.gnome.org/show_bug.cgi?id=668155
|
2221
|
+
*
|
1938
2222
|
* This workaround is limited to when a parse error occurs, the document
|
1939
2223
|
* went from having no children to having children, and the context node is
|
1940
2224
|
* part of a document fragment.
|
1941
|
-
*
|
2225
|
+
*
|
2226
|
+
* TODO: This was fixed in libxml 2.8.0 by 71a243d
|
1942
2227
|
*/
|
1943
2228
|
if (error != XML_ERR_OK && doc_is_empty && node->doc->children != NULL) {
|
1944
2229
|
child_iter = node;
|
@@ -1974,14 +2259,12 @@ in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1974
2259
|
return noko_xml_node_set_wrap(set, doc);
|
1975
2260
|
}
|
1976
2261
|
|
1977
|
-
|
1978
2262
|
VALUE
|
1979
2263
|
noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
1980
2264
|
{
|
1981
2265
|
VALUE rb_document, rb_node_cache, rb_node;
|
1982
2266
|
nokogiriTuplePtr node_has_a_document;
|
1983
2267
|
xmlDocPtr c_doc;
|
1984
|
-
void (*f_mark)(xmlNodePtr) = NULL ;
|
1985
2268
|
|
1986
2269
|
assert(c_node);
|
1987
2270
|
|
@@ -1989,11 +2272,9 @@ noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
|
1989
2272
|
return DOC_RUBY_OBJECT(c_node->doc);
|
1990
2273
|
}
|
1991
2274
|
|
1992
|
-
/* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */
|
1993
|
-
/* see https://github.com/sparklemotion/nokogiri/issues/95 */
|
1994
|
-
/* and https://github.com/sparklemotion/nokogiri/issues/439 */
|
1995
2275
|
c_doc = c_node->doc;
|
1996
|
-
|
2276
|
+
|
2277
|
+
// Nodes yielded from XML::Reader don't have a fully-realized Document
|
1997
2278
|
node_has_a_document = DOC_RUBY_OBJECT_TEST(c_doc);
|
1998
2279
|
|
1999
2280
|
if (c_node->_private && node_has_a_document) {
|
@@ -2043,9 +2324,7 @@ noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
|
2043
2324
|
}
|
2044
2325
|
}
|
2045
2326
|
|
2046
|
-
|
2047
|
-
|
2048
|
-
rb_node = Data_Wrap_Struct(rb_class, f_mark, _xml_node_dealloc, c_node) ;
|
2327
|
+
rb_node = TypedData_Wrap_Struct(rb_class, &nokogiri_node_type, c_node) ;
|
2049
2328
|
c_node->_private = (void *)rb_node;
|
2050
2329
|
|
2051
2330
|
if (node_has_a_document) {
|
@@ -2078,7 +2357,7 @@ noko_xml_node_attrs(xmlNodePtr c_node)
|
|
2078
2357
|
}
|
2079
2358
|
|
2080
2359
|
void
|
2081
|
-
noko_init_xml_node()
|
2360
|
+
noko_init_xml_node(void)
|
2082
2361
|
{
|
2083
2362
|
cNokogiriXmlNode = rb_define_class_under(mNokogiriXml, "Node", rb_cObject);
|
2084
2363
|
|
@@ -2134,6 +2413,8 @@ noko_init_xml_node()
|
|
2134
2413
|
rb_define_private_method(cNokogiriXmlNode, "get", get, 1);
|
2135
2414
|
rb_define_private_method(cNokogiriXmlNode, "in_context", in_context, 2);
|
2136
2415
|
rb_define_private_method(cNokogiriXmlNode, "native_write_to", native_write_to, 4);
|
2416
|
+
rb_define_private_method(cNokogiriXmlNode, "prepend_newline?", rb_prepend_newline, 0);
|
2417
|
+
rb_define_private_method(cNokogiriXmlNode, "html_standard_serialize", html_standard_serialize, 1);
|
2137
2418
|
rb_define_private_method(cNokogiriXmlNode, "process_xincludes", process_xincludes, 1);
|
2138
2419
|
rb_define_private_method(cNokogiriXmlNode, "replace_node", replace, 1);
|
2139
2420
|
rb_define_private_method(cNokogiriXmlNode, "set", set, 2);
|