nokolexbor 0.3.4 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/nokolexbor/extconf.rb +9 -5
- 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 -50
- 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
|
@@ -311,7 +383,6 @@ nl_node_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx)
|
|
311
383
|
}
|
312
384
|
|
313
385
|
/* Parse and get the log. */
|
314
|
-
// TODO: Cache the list for reuse, improves performance
|
315
386
|
list = lxb_css_selectors_parse_relative_list(parser, (const lxb_char_t *)selector_c, selector_len);
|
316
387
|
if (parser->status != LXB_STATUS_OK) {
|
317
388
|
status = parser->status;
|
@@ -384,6 +455,11 @@ void nl_sort_nodes_if_necessary(VALUE selector, lxb_dom_document_t *doc, lexbor_
|
|
384
455
|
}
|
385
456
|
}
|
386
457
|
|
458
|
+
/**
|
459
|
+
* Internal implementation of {#at_css}
|
460
|
+
*
|
461
|
+
* @see #at_css
|
462
|
+
*/
|
387
463
|
static VALUE
|
388
464
|
nl_node_at_css(VALUE self, VALUE selector)
|
389
465
|
{
|
@@ -411,6 +487,11 @@ nl_node_at_css(VALUE self, VALUE selector)
|
|
411
487
|
return ret;
|
412
488
|
}
|
413
489
|
|
490
|
+
/**
|
491
|
+
* Internal implementation of {#css}
|
492
|
+
*
|
493
|
+
* @see #css
|
494
|
+
*/
|
414
495
|
static VALUE
|
415
496
|
nl_node_css(VALUE self, VALUE selector)
|
416
497
|
{
|
@@ -428,6 +509,11 @@ nl_node_css(VALUE self, VALUE selector)
|
|
428
509
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
429
510
|
}
|
430
511
|
|
512
|
+
/**
|
513
|
+
* Get the inner_html of this Node.
|
514
|
+
*
|
515
|
+
* @return [String]
|
516
|
+
*/
|
431
517
|
static VALUE
|
432
518
|
nl_node_inner_html(int argc, VALUE *argv, VALUE self)
|
433
519
|
{
|
@@ -465,6 +551,11 @@ nl_node_inner_html(int argc, VALUE *argv, VALUE self)
|
|
465
551
|
return Qnil;
|
466
552
|
}
|
467
553
|
|
554
|
+
/**
|
555
|
+
* Serialize this Node to HTML, also known as outer_html.
|
556
|
+
*
|
557
|
+
* @return [String]
|
558
|
+
*/
|
468
559
|
static VALUE
|
469
560
|
nl_node_outer_html(int argc, VALUE *argv, VALUE self)
|
470
561
|
{
|
@@ -502,6 +593,11 @@ nl_node_outer_html(int argc, VALUE *argv, VALUE self)
|
|
502
593
|
return Qnil;
|
503
594
|
}
|
504
595
|
|
596
|
+
/**
|
597
|
+
* call-seq: key?(name) -> Boolean
|
598
|
+
*
|
599
|
+
* @return true if +name+ is set.
|
600
|
+
*/
|
505
601
|
static VALUE
|
506
602
|
nl_node_has_key(VALUE self, VALUE rb_attr)
|
507
603
|
{
|
@@ -520,6 +616,11 @@ nl_node_has_key(VALUE self, VALUE rb_attr)
|
|
520
616
|
return lxb_dom_element_has_attribute(element, (const lxb_char_t *)attr_c, attr_len) ? Qtrue : Qfalse;
|
521
617
|
}
|
522
618
|
|
619
|
+
/**
|
620
|
+
* Get the attribute names of this Node.
|
621
|
+
*
|
622
|
+
* @return [Array<String>] An array of attribute names.
|
623
|
+
*/
|
523
624
|
static VALUE
|
524
625
|
nl_node_keys(VALUE self)
|
525
626
|
{
|
@@ -543,6 +644,11 @@ nl_node_keys(VALUE self)
|
|
543
644
|
return ary_keys;
|
544
645
|
}
|
545
646
|
|
647
|
+
/**
|
648
|
+
* Get the attribute values of this Node.
|
649
|
+
*
|
650
|
+
* @return [Array<String>] An array of attribute values.
|
651
|
+
*/
|
546
652
|
static VALUE
|
547
653
|
nl_node_values(VALUE self)
|
548
654
|
{
|
@@ -570,6 +676,11 @@ nl_node_values(VALUE self)
|
|
570
676
|
return ary_values;
|
571
677
|
}
|
572
678
|
|
679
|
+
/**
|
680
|
+
* Get a hash of attribute names and values of this Node.
|
681
|
+
*
|
682
|
+
* @return [Hash{String => String}] A hash whose keys are attribute names and values are attribute values.
|
683
|
+
*/
|
573
684
|
static VALUE
|
574
685
|
nl_node_attrs(VALUE self)
|
575
686
|
{
|
@@ -598,6 +709,11 @@ nl_node_attrs(VALUE self)
|
|
598
709
|
return rb_hash;
|
599
710
|
}
|
600
711
|
|
712
|
+
/**
|
713
|
+
* Get the parent node.
|
714
|
+
*
|
715
|
+
* @return [Node,nil] The parent node
|
716
|
+
*/
|
601
717
|
static VALUE
|
602
718
|
nl_node_parent(VALUE self)
|
603
719
|
{
|
@@ -605,6 +721,11 @@ nl_node_parent(VALUE self)
|
|
605
721
|
return node->parent ? nl_rb_node_create(node->parent, nl_rb_document_get(self)) : Qnil;
|
606
722
|
}
|
607
723
|
|
724
|
+
/**
|
725
|
+
* Get the previous sibling node.
|
726
|
+
*
|
727
|
+
* @return [Node,nil] The previous sibling node
|
728
|
+
*/
|
608
729
|
static VALUE
|
609
730
|
nl_node_previous(VALUE self)
|
610
731
|
{
|
@@ -612,6 +733,11 @@ nl_node_previous(VALUE self)
|
|
612
733
|
return node->prev ? nl_rb_node_create(node->prev, nl_rb_document_get(self)) : Qnil;
|
613
734
|
}
|
614
735
|
|
736
|
+
/**
|
737
|
+
* Get the previous sibling element.
|
738
|
+
*
|
739
|
+
* @return [Element,nil] The previous sibling element
|
740
|
+
*/
|
615
741
|
static VALUE
|
616
742
|
nl_node_previous_element(VALUE self)
|
617
743
|
{
|
@@ -625,6 +751,11 @@ nl_node_previous_element(VALUE self)
|
|
625
751
|
return Qnil;
|
626
752
|
}
|
627
753
|
|
754
|
+
/**
|
755
|
+
* Get the next sibling node.
|
756
|
+
*
|
757
|
+
* @return [Node,nil] The previous sibling node
|
758
|
+
*/
|
628
759
|
static VALUE
|
629
760
|
nl_node_next(VALUE self)
|
630
761
|
{
|
@@ -632,6 +763,11 @@ nl_node_next(VALUE self)
|
|
632
763
|
return node->next ? nl_rb_node_create(node->next, nl_rb_document_get(self)) : Qnil;
|
633
764
|
}
|
634
765
|
|
766
|
+
/**
|
767
|
+
* Get the next sibling element.
|
768
|
+
*
|
769
|
+
* @return [Element,nil] The previous sibling element
|
770
|
+
*/
|
635
771
|
static VALUE
|
636
772
|
nl_node_next_element(VALUE self)
|
637
773
|
{
|
@@ -645,6 +781,11 @@ nl_node_next_element(VALUE self)
|
|
645
781
|
return Qnil;
|
646
782
|
}
|
647
783
|
|
784
|
+
/**
|
785
|
+
* Get the children of this node.
|
786
|
+
*
|
787
|
+
* @return [NodeSet] The set of this node's children.
|
788
|
+
*/
|
648
789
|
static VALUE
|
649
790
|
nl_node_children(VALUE self)
|
650
791
|
{
|
@@ -660,6 +801,11 @@ nl_node_children(VALUE self)
|
|
660
801
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
661
802
|
}
|
662
803
|
|
804
|
+
/**
|
805
|
+
* Get the first child of this node.
|
806
|
+
*
|
807
|
+
* @return [Node,nil] The first child.
|
808
|
+
*/
|
663
809
|
static VALUE
|
664
810
|
nl_node_child(VALUE self)
|
665
811
|
{
|
@@ -668,14 +814,26 @@ nl_node_child(VALUE self)
|
|
668
814
|
return child ? nl_rb_node_create(child, nl_rb_document_get(self)) : Qnil;
|
669
815
|
}
|
670
816
|
|
817
|
+
/**
|
818
|
+
* Remove this node from its current context.
|
819
|
+
*
|
820
|
+
* @return [Node] +self+, to support chaining of calls.
|
821
|
+
*/
|
671
822
|
static VALUE
|
672
823
|
nl_node_remove(VALUE self)
|
673
824
|
{
|
674
825
|
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
675
826
|
lxb_dom_node_remove(node);
|
676
|
-
return
|
827
|
+
return self;
|
677
828
|
}
|
678
829
|
|
830
|
+
/**
|
831
|
+
* Remove this node from its current context and free its allocated memory.
|
832
|
+
*
|
833
|
+
* @return [nil]
|
834
|
+
*
|
835
|
+
* @see #remove
|
836
|
+
*/
|
679
837
|
static VALUE
|
680
838
|
nl_node_destroy(VALUE self)
|
681
839
|
{
|
@@ -684,6 +842,9 @@ nl_node_destroy(VALUE self)
|
|
684
842
|
return Qnil;
|
685
843
|
}
|
686
844
|
|
845
|
+
/**
|
846
|
+
* @return [Boolean] true if this Node is equal to +other+.
|
847
|
+
*/
|
687
848
|
static VALUE
|
688
849
|
nl_node_equals(VALUE self, VALUE other)
|
689
850
|
{
|
@@ -702,6 +863,11 @@ lxb_dom_node_name_qualified(lxb_dom_node_t *node, size_t *len)
|
|
702
863
|
return lxb_dom_node_name(node, len);
|
703
864
|
}
|
704
865
|
|
866
|
+
/**
|
867
|
+
* Get the name of this Node
|
868
|
+
*
|
869
|
+
* @return [String] The name of this Node
|
870
|
+
*/
|
705
871
|
static VALUE
|
706
872
|
nl_node_name(VALUE self)
|
707
873
|
{
|
@@ -733,6 +899,13 @@ nl_node_parse_fragment(lxb_dom_document_t *doc, lxb_dom_element_t *element, lxb_
|
|
733
899
|
return frag_root;
|
734
900
|
}
|
735
901
|
|
902
|
+
/**
|
903
|
+
* Parse +html+ as a document fragment within the context of
|
904
|
+
* *this* node.
|
905
|
+
*
|
906
|
+
* @param html [String] The fragment to be parsed.
|
907
|
+
* @return [NodeSet] The {NodeSet} containing the parsed nodes.
|
908
|
+
*/
|
736
909
|
static VALUE
|
737
910
|
nl_node_parse(VALUE self, VALUE html)
|
738
911
|
{
|
@@ -752,38 +925,48 @@ nl_node_parse(VALUE self, VALUE html)
|
|
752
925
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
753
926
|
}
|
754
927
|
|
928
|
+
typedef void (*lxb_dom_node_add_nodes_to_f)(lxb_dom_node_t *, lxb_dom_node_t *);
|
929
|
+
|
755
930
|
static VALUE
|
756
|
-
|
931
|
+
nl_node_add_nodes(VALUE self, VALUE new, lxb_dom_node_add_nodes_to_f add_to, bool operate_on_new_node)
|
757
932
|
{
|
758
933
|
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
759
934
|
lxb_dom_document_t *doc = node->owner_document;
|
760
935
|
|
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));
|
936
|
+
if (TYPE(new) == T_STRING || rb_obj_is_kind_of(new, cNokolexborDocumentFragment)) {
|
937
|
+
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))
|
938
|
+
: nl_rb_node_unwrap(new);
|
772
939
|
lexbor_array_t *array = lexbor_array_create();
|
773
940
|
|
941
|
+
lxb_dom_node_t *last_node = node;
|
774
942
|
while (frag_root->first_child != NULL) {
|
775
943
|
lxb_dom_node_t *child = frag_root->first_child;
|
776
944
|
lxb_dom_node_remove(child);
|
777
|
-
|
945
|
+
operate_on_new_node ? add_to(last_node, child) : add_to(node, child);
|
946
|
+
last_node = child;
|
778
947
|
lexbor_array_push(array, child);
|
779
948
|
}
|
780
|
-
|
949
|
+
if (TYPE(new) == T_STRING) {
|
950
|
+
lxb_dom_node_destroy(frag_root);
|
951
|
+
}
|
781
952
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
782
953
|
|
954
|
+
} else if (rb_obj_is_kind_of(new, cNokolexborNodeSet)) {
|
955
|
+
lexbor_array_t *node_array = nl_rb_node_set_unwrap(new);
|
956
|
+
|
957
|
+
lxb_dom_node_t *last_node = node;
|
958
|
+
for (size_t i = 0; i < node_array->length; i++) {
|
959
|
+
lxb_dom_node_t *child = (lxb_dom_node_t *)node_array->list[i];
|
960
|
+
lxb_dom_node_remove(child);
|
961
|
+
operate_on_new_node ? add_to(last_node, child) : add_to(node, child);
|
962
|
+
last_node = child;
|
963
|
+
}
|
964
|
+
return new;
|
965
|
+
|
783
966
|
} else if (rb_obj_is_kind_of(new, cNokolexborNode)) {
|
784
967
|
lxb_dom_node_t *node_new = nl_rb_node_unwrap(new);
|
785
968
|
lxb_dom_node_remove(node_new);
|
786
|
-
|
969
|
+
add_to(node, node_new);
|
787
970
|
return new;
|
788
971
|
|
789
972
|
} else {
|
@@ -792,43 +975,57 @@ nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
|
|
792
975
|
return Qnil;
|
793
976
|
}
|
794
977
|
|
978
|
+
/**
|
979
|
+
* Insert +node_or_tags+ before or after this Node (as a sibling).
|
980
|
+
*
|
981
|
+
* @see #add_previous_sibling
|
982
|
+
* @see #add_next_sibling
|
983
|
+
*
|
984
|
+
* @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}).
|
985
|
+
*/
|
795
986
|
static VALUE
|
796
|
-
|
987
|
+
nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
|
797
988
|
{
|
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
|
-
|
989
|
+
bool insert_after;
|
990
|
+
if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("next"))) {
|
991
|
+
insert_after = true;
|
992
|
+
} else if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("previous"))) {
|
993
|
+
insert_after = false;
|
820
994
|
} else {
|
821
|
-
rb_raise(rb_eArgError, "Unsupported
|
995
|
+
rb_raise(rb_eArgError, "Unsupported inserting position");
|
822
996
|
}
|
823
|
-
|
997
|
+
|
998
|
+
return insert_after ? nl_node_add_nodes(self, new, lxb_dom_node_insert_after, true)
|
999
|
+
: nl_node_add_nodes(self, new, lxb_dom_node_insert_before, false);
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
/**
|
1003
|
+
* Add +new+ as a child of this Node.
|
1004
|
+
*
|
1005
|
+
* @param new [Node, DocumentFragment, NodeSet, String] The node to be added.
|
1006
|
+
*
|
1007
|
+
* @return [Node,NodeSet] The reparented {Node} (if +new+ is a {Node}), or {NodeSet} (if +new+ is a {DocumentFragment}, {NodeSet}, or {String}).
|
1008
|
+
*/
|
1009
|
+
static VALUE
|
1010
|
+
nl_node_add_child(VALUE self, VALUE new)
|
1011
|
+
{
|
1012
|
+
return nl_node_add_nodes(self, new, lxb_dom_node_insert_child, false);
|
824
1013
|
}
|
825
1014
|
|
1015
|
+
/**
|
1016
|
+
* Get the type of this Node
|
1017
|
+
*
|
1018
|
+
* @return {Integer}
|
1019
|
+
*/
|
826
1020
|
static VALUE
|
827
1021
|
nl_node_get_type(VALUE self)
|
828
1022
|
{
|
829
1023
|
return INT2NUM(nl_rb_node_unwrap(self)->type);
|
830
1024
|
}
|
831
1025
|
|
1026
|
+
/**
|
1027
|
+
* @return [Element] The first child Node that is an element.
|
1028
|
+
*/
|
832
1029
|
static VALUE
|
833
1030
|
nl_node_first_element_child(VALUE self)
|
834
1031
|
{
|
@@ -856,6 +1053,9 @@ nl_node_first_element_child(VALUE self)
|
|
856
1053
|
return Qnil;
|
857
1054
|
}
|
858
1055
|
|
1056
|
+
/**
|
1057
|
+
* @return [Element] The last child Node that is an element.
|
1058
|
+
*/
|
859
1059
|
static VALUE
|
860
1060
|
nl_node_last_element_child(VALUE self)
|
861
1061
|
{
|
@@ -883,6 +1083,11 @@ nl_node_last_element_child(VALUE self)
|
|
883
1083
|
return Qnil;
|
884
1084
|
}
|
885
1085
|
|
1086
|
+
/**
|
1087
|
+
* Copy this node.
|
1088
|
+
*
|
1089
|
+
* @return [Node] The new {Node}.
|
1090
|
+
*/
|
886
1091
|
static VALUE
|
887
1092
|
nl_node_clone(VALUE self)
|
888
1093
|
{
|
@@ -891,9 +1096,9 @@ nl_node_clone(VALUE self)
|
|
891
1096
|
|
892
1097
|
switch (node->type) {
|
893
1098
|
case LXB_DOM_NODE_TYPE_ATTRIBUTE:
|
894
|
-
clone = lxb_dom_attr_interface_clone(node->owner_document, lxb_dom_interface_attr(node));
|
1099
|
+
clone = (lxb_dom_node_t *)lxb_dom_attr_interface_clone(node->owner_document, lxb_dom_interface_attr(node));
|
895
1100
|
case LXB_DOM_NODE_TYPE_CDATA_SECTION:
|
896
|
-
clone = lxb_dom_cdata_section_interface_clone(node->owner_document, lxb_dom_interface_cdata_section(node));
|
1101
|
+
clone = (lxb_dom_node_t *)lxb_dom_cdata_section_interface_clone(node->owner_document, lxb_dom_interface_cdata_section(node));
|
897
1102
|
default:
|
898
1103
|
clone = lxb_dom_node_clone(node, true);
|
899
1104
|
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, "+", "|");
|