nokolexbor 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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, "+", "|");
|