nokolexbor 0.3.4 → 0.3.6

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/ext/nokolexbor/extconf.rb +9 -5
  3. data/ext/nokolexbor/nl_attribute.c +46 -0
  4. data/ext/nokolexbor/nl_cdata.c +8 -0
  5. data/ext/nokolexbor/nl_comment.c +6 -0
  6. data/ext/nokolexbor/nl_document.c +53 -7
  7. data/ext/nokolexbor/nl_document_fragment.c +9 -0
  8. data/ext/nokolexbor/nl_error.c +21 -19
  9. data/ext/nokolexbor/nl_node.c +255 -50
  10. data/ext/nokolexbor/nl_node_set.c +56 -1
  11. data/ext/nokolexbor/nl_processing_instruction.c +6 -0
  12. data/ext/nokolexbor/nl_text.c +6 -0
  13. data/ext/nokolexbor/nokolexbor.h +1 -0
  14. data/lib/nokolexbor/document.rb +52 -5
  15. data/lib/nokolexbor/document_fragment.rb +11 -0
  16. data/lib/nokolexbor/node.rb +367 -18
  17. data/lib/nokolexbor/node_set.rb +56 -0
  18. data/lib/nokolexbor/version.rb +1 -1
  19. metadata +2 -24
  20. data/vendor/lexbor/source/lexbor/encoding/base.h +0 -218
  21. data/vendor/lexbor/source/lexbor/encoding/big5.c +0 -42839
  22. data/vendor/lexbor/source/lexbor/encoding/config.cmake +0 -12
  23. data/vendor/lexbor/source/lexbor/encoding/const.h +0 -65
  24. data/vendor/lexbor/source/lexbor/encoding/decode.c +0 -3193
  25. data/vendor/lexbor/source/lexbor/encoding/decode.h +0 -370
  26. data/vendor/lexbor/source/lexbor/encoding/encode.c +0 -1931
  27. data/vendor/lexbor/source/lexbor/encoding/encode.h +0 -377
  28. data/vendor/lexbor/source/lexbor/encoding/encoding.c +0 -252
  29. data/vendor/lexbor/source/lexbor/encoding/encoding.h +0 -475
  30. data/vendor/lexbor/source/lexbor/encoding/euc_kr.c +0 -53883
  31. data/vendor/lexbor/source/lexbor/encoding/gb18030.c +0 -47905
  32. data/vendor/lexbor/source/lexbor/encoding/iso_2022_jp_katakana.c +0 -159
  33. data/vendor/lexbor/source/lexbor/encoding/jis0208.c +0 -22477
  34. data/vendor/lexbor/source/lexbor/encoding/jis0212.c +0 -15787
  35. data/vendor/lexbor/source/lexbor/encoding/multi.h +0 -53
  36. data/vendor/lexbor/source/lexbor/encoding/range.c +0 -71
  37. data/vendor/lexbor/source/lexbor/encoding/range.h +0 -34
  38. data/vendor/lexbor/source/lexbor/encoding/res.c +0 -222
  39. data/vendor/lexbor/source/lexbor/encoding/res.h +0 -34
  40. data/vendor/lexbor/source/lexbor/encoding/single.c +0 -13748
  41. 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
@@ -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 Qnil;
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
- nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
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
- 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));
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
- insert_after ? lxb_dom_node_insert_after(node, child) : lxb_dom_node_insert_before(node, child);
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
- lxb_dom_node_destroy(frag_root);
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
- insert_after ? lxb_dom_node_insert_after(node, node_new) : lxb_dom_node_insert_before(node, node_new);
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
- nl_node_add_child(VALUE self, VALUE new)
987
+ nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
797
988
  {
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
-
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 node type");
995
+ rb_raise(rb_eArgError, "Unsupported inserting position");
822
996
  }
823
- return Qnil;
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, "+", "|");