nokolexbor 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/ext/nokolexbor/nl_attribute.c +46 -0
  3. data/ext/nokolexbor/nl_cdata.c +8 -0
  4. data/ext/nokolexbor/nl_comment.c +6 -0
  5. data/ext/nokolexbor/nl_document.c +53 -7
  6. data/ext/nokolexbor/nl_document_fragment.c +9 -0
  7. data/ext/nokolexbor/nl_error.c +21 -19
  8. data/ext/nokolexbor/nl_node.c +255 -49
  9. data/ext/nokolexbor/nl_node_set.c +56 -1
  10. data/ext/nokolexbor/nl_processing_instruction.c +6 -0
  11. data/ext/nokolexbor/nl_text.c +6 -0
  12. data/ext/nokolexbor/nokolexbor.h +1 -0
  13. data/lib/nokolexbor/document.rb +52 -5
  14. data/lib/nokolexbor/document_fragment.rb +11 -0
  15. data/lib/nokolexbor/node.rb +367 -18
  16. data/lib/nokolexbor/node_set.rb +56 -0
  17. data/lib/nokolexbor/version.rb +1 -1
  18. metadata +2 -24
  19. data/vendor/lexbor/source/lexbor/encoding/base.h +0 -218
  20. data/vendor/lexbor/source/lexbor/encoding/big5.c +0 -42839
  21. data/vendor/lexbor/source/lexbor/encoding/config.cmake +0 -12
  22. data/vendor/lexbor/source/lexbor/encoding/const.h +0 -65
  23. data/vendor/lexbor/source/lexbor/encoding/decode.c +0 -3193
  24. data/vendor/lexbor/source/lexbor/encoding/decode.h +0 -370
  25. data/vendor/lexbor/source/lexbor/encoding/encode.c +0 -1931
  26. data/vendor/lexbor/source/lexbor/encoding/encode.h +0 -377
  27. data/vendor/lexbor/source/lexbor/encoding/encoding.c +0 -252
  28. data/vendor/lexbor/source/lexbor/encoding/encoding.h +0 -475
  29. data/vendor/lexbor/source/lexbor/encoding/euc_kr.c +0 -53883
  30. data/vendor/lexbor/source/lexbor/encoding/gb18030.c +0 -47905
  31. data/vendor/lexbor/source/lexbor/encoding/iso_2022_jp_katakana.c +0 -159
  32. data/vendor/lexbor/source/lexbor/encoding/jis0208.c +0 -22477
  33. data/vendor/lexbor/source/lexbor/encoding/jis0212.c +0 -15787
  34. data/vendor/lexbor/source/lexbor/encoding/multi.h +0 -53
  35. data/vendor/lexbor/source/lexbor/encoding/range.c +0 -71
  36. data/vendor/lexbor/source/lexbor/encoding/range.h +0 -34
  37. data/vendor/lexbor/source/lexbor/encoding/res.c +0 -222
  38. data/vendor/lexbor/source/lexbor/encoding/res.h +0 -34
  39. data/vendor/lexbor/source/lexbor/encoding/single.c +0 -13748
  40. data/vendor/lexbor/source/lexbor/encoding/single.h +0 -116
@@ -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
- // case LXB_DOM_NODE_TYPE_DOCUMENT:
55
- // break;
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 Qnil;
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
- return lxb_dom_element_remove_attribute(element, (const lxb_char_t *)attr_c, attr_len) == LXB_STATUS_OK ? Qtrue : Qfalse;
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 Qnil;
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
- nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
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
- int insert_after;
762
- if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("next"))) {
763
- insert_after = 1;
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
- insert_after ? lxb_dom_node_insert_after(node, child) : lxb_dom_node_insert_before(node, child);
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
- lxb_dom_node_destroy(frag_root);
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
- insert_after ? lxb_dom_node_insert_after(node, node_new) : lxb_dom_node_insert_before(node, node_new);
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
- nl_node_add_child(VALUE self, VALUE new)
988
+ nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
797
989
  {
798
- lxb_dom_node_t *node = nl_rb_node_unwrap(self);
799
- lxb_dom_document_t *doc = node->owner_document;
800
-
801
- if (TYPE(new) == T_STRING) {
802
- lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, NULL, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
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 node type");
996
+ rb_raise(rb_eArgError, "Unsupported inserting position");
822
997
  }
823
- return Qnil;
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, "+", "|");