nokolexbor 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/nokolexbor/nl_attribute.c +46 -0
- data/ext/nokolexbor/nl_cdata.c +8 -0
- data/ext/nokolexbor/nl_comment.c +6 -0
- data/ext/nokolexbor/nl_document.c +53 -7
- data/ext/nokolexbor/nl_document_fragment.c +9 -0
- data/ext/nokolexbor/nl_error.c +21 -19
- data/ext/nokolexbor/nl_node.c +255 -49
- data/ext/nokolexbor/nl_node_set.c +56 -1
- data/ext/nokolexbor/nl_processing_instruction.c +6 -0
- data/ext/nokolexbor/nl_text.c +6 -0
- data/ext/nokolexbor/nokolexbor.h +1 -0
- data/lib/nokolexbor/document.rb +52 -5
- data/lib/nokolexbor/document_fragment.rb +11 -0
- data/lib/nokolexbor/node.rb +367 -18
- data/lib/nokolexbor/node_set.rb +56 -0
- data/lib/nokolexbor/version.rb +1 -1
- metadata +2 -24
- data/vendor/lexbor/source/lexbor/encoding/base.h +0 -218
- data/vendor/lexbor/source/lexbor/encoding/big5.c +0 -42839
- data/vendor/lexbor/source/lexbor/encoding/config.cmake +0 -12
- data/vendor/lexbor/source/lexbor/encoding/const.h +0 -65
- data/vendor/lexbor/source/lexbor/encoding/decode.c +0 -3193
- data/vendor/lexbor/source/lexbor/encoding/decode.h +0 -370
- data/vendor/lexbor/source/lexbor/encoding/encode.c +0 -1931
- data/vendor/lexbor/source/lexbor/encoding/encode.h +0 -377
- data/vendor/lexbor/source/lexbor/encoding/encoding.c +0 -252
- data/vendor/lexbor/source/lexbor/encoding/encoding.h +0 -475
- data/vendor/lexbor/source/lexbor/encoding/euc_kr.c +0 -53883
- data/vendor/lexbor/source/lexbor/encoding/gb18030.c +0 -47905
- data/vendor/lexbor/source/lexbor/encoding/iso_2022_jp_katakana.c +0 -159
- data/vendor/lexbor/source/lexbor/encoding/jis0208.c +0 -22477
- data/vendor/lexbor/source/lexbor/encoding/jis0212.c +0 -15787
- data/vendor/lexbor/source/lexbor/encoding/multi.h +0 -53
- data/vendor/lexbor/source/lexbor/encoding/range.c +0 -71
- data/vendor/lexbor/source/lexbor/encoding/range.h +0 -34
- data/vendor/lexbor/source/lexbor/encoding/res.c +0 -222
- data/vendor/lexbor/source/lexbor/encoding/res.h +0 -34
- data/vendor/lexbor/source/lexbor/encoding/single.c +0 -13748
- data/vendor/lexbor/source/lexbor/encoding/single.h +0 -116
data/ext/nokolexbor/nl_node.c
CHANGED
@@ -51,8 +51,11 @@ nl_rb_node_create(lxb_dom_node_t *node, VALUE rb_document)
|
|
51
51
|
case LXB_DOM_NODE_TYPE_COMMENT:
|
52
52
|
rb_class = cNokolexborComment;
|
53
53
|
break;
|
54
|
-
|
55
|
-
|
54
|
+
case LXB_DOM_NODE_TYPE_DOCUMENT:
|
55
|
+
if (nl_rb_node_unwrap(rb_document) != node) {
|
56
|
+
rb_raise(rb_eRuntimeError, "Unexpected node type: Document");
|
57
|
+
}
|
58
|
+
return rb_document;
|
56
59
|
// case LXB_DOM_NODE_TYPE_DOCUMENT_TYPE:
|
57
60
|
// break;
|
58
61
|
case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT:
|
@@ -81,6 +84,23 @@ nl_rb_node_unwrap(VALUE rb_node)
|
|
81
84
|
return node;
|
82
85
|
}
|
83
86
|
|
87
|
+
/**
|
88
|
+
* call-seq:
|
89
|
+
* new(name, document) { |Node| ... } -> Node
|
90
|
+
*
|
91
|
+
* Create a new node with +name+ that belongs to +document+.
|
92
|
+
*
|
93
|
+
* If you intend to add a node to a document tree, it's likely that you will prefer one of the
|
94
|
+
* {Node} methods like {#add_child}, {#add_next_sibling}, {#replace}, etc. which will
|
95
|
+
* both create an element (or subtree) and place it in the document tree.
|
96
|
+
*
|
97
|
+
* Another alternative, if you are concerned about performance, is
|
98
|
+
* {Document#create_element} which accepts additional arguments for contents or
|
99
|
+
* attributes but (like this method) avoids parsing markup.
|
100
|
+
*
|
101
|
+
* @param name [String]
|
102
|
+
* @param document [Document] The document to which the the returned node will belong.
|
103
|
+
*/
|
84
104
|
static VALUE
|
85
105
|
nl_node_new(int argc, VALUE *argv, VALUE klass)
|
86
106
|
{
|
@@ -113,6 +133,11 @@ nl_node_new(int argc, VALUE *argv, VALUE klass)
|
|
113
133
|
return rb_node;
|
114
134
|
}
|
115
135
|
|
136
|
+
/**
|
137
|
+
* call-seq: attribute(name) → Attribute
|
138
|
+
*
|
139
|
+
* @return [Attribute] The attribute belonging to this node with name +name+.
|
140
|
+
*/
|
116
141
|
static VALUE
|
117
142
|
nl_node_attribute(VALUE self, VALUE rb_name)
|
118
143
|
{
|
@@ -130,11 +155,14 @@ nl_node_attribute(VALUE self, VALUE rb_name)
|
|
130
155
|
return Qnil;
|
131
156
|
}
|
132
157
|
if (attr->owner == NULL) {
|
133
|
-
attr->owner = node;
|
158
|
+
attr->owner = lxb_dom_interface_element(node);
|
134
159
|
}
|
135
160
|
return nl_rb_node_create(attr, nl_rb_document_get(self));
|
136
161
|
}
|
137
162
|
|
163
|
+
/**
|
164
|
+
* @return [Array<Attribute>] An array of {Attribute} belonging to this node.
|
165
|
+
*/
|
138
166
|
static VALUE
|
139
167
|
nl_node_attribute_nodes(VALUE self)
|
140
168
|
{
|
@@ -153,7 +181,7 @@ nl_node_attribute_nodes(VALUE self)
|
|
153
181
|
VALUE rb_doc = nl_rb_document_get(self);
|
154
182
|
while (attr != NULL) {
|
155
183
|
if (attr->owner == NULL) {
|
156
|
-
attr->owner = node;
|
184
|
+
attr->owner = lxb_dom_interface_element(node);
|
157
185
|
}
|
158
186
|
rb_ary_push(ary, nl_rb_node_create(attr, rb_doc));
|
159
187
|
attr = attr->next;
|
@@ -162,6 +190,11 @@ nl_node_attribute_nodes(VALUE self)
|
|
162
190
|
return ary;
|
163
191
|
}
|
164
192
|
|
193
|
+
/**
|
194
|
+
* @return [String]
|
195
|
+
* Contents of all the text nodes in this node's subtree, concatenated together into a single
|
196
|
+
* String.
|
197
|
+
*/
|
165
198
|
static VALUE
|
166
199
|
nl_node_content(VALUE self)
|
167
200
|
{
|
@@ -178,6 +211,12 @@ nl_node_content(VALUE self)
|
|
178
211
|
return rb_str;
|
179
212
|
}
|
180
213
|
|
214
|
+
/**
|
215
|
+
* Set the Node's content to a Text node containing +content+. The string gets XML escaped, not
|
216
|
+
* interpreted as markup.
|
217
|
+
*
|
218
|
+
* @return [String] +content+
|
219
|
+
*/
|
181
220
|
static VALUE
|
182
221
|
nl_node_content_set(VALUE self, VALUE content)
|
183
222
|
{
|
@@ -192,6 +231,15 @@ nl_node_content_set(VALUE self, VALUE content)
|
|
192
231
|
return content;
|
193
232
|
}
|
194
233
|
|
234
|
+
/**
|
235
|
+
* call-seq: [](name) -> String,nil
|
236
|
+
*
|
237
|
+
* Fetch an attribute from this node.
|
238
|
+
*
|
239
|
+
* @param name The name of the attribute.
|
240
|
+
*
|
241
|
+
* @return (String, nil) The value of the attribute +name+, or +nil+ if no matching attribute exists.
|
242
|
+
*/
|
195
243
|
static VALUE
|
196
244
|
nl_node_get_attr(VALUE self, VALUE rb_attr)
|
197
245
|
{
|
@@ -217,6 +265,16 @@ nl_node_get_attr(VALUE self, VALUE rb_attr)
|
|
217
265
|
return rb_utf8_str_new((const char *)attr_value, attr_value_len);
|
218
266
|
}
|
219
267
|
|
268
|
+
/**
|
269
|
+
* call-seq: []=(name, value) -> String,nil
|
270
|
+
*
|
271
|
+
* Update the attribute +name+ to +value+, or create the attribute if it does not exist.
|
272
|
+
*
|
273
|
+
* @param name The name of the attribute.
|
274
|
+
* @param value The value of the attribute.
|
275
|
+
*
|
276
|
+
* @return [String] +value+
|
277
|
+
*/
|
220
278
|
static VALUE
|
221
279
|
nl_node_set_attr(VALUE self, VALUE rb_attr, VALUE rb_value)
|
222
280
|
{
|
@@ -241,13 +299,22 @@ nl_node_set_attr(VALUE self, VALUE rb_attr, VALUE rb_value)
|
|
241
299
|
return rb_value;
|
242
300
|
}
|
243
301
|
|
302
|
+
/**
|
303
|
+
* call-seq: remove_attr(name) -> Boolean
|
304
|
+
*
|
305
|
+
* Remove the attribute named +name+.
|
306
|
+
*
|
307
|
+
* @param name [String]
|
308
|
+
*
|
309
|
+
* @return [Boolean] +true+ if removal success, +false+ if node is not an {Element}.
|
310
|
+
*/
|
244
311
|
static VALUE
|
245
312
|
nl_node_remove_attr(VALUE self, VALUE rb_attr)
|
246
313
|
{
|
247
314
|
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
248
315
|
|
249
316
|
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
|
250
|
-
return
|
317
|
+
return Qfalse;
|
251
318
|
}
|
252
319
|
|
253
320
|
VALUE rb_attr_s = rb_String(rb_attr);
|
@@ -257,7 +324,12 @@ nl_node_remove_attr(VALUE self, VALUE rb_attr)
|
|
257
324
|
|
258
325
|
lxb_dom_element_t *element = lxb_dom_interface_element(node);
|
259
326
|
|
260
|
-
|
327
|
+
lxb_status_t status = lxb_dom_element_remove_attribute(element, (const lxb_char_t *)attr_c, attr_len);
|
328
|
+
if (status != LXB_STATUS_OK) {
|
329
|
+
nl_raise_lexbor_error(status);
|
330
|
+
}
|
331
|
+
|
332
|
+
return Qtrue;
|
261
333
|
}
|
262
334
|
|
263
335
|
lxb_status_t
|
@@ -384,6 +456,11 @@ void nl_sort_nodes_if_necessary(VALUE selector, lxb_dom_document_t *doc, lexbor_
|
|
384
456
|
}
|
385
457
|
}
|
386
458
|
|
459
|
+
/**
|
460
|
+
* Internal implementation of {#at_css}
|
461
|
+
*
|
462
|
+
* @see #at_css
|
463
|
+
*/
|
387
464
|
static VALUE
|
388
465
|
nl_node_at_css(VALUE self, VALUE selector)
|
389
466
|
{
|
@@ -411,6 +488,11 @@ nl_node_at_css(VALUE self, VALUE selector)
|
|
411
488
|
return ret;
|
412
489
|
}
|
413
490
|
|
491
|
+
/**
|
492
|
+
* Internal implementation of {#css}
|
493
|
+
*
|
494
|
+
* @see #css
|
495
|
+
*/
|
414
496
|
static VALUE
|
415
497
|
nl_node_css(VALUE self, VALUE selector)
|
416
498
|
{
|
@@ -428,6 +510,11 @@ nl_node_css(VALUE self, VALUE selector)
|
|
428
510
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
429
511
|
}
|
430
512
|
|
513
|
+
/**
|
514
|
+
* Get the inner_html of this Node.
|
515
|
+
*
|
516
|
+
* @return [String]
|
517
|
+
*/
|
431
518
|
static VALUE
|
432
519
|
nl_node_inner_html(int argc, VALUE *argv, VALUE self)
|
433
520
|
{
|
@@ -465,6 +552,11 @@ nl_node_inner_html(int argc, VALUE *argv, VALUE self)
|
|
465
552
|
return Qnil;
|
466
553
|
}
|
467
554
|
|
555
|
+
/**
|
556
|
+
* Serialize this Node to HTML, also known as outer_html.
|
557
|
+
*
|
558
|
+
* @return [String]
|
559
|
+
*/
|
468
560
|
static VALUE
|
469
561
|
nl_node_outer_html(int argc, VALUE *argv, VALUE self)
|
470
562
|
{
|
@@ -502,6 +594,11 @@ nl_node_outer_html(int argc, VALUE *argv, VALUE self)
|
|
502
594
|
return Qnil;
|
503
595
|
}
|
504
596
|
|
597
|
+
/**
|
598
|
+
* call-seq: key?(name) -> Boolean
|
599
|
+
*
|
600
|
+
* @return true if +name+ is set.
|
601
|
+
*/
|
505
602
|
static VALUE
|
506
603
|
nl_node_has_key(VALUE self, VALUE rb_attr)
|
507
604
|
{
|
@@ -520,6 +617,11 @@ nl_node_has_key(VALUE self, VALUE rb_attr)
|
|
520
617
|
return lxb_dom_element_has_attribute(element, (const lxb_char_t *)attr_c, attr_len) ? Qtrue : Qfalse;
|
521
618
|
}
|
522
619
|
|
620
|
+
/**
|
621
|
+
* Get the attribute names of this Node.
|
622
|
+
*
|
623
|
+
* @return [Array<String>] An array of attribute names.
|
624
|
+
*/
|
523
625
|
static VALUE
|
524
626
|
nl_node_keys(VALUE self)
|
525
627
|
{
|
@@ -543,6 +645,11 @@ nl_node_keys(VALUE self)
|
|
543
645
|
return ary_keys;
|
544
646
|
}
|
545
647
|
|
648
|
+
/**
|
649
|
+
* Get the attribute values of this Node.
|
650
|
+
*
|
651
|
+
* @return [Array<String>] An array of attribute values.
|
652
|
+
*/
|
546
653
|
static VALUE
|
547
654
|
nl_node_values(VALUE self)
|
548
655
|
{
|
@@ -570,6 +677,11 @@ nl_node_values(VALUE self)
|
|
570
677
|
return ary_values;
|
571
678
|
}
|
572
679
|
|
680
|
+
/**
|
681
|
+
* Get a hash of attribute names and values of this Node.
|
682
|
+
*
|
683
|
+
* @return [Hash{String => String}] A hash whose keys are attribute names and values are attribute values.
|
684
|
+
*/
|
573
685
|
static VALUE
|
574
686
|
nl_node_attrs(VALUE self)
|
575
687
|
{
|
@@ -598,6 +710,11 @@ nl_node_attrs(VALUE self)
|
|
598
710
|
return rb_hash;
|
599
711
|
}
|
600
712
|
|
713
|
+
/**
|
714
|
+
* Get the parent node.
|
715
|
+
*
|
716
|
+
* @return [Node,nil] The parent node
|
717
|
+
*/
|
601
718
|
static VALUE
|
602
719
|
nl_node_parent(VALUE self)
|
603
720
|
{
|
@@ -605,6 +722,11 @@ nl_node_parent(VALUE self)
|
|
605
722
|
return node->parent ? nl_rb_node_create(node->parent, nl_rb_document_get(self)) : Qnil;
|
606
723
|
}
|
607
724
|
|
725
|
+
/**
|
726
|
+
* Get the previous sibling node.
|
727
|
+
*
|
728
|
+
* @return [Node,nil] The previous sibling node
|
729
|
+
*/
|
608
730
|
static VALUE
|
609
731
|
nl_node_previous(VALUE self)
|
610
732
|
{
|
@@ -612,6 +734,11 @@ nl_node_previous(VALUE self)
|
|
612
734
|
return node->prev ? nl_rb_node_create(node->prev, nl_rb_document_get(self)) : Qnil;
|
613
735
|
}
|
614
736
|
|
737
|
+
/**
|
738
|
+
* Get the previous sibling element.
|
739
|
+
*
|
740
|
+
* @return [Element,nil] The previous sibling element
|
741
|
+
*/
|
615
742
|
static VALUE
|
616
743
|
nl_node_previous_element(VALUE self)
|
617
744
|
{
|
@@ -625,6 +752,11 @@ nl_node_previous_element(VALUE self)
|
|
625
752
|
return Qnil;
|
626
753
|
}
|
627
754
|
|
755
|
+
/**
|
756
|
+
* Get the next sibling node.
|
757
|
+
*
|
758
|
+
* @return [Node,nil] The previous sibling node
|
759
|
+
*/
|
628
760
|
static VALUE
|
629
761
|
nl_node_next(VALUE self)
|
630
762
|
{
|
@@ -632,6 +764,11 @@ nl_node_next(VALUE self)
|
|
632
764
|
return node->next ? nl_rb_node_create(node->next, nl_rb_document_get(self)) : Qnil;
|
633
765
|
}
|
634
766
|
|
767
|
+
/**
|
768
|
+
* Get the next sibling element.
|
769
|
+
*
|
770
|
+
* @return [Element,nil] The previous sibling element
|
771
|
+
*/
|
635
772
|
static VALUE
|
636
773
|
nl_node_next_element(VALUE self)
|
637
774
|
{
|
@@ -645,6 +782,11 @@ nl_node_next_element(VALUE self)
|
|
645
782
|
return Qnil;
|
646
783
|
}
|
647
784
|
|
785
|
+
/**
|
786
|
+
* Get the children of this node.
|
787
|
+
*
|
788
|
+
* @return [NodeSet] The set of this node's children.
|
789
|
+
*/
|
648
790
|
static VALUE
|
649
791
|
nl_node_children(VALUE self)
|
650
792
|
{
|
@@ -660,6 +802,11 @@ nl_node_children(VALUE self)
|
|
660
802
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
661
803
|
}
|
662
804
|
|
805
|
+
/**
|
806
|
+
* Get the first child of this node.
|
807
|
+
*
|
808
|
+
* @return [Node,nil] The first child.
|
809
|
+
*/
|
663
810
|
static VALUE
|
664
811
|
nl_node_child(VALUE self)
|
665
812
|
{
|
@@ -668,14 +815,26 @@ nl_node_child(VALUE self)
|
|
668
815
|
return child ? nl_rb_node_create(child, nl_rb_document_get(self)) : Qnil;
|
669
816
|
}
|
670
817
|
|
818
|
+
/**
|
819
|
+
* Remove this node from its current context.
|
820
|
+
*
|
821
|
+
* @return [Node] +self+, to support chaining of calls.
|
822
|
+
*/
|
671
823
|
static VALUE
|
672
824
|
nl_node_remove(VALUE self)
|
673
825
|
{
|
674
826
|
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
675
827
|
lxb_dom_node_remove(node);
|
676
|
-
return
|
828
|
+
return self;
|
677
829
|
}
|
678
830
|
|
831
|
+
/**
|
832
|
+
* Remove this node from its current context and free its allocated memory.
|
833
|
+
*
|
834
|
+
* @return [nil]
|
835
|
+
*
|
836
|
+
* @see #remove
|
837
|
+
*/
|
679
838
|
static VALUE
|
680
839
|
nl_node_destroy(VALUE self)
|
681
840
|
{
|
@@ -684,6 +843,9 @@ nl_node_destroy(VALUE self)
|
|
684
843
|
return Qnil;
|
685
844
|
}
|
686
845
|
|
846
|
+
/**
|
847
|
+
* @return [Boolean] true if this Node is equal to +other+.
|
848
|
+
*/
|
687
849
|
static VALUE
|
688
850
|
nl_node_equals(VALUE self, VALUE other)
|
689
851
|
{
|
@@ -702,6 +864,11 @@ lxb_dom_node_name_qualified(lxb_dom_node_t *node, size_t *len)
|
|
702
864
|
return lxb_dom_node_name(node, len);
|
703
865
|
}
|
704
866
|
|
867
|
+
/**
|
868
|
+
* Get the name of this Node
|
869
|
+
*
|
870
|
+
* @return [String] The name of this Node
|
871
|
+
*/
|
705
872
|
static VALUE
|
706
873
|
nl_node_name(VALUE self)
|
707
874
|
{
|
@@ -733,6 +900,13 @@ nl_node_parse_fragment(lxb_dom_document_t *doc, lxb_dom_element_t *element, lxb_
|
|
733
900
|
return frag_root;
|
734
901
|
}
|
735
902
|
|
903
|
+
/**
|
904
|
+
* Parse +html+ as a document fragment within the context of
|
905
|
+
* *this* node.
|
906
|
+
*
|
907
|
+
* @param html [String] The fragment to be parsed.
|
908
|
+
* @return [NodeSet] The {NodeSet} containing the parsed nodes.
|
909
|
+
*/
|
736
910
|
static VALUE
|
737
911
|
nl_node_parse(VALUE self, VALUE html)
|
738
912
|
{
|
@@ -752,38 +926,48 @@ nl_node_parse(VALUE self, VALUE html)
|
|
752
926
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
753
927
|
}
|
754
928
|
|
929
|
+
typedef void (*lxb_dom_node_add_nodes_to_f)(lxb_dom_node_t *, lxb_dom_node_t *);
|
930
|
+
|
755
931
|
static VALUE
|
756
|
-
|
932
|
+
nl_node_add_nodes(VALUE self, VALUE new, lxb_dom_node_add_nodes_to_f add_to, bool operate_on_new_node)
|
757
933
|
{
|
758
934
|
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
759
935
|
lxb_dom_document_t *doc = node->owner_document;
|
760
936
|
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
} else if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("previous"))) {
|
765
|
-
insert_after = 0;
|
766
|
-
} else {
|
767
|
-
rb_raise(rb_eArgError, "Unsupported inserting position");
|
768
|
-
}
|
769
|
-
|
770
|
-
if (TYPE(new) == T_STRING) {
|
771
|
-
lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, NULL, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
|
937
|
+
if (TYPE(new) == T_STRING || rb_obj_is_kind_of(new, cNokolexborDocumentFragment)) {
|
938
|
+
lxb_dom_node_t *frag_root = (TYPE(new) == T_STRING) ? nl_node_parse_fragment(doc, NULL, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new))
|
939
|
+
: nl_rb_node_unwrap(new);
|
772
940
|
lexbor_array_t *array = lexbor_array_create();
|
773
941
|
|
942
|
+
lxb_dom_node_t *last_node = node;
|
774
943
|
while (frag_root->first_child != NULL) {
|
775
944
|
lxb_dom_node_t *child = frag_root->first_child;
|
776
945
|
lxb_dom_node_remove(child);
|
777
|
-
|
946
|
+
operate_on_new_node ? add_to(last_node, child) : add_to(node, child);
|
947
|
+
last_node = child;
|
778
948
|
lexbor_array_push(array, child);
|
779
949
|
}
|
780
|
-
|
950
|
+
if (TYPE(new) == T_STRING) {
|
951
|
+
lxb_dom_node_destroy(frag_root);
|
952
|
+
}
|
781
953
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
782
954
|
|
955
|
+
} else if (rb_obj_is_kind_of(new, cNokolexborNodeSet)) {
|
956
|
+
lexbor_array_t *node_array = nl_rb_node_set_unwrap(new);
|
957
|
+
|
958
|
+
lxb_dom_node_t *last_node = node;
|
959
|
+
for (size_t i = 0; i < node_array->length; i++) {
|
960
|
+
lxb_dom_node_t *child = (lxb_dom_node_t *)node_array->list[i];
|
961
|
+
lxb_dom_node_remove(child);
|
962
|
+
operate_on_new_node ? add_to(last_node, child) : add_to(node, child);
|
963
|
+
last_node = child;
|
964
|
+
}
|
965
|
+
return new;
|
966
|
+
|
783
967
|
} else if (rb_obj_is_kind_of(new, cNokolexborNode)) {
|
784
968
|
lxb_dom_node_t *node_new = nl_rb_node_unwrap(new);
|
785
969
|
lxb_dom_node_remove(node_new);
|
786
|
-
|
970
|
+
add_to(node, node_new);
|
787
971
|
return new;
|
788
972
|
|
789
973
|
} else {
|
@@ -792,43 +976,57 @@ nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
|
|
792
976
|
return Qnil;
|
793
977
|
}
|
794
978
|
|
979
|
+
/**
|
980
|
+
* Insert +node_or_tags+ before or after this Node (as a sibling).
|
981
|
+
*
|
982
|
+
* @see #add_previous_sibling
|
983
|
+
* @see #add_next_sibling
|
984
|
+
*
|
985
|
+
* @return [Node,NodeSet] The reparented {Node} (if +node_or_tags+ is a {Node}), or {NodeSet} (if +node_or_tags+ is a {DocumentFragment}, {NodeSet}, or {String}).
|
986
|
+
*/
|
795
987
|
static VALUE
|
796
|
-
|
988
|
+
nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
|
797
989
|
{
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
if (
|
802
|
-
|
803
|
-
lexbor_array_t *array = lexbor_array_create();
|
804
|
-
|
805
|
-
while (frag_root->first_child != NULL) {
|
806
|
-
lxb_dom_node_t *child = frag_root->first_child;
|
807
|
-
lxb_dom_node_remove(child);
|
808
|
-
lxb_dom_node_insert_child(node, child);
|
809
|
-
lexbor_array_push(array, child);
|
810
|
-
}
|
811
|
-
lxb_dom_node_destroy(frag_root);
|
812
|
-
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
813
|
-
|
814
|
-
} else if (rb_obj_is_kind_of(new, cNokolexborNode)) {
|
815
|
-
lxb_dom_node_t *node_new = nl_rb_node_unwrap(new);
|
816
|
-
lxb_dom_node_remove(node_new);
|
817
|
-
lxb_dom_node_insert_child(node, node_new);
|
818
|
-
return new;
|
819
|
-
|
990
|
+
bool insert_after;
|
991
|
+
if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("next"))) {
|
992
|
+
insert_after = true;
|
993
|
+
} else if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("previous"))) {
|
994
|
+
insert_after = false;
|
820
995
|
} else {
|
821
|
-
rb_raise(rb_eArgError, "Unsupported
|
996
|
+
rb_raise(rb_eArgError, "Unsupported inserting position");
|
822
997
|
}
|
823
|
-
|
998
|
+
|
999
|
+
return insert_after ? nl_node_add_nodes(self, new, lxb_dom_node_insert_after, true)
|
1000
|
+
: nl_node_add_nodes(self, new, lxb_dom_node_insert_before, false);
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
/**
|
1004
|
+
* Add +new+ as a child of this Node.
|
1005
|
+
*
|
1006
|
+
* @param new [Node, DocumentFragment, NodeSet, String] The node to be added.
|
1007
|
+
*
|
1008
|
+
* @return [Node,NodeSet] The reparented {Node} (if +new+ is a {Node}), or {NodeSet} (if +new+ is a {DocumentFragment}, {NodeSet}, or {String}).
|
1009
|
+
*/
|
1010
|
+
static VALUE
|
1011
|
+
nl_node_add_child(VALUE self, VALUE new)
|
1012
|
+
{
|
1013
|
+
return nl_node_add_nodes(self, new, lxb_dom_node_insert_child, false);
|
824
1014
|
}
|
825
1015
|
|
1016
|
+
/**
|
1017
|
+
* Get the type of this Node
|
1018
|
+
*
|
1019
|
+
* @return {Integer}
|
1020
|
+
*/
|
826
1021
|
static VALUE
|
827
1022
|
nl_node_get_type(VALUE self)
|
828
1023
|
{
|
829
1024
|
return INT2NUM(nl_rb_node_unwrap(self)->type);
|
830
1025
|
}
|
831
1026
|
|
1027
|
+
/**
|
1028
|
+
* @return [Element] The first child Node that is an element.
|
1029
|
+
*/
|
832
1030
|
static VALUE
|
833
1031
|
nl_node_first_element_child(VALUE self)
|
834
1032
|
{
|
@@ -856,6 +1054,9 @@ nl_node_first_element_child(VALUE self)
|
|
856
1054
|
return Qnil;
|
857
1055
|
}
|
858
1056
|
|
1057
|
+
/**
|
1058
|
+
* @return [Element] The last child Node that is an element.
|
1059
|
+
*/
|
859
1060
|
static VALUE
|
860
1061
|
nl_node_last_element_child(VALUE self)
|
861
1062
|
{
|
@@ -883,6 +1084,11 @@ nl_node_last_element_child(VALUE self)
|
|
883
1084
|
return Qnil;
|
884
1085
|
}
|
885
1086
|
|
1087
|
+
/**
|
1088
|
+
* Copy this node.
|
1089
|
+
*
|
1090
|
+
* @return [Node] The new {Node}.
|
1091
|
+
*/
|
886
1092
|
static VALUE
|
887
1093
|
nl_node_clone(VALUE self)
|
888
1094
|
{
|
@@ -891,9 +1097,9 @@ nl_node_clone(VALUE self)
|
|
891
1097
|
|
892
1098
|
switch (node->type) {
|
893
1099
|
case LXB_DOM_NODE_TYPE_ATTRIBUTE:
|
894
|
-
clone = lxb_dom_attr_interface_clone(node->owner_document, lxb_dom_interface_attr(node));
|
1100
|
+
clone = (lxb_dom_node_t *)lxb_dom_attr_interface_clone(node->owner_document, lxb_dom_interface_attr(node));
|
895
1101
|
case LXB_DOM_NODE_TYPE_CDATA_SECTION:
|
896
|
-
clone = lxb_dom_cdata_section_interface_clone(node->owner_document, lxb_dom_interface_cdata_section(node));
|
1102
|
+
clone = (lxb_dom_node_t *)lxb_dom_cdata_section_interface_clone(node->owner_document, lxb_dom_interface_cdata_section(node));
|
897
1103
|
default:
|
898
1104
|
clone = lxb_dom_node_clone(node, true);
|
899
1105
|
break;
|
@@ -63,12 +63,27 @@ nl_rb_node_set_create_with_data(lexbor_array_t *array, VALUE rb_document)
|
|
63
63
|
return ret;
|
64
64
|
}
|
65
65
|
|
66
|
+
/**
|
67
|
+
* Get the length of this NodeSet.
|
68
|
+
*
|
69
|
+
* @return [Integer]
|
70
|
+
*/
|
66
71
|
static VALUE
|
67
72
|
nl_node_set_length(VALUE self)
|
68
73
|
{
|
69
74
|
return INT2NUM(nl_rb_node_set_unwrap(self)->length);
|
70
75
|
}
|
71
76
|
|
77
|
+
/**
|
78
|
+
* call-seq:
|
79
|
+
* push(node)
|
80
|
+
*
|
81
|
+
* Append +node+ to the NodeSet.
|
82
|
+
*
|
83
|
+
* @param node [Node]
|
84
|
+
*
|
85
|
+
* @return [NodeSet] +self+, to support chaining of calls.
|
86
|
+
*/
|
72
87
|
static VALUE
|
73
88
|
nl_node_set_push(VALUE self, VALUE rb_node)
|
74
89
|
{
|
@@ -83,6 +98,16 @@ nl_node_set_push(VALUE self, VALUE rb_node)
|
|
83
98
|
return self;
|
84
99
|
}
|
85
100
|
|
101
|
+
/**
|
102
|
+
* call-seq:
|
103
|
+
* delete(node)
|
104
|
+
*
|
105
|
+
* Delete +node+ from the NodeSet.
|
106
|
+
*
|
107
|
+
* @param node [Node]
|
108
|
+
*
|
109
|
+
* @return [Node,nil] The deleted node if found, otherwise returns nil.
|
110
|
+
*/
|
86
111
|
static VALUE
|
87
112
|
nl_node_set_delete(VALUE self, VALUE rb_node)
|
88
113
|
{
|
@@ -103,6 +128,12 @@ nl_node_set_delete(VALUE self, VALUE rb_node)
|
|
103
128
|
return rb_node;
|
104
129
|
}
|
105
130
|
|
131
|
+
/**
|
132
|
+
* call-seq:
|
133
|
+
* include?(node)
|
134
|
+
*
|
135
|
+
* @return true if any member of this NodeSet equals +node+.
|
136
|
+
*/
|
106
137
|
static VALUE
|
107
138
|
nl_node_set_is_include(VALUE self, VALUE rb_node)
|
108
139
|
{
|
@@ -166,6 +197,18 @@ nl_node_set_subseq(VALUE self, long beg, long len)
|
|
166
197
|
return nl_rb_node_set_create_with_data(new_array, nl_rb_document_get(self));
|
167
198
|
}
|
168
199
|
|
200
|
+
/**
|
201
|
+
* call-seq:
|
202
|
+
* [](index) -> Node,nil
|
203
|
+
* [](start, length) -> NodeSet,nil
|
204
|
+
* [](range) -> NodeSet,nil
|
205
|
+
*
|
206
|
+
* @return [Node,NodeSet,nil] the {Node} at +index+, or returns a {NodeSet}
|
207
|
+
* containing nodes starting at +start+ and continuing for +length+ elements, or
|
208
|
+
* returns a {NodeSet} containing nodes specified by +range+. Negative +indices+
|
209
|
+
* count backward from the end of the +node_set+ (-1 is the last node). Returns
|
210
|
+
* nil if the +index+ (or +start+) are out of range.
|
211
|
+
*/
|
169
212
|
static VALUE
|
170
213
|
nl_node_set_slice(int argc, VALUE *argv, VALUE self)
|
171
214
|
{
|
@@ -205,6 +248,9 @@ nl_node_set_slice(int argc, VALUE *argv, VALUE self)
|
|
205
248
|
return nl_node_set_index_at(self, NUM2LONG(arg));
|
206
249
|
}
|
207
250
|
|
251
|
+
/**
|
252
|
+
* @return [Array<Node>] This list as an Array
|
253
|
+
*/
|
208
254
|
static VALUE
|
209
255
|
nl_node_set_to_array(VALUE self)
|
210
256
|
{
|
@@ -221,6 +267,9 @@ nl_node_set_to_array(VALUE self)
|
|
221
267
|
return list;
|
222
268
|
}
|
223
269
|
|
270
|
+
/**
|
271
|
+
* @return [NodeSet] A new set built by merging the +other+ set, excluding duplicates.
|
272
|
+
*/
|
224
273
|
static VALUE
|
225
274
|
nl_node_set_union(VALUE self, VALUE other)
|
226
275
|
{
|
@@ -301,6 +350,9 @@ nl_node_set_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx)
|
|
301
350
|
return status;
|
302
351
|
}
|
303
352
|
|
353
|
+
/**
|
354
|
+
* (see Node#at_css)
|
355
|
+
*/
|
304
356
|
static VALUE
|
305
357
|
nl_node_set_at_css(VALUE self, VALUE selector)
|
306
358
|
{
|
@@ -328,6 +380,9 @@ nl_node_set_at_css(VALUE self, VALUE selector)
|
|
328
380
|
return ret;
|
329
381
|
}
|
330
382
|
|
383
|
+
/**
|
384
|
+
* (see Node#css)
|
385
|
+
*/
|
331
386
|
static VALUE
|
332
387
|
nl_node_set_css(VALUE self, VALUE selector)
|
333
388
|
{
|
@@ -353,7 +408,6 @@ void Init_nl_node_set(void)
|
|
353
408
|
|
354
409
|
rb_define_method(cNokolexborNodeSet, "length", nl_node_set_length, 0);
|
355
410
|
rb_define_method(cNokolexborNodeSet, "[]", nl_node_set_slice, -1);
|
356
|
-
rb_define_method(cNokolexborNodeSet, "slice", nl_node_set_slice, -1);
|
357
411
|
rb_define_method(cNokolexborNodeSet, "push", nl_node_set_push, 1);
|
358
412
|
rb_define_method(cNokolexborNodeSet, "|", nl_node_set_union, 1);
|
359
413
|
rb_define_method(cNokolexborNodeSet, "to_a", nl_node_set_to_array, 0);
|
@@ -362,6 +416,7 @@ void Init_nl_node_set(void)
|
|
362
416
|
rb_define_method(cNokolexborNodeSet, "at_css", nl_node_set_at_css, 1);
|
363
417
|
rb_define_method(cNokolexborNodeSet, "css", nl_node_set_css, 1);
|
364
418
|
|
419
|
+
rb_define_alias(cNokolexborNodeSet, "slice", "[]");
|
365
420
|
rb_define_alias(cNokolexborNodeSet, "<<", "push");
|
366
421
|
rb_define_alias(cNokolexborNodeSet, "size", "length");
|
367
422
|
rb_define_alias(cNokolexborNodeSet, "+", "|");
|