nokolexbor 0.3.2 → 0.3.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e83f343175997fd437b89893ae63b7cc6eaffa86711800a42e8ce64371c03c85
4
- data.tar.gz: ea272e36f2a37cd5bc3e8e13b3fa8993098503abdaa85299bcf99f59ae484918
3
+ metadata.gz: 53cb1f54e475a0b10fc7773259866fe675e761d0ca204c5f685f4ed8dd60294a
4
+ data.tar.gz: 0e697320eae75b41e16ac431c6c679159507013b5e3a9858959377eb969355b2
5
5
  SHA512:
6
- metadata.gz: be0f026e8f2571705f1ae6225ddc4a3b7e78d7108e441a63d8b0988d4d0c91afa7af57ce8c6c318c1f2a5c38ebf00d9190ce29ec27de8e17505250273209d834
7
- data.tar.gz: 0000f9c78d7743e789c8edc11aaeaf4bf8a75503d0b6631a0a25a9d3c571a56fb424fc69d3e4c2a737d38c4a84c23424cd79a87f4b6f967b749522b217bd1abd
6
+ metadata.gz: 609b453f596331b53ab13b403c274cde9472e119307c0af63da19be28f0475603705ef285332c94f8b39a47b6850dfc138694ccee0ede531acffd67e31e915a9
7
+ data.tar.gz: 9f6d2c3ceba6d98bc8f87d59c846bd6c41fc2758681b66481c72de1027078d30e62344267cfe63ce58209e23f6749502750fa05f4365112275d79cee11641e9d
@@ -0,0 +1,155 @@
1
+ #include "nokolexbor.h"
2
+
3
+ VALUE cNokolexborAttribute;
4
+ extern VALUE mNokolexbor;
5
+ extern VALUE cNokolexborNode;
6
+
7
+ static VALUE
8
+ nl_attribute_new(int argc, VALUE *argv, VALUE klass)
9
+ {
10
+ lxb_dom_document_t *document;
11
+ VALUE rb_document;
12
+ VALUE rb_name;
13
+ VALUE rest;
14
+
15
+ rb_scan_args(argc, argv, "2*", &rb_document, &rb_name, &rest);
16
+
17
+ if (!rb_obj_is_kind_of(rb_document, cNokolexborDocument)) {
18
+ rb_raise(rb_eArgError, "Document must be a Nokolexbor::Document");
19
+ }
20
+
21
+ document = nl_rb_document_unwrap(rb_document);
22
+
23
+ const char *c_name = StringValuePtr(rb_name);
24
+ size_t name_len = RSTRING_LEN(rb_name);
25
+ lxb_dom_attr_t *attr = lxb_dom_attr_interface_create(document);
26
+ if (attr == NULL) {
27
+ rb_raise(rb_eRuntimeError, "Error creating attribute");
28
+ }
29
+
30
+ lxb_dom_attr_set_name(attr, (const lxb_char_t *)c_name, name_len, false);
31
+
32
+ VALUE rb_node = nl_rb_node_create(&attr->node, rb_document);
33
+
34
+ if (rb_block_given_p()) {
35
+ rb_yield(rb_node);
36
+ }
37
+
38
+ return rb_node;
39
+ }
40
+
41
+ static VALUE
42
+ nl_attribute_name(VALUE self)
43
+ {
44
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
45
+ lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
46
+
47
+ size_t len;
48
+ lxb_char_t *name = lxb_dom_attr_qualified_name(attr, &len);
49
+
50
+ return rb_utf8_str_new(name, len);
51
+ }
52
+
53
+ static VALUE
54
+ nl_attribute_set_name(VALUE self, VALUE rb_name)
55
+ {
56
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
57
+ lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
58
+
59
+ const char *c_name = StringValuePtr(rb_name);
60
+ size_t name_len = RSTRING_LEN(rb_name);
61
+
62
+ lxb_status_t status = lxb_dom_attr_set_name(attr, (const lxb_char_t *)c_name, name_len, false);
63
+ if (status != LXB_STATUS_OK) {
64
+ nl_raise_lexbor_error(status);
65
+ }
66
+
67
+ return rb_name;
68
+ }
69
+
70
+ static VALUE
71
+ nl_attribute_value(VALUE self)
72
+ {
73
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
74
+ lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
75
+
76
+ size_t len;
77
+ lxb_char_t *value = lxb_dom_attr_value(attr, &len);
78
+
79
+ return rb_utf8_str_new(value, len);
80
+ }
81
+
82
+ static VALUE
83
+ nl_attribute_set_value(VALUE self, VALUE rb_content)
84
+ {
85
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
86
+ lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
87
+
88
+ const char *c_content = StringValuePtr(rb_content);
89
+ size_t content_len = RSTRING_LEN(rb_content);
90
+
91
+ lxb_status_t status = lxb_dom_attr_set_value(attr, (const lxb_char_t *)c_content, content_len);
92
+ if (status != LXB_STATUS_OK) {
93
+ nl_raise_lexbor_error(status);
94
+ }
95
+
96
+ return rb_content;
97
+ }
98
+
99
+ static VALUE
100
+ nl_attribute_parent(VALUE self)
101
+ {
102
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
103
+ lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
104
+
105
+ if (attr->owner == NULL) {
106
+ return Qnil;
107
+ }
108
+ return nl_rb_node_create(attr->owner, nl_rb_document_get(self));
109
+ }
110
+
111
+ static VALUE
112
+ nl_attribute_previous(VALUE self)
113
+ {
114
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
115
+ lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
116
+
117
+ if (attr->prev == NULL) {
118
+ return Qnil;
119
+ }
120
+ return nl_rb_node_create(attr->prev, nl_rb_document_get(self));
121
+ }
122
+
123
+ static VALUE
124
+ nl_attribute_next(VALUE self)
125
+ {
126
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
127
+ lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
128
+
129
+ if (attr->next == NULL) {
130
+ return Qnil;
131
+ }
132
+ return nl_rb_node_create(attr->next, nl_rb_document_get(self));
133
+ }
134
+
135
+ void Init_nl_attribute(void)
136
+ {
137
+ cNokolexborAttribute = rb_define_class_under(mNokolexbor, "Attribute", cNokolexborNode);
138
+
139
+ rb_define_singleton_method(cNokolexborAttribute, "new", nl_attribute_new, -1);
140
+
141
+ rb_define_method(cNokolexborAttribute, "name", nl_attribute_name, 0);
142
+ rb_define_method(cNokolexborAttribute, "name=", nl_attribute_set_name, 1);
143
+ rb_define_method(cNokolexborAttribute, "value", nl_attribute_value, 0);
144
+ rb_define_method(cNokolexborAttribute, "value=", nl_attribute_set_value, 1);
145
+ rb_define_method(cNokolexborAttribute, "parent", nl_attribute_parent, 0);
146
+ rb_define_method(cNokolexborAttribute, "previous", nl_attribute_previous, 0);
147
+ rb_define_method(cNokolexborAttribute, "next", nl_attribute_next, 0);
148
+
149
+ rb_define_alias(cNokolexborAttribute, "node_name", "name");
150
+ rb_define_alias(cNokolexborAttribute, "node_name=", "name=");
151
+ rb_define_alias(cNokolexborAttribute, "text", "value");
152
+ rb_define_alias(cNokolexborAttribute, "content", "value");
153
+ rb_define_alias(cNokolexborAttribute, "to_s", "value");
154
+ rb_define_alias(cNokolexborAttribute, "to_str", "value");
155
+ }
@@ -20,7 +20,7 @@ nl_cdata_new(int argc, VALUE *argv, VALUE klass)
20
20
 
21
21
  document = nl_rb_document_unwrap(rb_document);
22
22
 
23
- const char* c_content = StringValuePtr(rb_content);
23
+ const char *c_content = StringValuePtr(rb_content);
24
24
  size_t content_len = RSTRING_LEN(rb_content);
25
25
  lxb_dom_cdata_section_t *element = lxb_dom_document_create_cdata_section(document, (const lxb_char_t *)c_content, content_len);
26
26
  if (element == NULL) {
@@ -20,7 +20,7 @@ nl_comment_new(int argc, VALUE *argv, VALUE klass)
20
20
 
21
21
  document = nl_rb_document_unwrap(rb_document);
22
22
 
23
- const char* c_content = StringValuePtr(rb_content);
23
+ const char *c_content = StringValuePtr(rb_content);
24
24
  size_t content_len = RSTRING_LEN(rb_content);
25
25
  lxb_dom_comment_t *element = lxb_dom_document_create_comment(document, (const lxb_char_t *)c_content, content_len);
26
26
  if (element == NULL) {
@@ -41,6 +41,8 @@ nl_document_parse(VALUE self, VALUE rb_string_or_io)
41
41
  rb_raise(rb_eRuntimeError, "Error creating document");
42
42
  }
43
43
 
44
+ lxb_dom_document_scripting_set(lxb_dom_interface_document(document), true);
45
+
44
46
  lxb_status_t status = lxb_html_document_parse(document, (const lxb_char_t *)html_c, html_len);
45
47
  if (status != LXB_STATUS_OK) {
46
48
  nl_raise_lexbor_error(status);
@@ -0,0 +1,39 @@
1
+ #include "nokolexbor.h"
2
+
3
+ VALUE cNokolexborDocumentFragment;
4
+ extern VALUE cNokolexborNode;
5
+ extern VALUE mNokolexbor;
6
+
7
+ static VALUE
8
+ nl_document_fragment_new(int argc, VALUE *argv, VALUE klass)
9
+ {
10
+ lxb_dom_document_t *document;
11
+ VALUE rb_document;
12
+ VALUE rest;
13
+
14
+ rb_scan_args(argc, argv, "1*", &rb_document, &rest);
15
+
16
+ if (!rb_obj_is_kind_of(rb_document, cNokolexborDocument)) {
17
+ rb_raise(rb_eArgError, "Document must be a Nokolexbor::Document");
18
+ }
19
+
20
+ document = nl_rb_document_unwrap(rb_document);
21
+
22
+ lxb_dom_document_fragment_t *node = lxb_dom_document_create_document_fragment(document);
23
+ if (node == NULL) {
24
+ rb_raise(rb_eRuntimeError, "Error creating document fragment");
25
+ }
26
+
27
+ VALUE rb_node = nl_rb_node_create(&node->node, rb_document);
28
+
29
+ rb_obj_call_init(rb_node, argc, argv);
30
+
31
+ return rb_node;
32
+ }
33
+
34
+ void Init_nl_document_fragment(void)
35
+ {
36
+ cNokolexborDocumentFragment = rb_define_class_under(mNokolexbor, "DocumentFragment", cNokolexborNode);
37
+
38
+ rb_define_singleton_method(cNokolexborDocumentFragment, "new", nl_document_fragment_new, -1);
39
+ }
@@ -0,0 +1,93 @@
1
+ #include "nokolexbor.h"
2
+
3
+ VALUE eLexborError;
4
+ VALUE eLexborMemoryAllocationError;
5
+ VALUE eLexborSmallBufferError;
6
+ VALUE eLexborObjectIsNullError;
7
+ VALUE eLexborIncompleteObjectError;
8
+ VALUE eLexborNoFreeSlotError;
9
+ VALUE eLexborTooSmallSizeError;
10
+ VALUE eLexborNotExistsError;
11
+ VALUE eLexborWrongArgsError;
12
+ VALUE eLexborWrongStageError;
13
+ VALUE eLexborUnexpectedResultError;
14
+ VALUE eLexborUnexpectedDataError;
15
+ VALUE eLexborOverflowError;
16
+ VALUE eLexborContinueStatus;
17
+ VALUE eLexborSmallBufferStatus;
18
+ VALUE eLexborAbortedStatus;
19
+ VALUE eLexborStoppedStatus;
20
+ VALUE eLexborNextStatus;
21
+ VALUE eLexborStopStatus;
22
+ extern VALUE mNokolexbor;
23
+
24
+ void nl_raise_lexbor_error(lxb_status_t error)
25
+ {
26
+ switch (error) {
27
+ case LXB_STATUS_ERROR:
28
+ rb_exc_raise(eLexborError);
29
+ case LXB_STATUS_ERROR_MEMORY_ALLOCATION:
30
+ rb_exc_raise(eLexborMemoryAllocationError);
31
+ case LXB_STATUS_ERROR_OBJECT_IS_NULL:
32
+ rb_exc_raise(eLexborObjectIsNullError);
33
+ case LXB_STATUS_ERROR_SMALL_BUFFER:
34
+ rb_exc_raise(eLexborSmallBufferError);
35
+ case LXB_STATUS_ERROR_INCOMPLETE_OBJECT:
36
+ rb_exc_raise(eLexborIncompleteObjectError);
37
+ case LXB_STATUS_ERROR_NO_FREE_SLOT:
38
+ rb_exc_raise(eLexborNoFreeSlotError);
39
+ case LXB_STATUS_ERROR_TOO_SMALL_SIZE:
40
+ rb_exc_raise(eLexborTooSmallSizeError);
41
+ case LXB_STATUS_ERROR_NOT_EXISTS:
42
+ rb_exc_raise(eLexborNotExistsError);
43
+ case LXB_STATUS_ERROR_WRONG_ARGS:
44
+ rb_exc_raise(eLexborWrongArgsError);
45
+ case LXB_STATUS_ERROR_WRONG_STAGE:
46
+ rb_exc_raise(eLexborWrongStageError);
47
+ case LXB_STATUS_ERROR_UNEXPECTED_RESULT:
48
+ rb_exc_raise(eLexborUnexpectedResultError);
49
+ case LXB_STATUS_ERROR_UNEXPECTED_DATA:
50
+ rb_raise(eLexborUnexpectedDataError, "Invalid syntax");
51
+ case LXB_STATUS_ERROR_OVERFLOW:
52
+ rb_exc_raise(eLexborOverflowError);
53
+ case LXB_STATUS_CONTINUE:
54
+ rb_exc_raise(eLexborContinueStatus);
55
+ case LXB_STATUS_SMALL_BUFFER:
56
+ rb_exc_raise(eLexborSmallBufferStatus);
57
+ case LXB_STATUS_ABORTED:
58
+ rb_exc_raise(eLexborAbortedStatus);
59
+ case LXB_STATUS_STOPPED:
60
+ rb_exc_raise(eLexborStoppedStatus);
61
+ case LXB_STATUS_NEXT:
62
+ rb_exc_raise(eLexborNextStatus);
63
+ case LXB_STATUS_STOP:
64
+ rb_exc_raise(eLexborStopStatus);
65
+ case LXB_STATUS_OK:
66
+ return;
67
+ default:
68
+ rb_raise(eLexborError, "Unknown error (%d)", error);
69
+ }
70
+ }
71
+
72
+ void Init_nl_error(void)
73
+ {
74
+ eLexborError = rb_define_class_under(mNokolexbor, "LexborError", rb_eStandardError);
75
+ eLexborMemoryAllocationError = rb_define_class_under(mNokolexbor, "LexborMemoryAllocationError", eLexborError);
76
+ eLexborSmallBufferError = rb_define_class_under(mNokolexbor, "LexborSmallBufferError", eLexborError);
77
+ eLexborObjectIsNullError = rb_define_class_under(mNokolexbor, "LexborObjectIsNullError", eLexborError);
78
+ eLexborIncompleteObjectError = rb_define_class_under(mNokolexbor, "LexborIncompleteObjectError", eLexborError);
79
+ eLexborNoFreeSlotError = rb_define_class_under(mNokolexbor, "LexborNoFreeSlotError", eLexborError);
80
+ eLexborTooSmallSizeError = rb_define_class_under(mNokolexbor, "LexborTooSmallSizeError", eLexborError);
81
+ eLexborNotExistsError = rb_define_class_under(mNokolexbor, "LexborNotExistsError", eLexborError);
82
+ eLexborWrongArgsError = rb_define_class_under(mNokolexbor, "LexborWrongArgsError", eLexborError);
83
+ eLexborWrongStageError = rb_define_class_under(mNokolexbor, "LexborWrongStageError", eLexborError);
84
+ eLexborUnexpectedResultError = rb_define_class_under(mNokolexbor, "LexborUnexpectedResultError", eLexborError);
85
+ eLexborUnexpectedDataError = rb_define_class_under(mNokolexbor, "LexborUnexpectedDataError", eLexborError);
86
+ eLexborOverflowError = rb_define_class_under(mNokolexbor, "LexborOverflowError", eLexborError);
87
+ eLexborContinueStatus = rb_define_class_under(mNokolexbor, "LexborContinueStatus", eLexborError);
88
+ eLexborSmallBufferStatus = rb_define_class_under(mNokolexbor, "LexborSmallBufferStatus", eLexborError);
89
+ eLexborAbortedStatus = rb_define_class_under(mNokolexbor, "LexborAbortedStatus", eLexborError);
90
+ eLexborStoppedStatus = rb_define_class_under(mNokolexbor, "LexborStoppedStatus", eLexborError);
91
+ eLexborNextStatus = rb_define_class_under(mNokolexbor, "LexborNextStatus", eLexborError);
92
+ eLexborStopStatus = rb_define_class_under(mNokolexbor, "LexborStopStatus", eLexborError);
93
+ }
@@ -9,7 +9,10 @@ extern VALUE mNokolexbor;
9
9
  extern VALUE cNokolexborDocument;
10
10
  extern VALUE cNokolexborText;
11
11
  extern VALUE cNokolexborComment;
12
+ extern VALUE cNokolexborProcessingInstruction;
12
13
  extern VALUE cNokolexborNodeSet;
14
+ extern VALUE cNokolexborDocumentFragment;
15
+ extern VALUE cNokolexborAttribute;
13
16
  extern VALUE eLexborError;
14
17
  VALUE cNokolexborNode;
15
18
  VALUE cNokolexborElement;
@@ -29,8 +32,9 @@ nl_rb_node_create(lxb_dom_node_t *node, VALUE rb_document)
29
32
  case LXB_DOM_NODE_TYPE_ELEMENT:
30
33
  rb_class = cNokolexborElement;
31
34
  break;
32
- // case LXB_DOM_NODE_TYPE_ATTRIBUTE:
33
- // break;
35
+ case LXB_DOM_NODE_TYPE_ATTRIBUTE:
36
+ rb_class = cNokolexborAttribute;
37
+ break;
34
38
  case LXB_DOM_NODE_TYPE_TEXT:
35
39
  rb_class = cNokolexborText;
36
40
  break;
@@ -41,8 +45,9 @@ nl_rb_node_create(lxb_dom_node_t *node, VALUE rb_document)
41
45
  // break;
42
46
  // case LXB_DOM_NODE_TYPE_ENTITY:
43
47
  // break;
44
- // case LXB_DOM_NODE_TYPE_PROCESSING_INSTRUCTION:
45
- // break;
48
+ case LXB_DOM_NODE_TYPE_PROCESSING_INSTRUCTION:
49
+ rb_class = cNokolexborProcessingInstruction;
50
+ break;
46
51
  case LXB_DOM_NODE_TYPE_COMMENT:
47
52
  rb_class = cNokolexborComment;
48
53
  break;
@@ -50,8 +55,9 @@ nl_rb_node_create(lxb_dom_node_t *node, VALUE rb_document)
50
55
  // break;
51
56
  // case LXB_DOM_NODE_TYPE_DOCUMENT_TYPE:
52
57
  // break;
53
- // case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT:
54
- // break;
58
+ case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT:
59
+ rb_class = cNokolexborDocumentFragment;
60
+ break;
55
61
  // case LXB_DOM_NODE_TYPE_NOTATION:
56
62
  // break;
57
63
  default:
@@ -91,7 +97,7 @@ nl_node_new(int argc, VALUE *argv, VALUE klass)
91
97
 
92
98
  document = nl_rb_document_unwrap(rb_document);
93
99
 
94
- const char* c_name = StringValuePtr(rb_name);
100
+ const char *c_name = StringValuePtr(rb_name);
95
101
  size_t name_len = RSTRING_LEN(rb_name);
96
102
  lxb_dom_element_t *element = lxb_dom_document_create_element(document, (const lxb_char_t *)c_name, name_len, NULL);
97
103
  if (element == NULL) {
@@ -107,6 +113,55 @@ nl_node_new(int argc, VALUE *argv, VALUE klass)
107
113
  return rb_node;
108
114
  }
109
115
 
116
+ static VALUE
117
+ nl_node_attribute(VALUE self, VALUE rb_name)
118
+ {
119
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
120
+
121
+ const char *c_name = StringValuePtr(rb_name);
122
+ size_t name_len = RSTRING_LEN(rb_name);
123
+
124
+ if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
125
+ return Qnil;
126
+ }
127
+
128
+ lxb_dom_attr_t *attr = lxb_dom_element_attr_by_name(lxb_dom_interface_element(node), (const lxb_char_t *)c_name, name_len);
129
+ if (attr == NULL) {
130
+ return Qnil;
131
+ }
132
+ if (attr->owner == NULL) {
133
+ attr->owner = node;
134
+ }
135
+ return nl_rb_node_create(attr, nl_rb_document_get(self));
136
+ }
137
+
138
+ static VALUE
139
+ nl_node_attribute_nodes(VALUE self)
140
+ {
141
+ lxb_dom_node_t *node = nl_rb_node_unwrap(self);
142
+ VALUE ary = rb_ary_new();
143
+ if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
144
+ return ary;
145
+ }
146
+
147
+ lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
148
+
149
+ if (attr == NULL) {
150
+ return ary;
151
+ }
152
+
153
+ VALUE rb_doc = nl_rb_document_get(self);
154
+ while (attr != NULL) {
155
+ if (attr->owner == NULL) {
156
+ attr->owner = node;
157
+ }
158
+ rb_ary_push(ary, nl_rb_node_create(attr, rb_doc));
159
+ attr = attr->next;
160
+ }
161
+
162
+ return ary;
163
+ }
164
+
110
165
  static VALUE
111
166
  nl_node_content(VALUE self)
112
167
  {
@@ -657,17 +712,19 @@ nl_node_name(VALUE self)
657
712
  }
658
713
 
659
714
  static lxb_dom_node_t *
660
- nl_node_parse_fragment(lxb_dom_document_t *doc, lxb_char_t *html, size_t size)
715
+ nl_node_parse_fragment(lxb_dom_document_t *doc, lxb_dom_element_t *element, lxb_char_t *html, size_t size)
661
716
  {
662
717
  size_t tag_name_len;
663
718
  lxb_html_document_t *html_doc = lxb_html_interface_document(doc);
664
- const lxb_char_t *tag_name = lxb_tag_name_by_id(lxb_html_document_tags(html_doc), LXB_TAG__UNDEF, &tag_name_len);
665
- if (tag_name == NULL) {
666
- rb_raise(rb_eRuntimeError, "Error getting tag name");
667
- }
668
- lxb_dom_element_t *element = lxb_dom_document_create_element(doc, tag_name, tag_name_len, NULL);
669
719
  if (element == NULL) {
670
- rb_raise(rb_eRuntimeError, "Error creating element");
720
+ const lxb_char_t *tag_name = lxb_tag_name_by_id(lxb_html_document_tags(html_doc), LXB_TAG__UNDEF, &tag_name_len);
721
+ if (tag_name == NULL) {
722
+ rb_raise(rb_eRuntimeError, "Error getting tag name");
723
+ }
724
+ element = lxb_dom_document_create_element(doc, tag_name, tag_name_len, NULL);
725
+ if (element == NULL) {
726
+ rb_raise(rb_eRuntimeError, "Error creating element");
727
+ }
671
728
  }
672
729
  lxb_dom_node_t *frag_root = lxb_html_document_parse_fragment(html_doc, element, html, size);
673
730
  if (frag_root == NULL) {
@@ -677,14 +734,22 @@ nl_node_parse_fragment(lxb_dom_document_t *doc, lxb_char_t *html, size_t size)
677
734
  }
678
735
 
679
736
  static VALUE
680
- nl_node_fragment(VALUE self, VALUE html)
737
+ nl_node_parse(VALUE self, VALUE html)
681
738
  {
682
739
  Check_Type(html, T_STRING);
683
740
  lxb_dom_node_t *node = nl_rb_node_unwrap(self);
684
741
  lxb_dom_document_t *doc = node->owner_document;
685
742
 
686
- lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, (lxb_char_t *)RSTRING_PTR(html), RSTRING_LEN(html));
687
- return nl_rb_node_create(frag_root, nl_rb_document_get(self));
743
+ lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, lxb_dom_interface_element(node), (lxb_char_t *)RSTRING_PTR(html), RSTRING_LEN(html));
744
+ lexbor_array_t *array = lexbor_array_create();
745
+
746
+ while (frag_root->first_child != NULL) {
747
+ lxb_dom_node_t *child = frag_root->first_child;
748
+ lxb_dom_node_remove(child);
749
+ lexbor_array_push(array, child);
750
+ }
751
+ lxb_dom_node_destroy(frag_root);
752
+ return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
688
753
  }
689
754
 
690
755
  static VALUE
@@ -703,7 +768,7 @@ nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
703
768
  }
704
769
 
705
770
  if (TYPE(new) == T_STRING) {
706
- lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
771
+ lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, NULL, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
707
772
  lexbor_array_t *array = lexbor_array_create();
708
773
 
709
774
  while (frag_root->first_child != NULL) {
@@ -734,7 +799,7 @@ nl_node_add_child(VALUE self, VALUE new)
734
799
  lxb_dom_document_t *doc = node->owner_document;
735
800
 
736
801
  if (TYPE(new) == T_STRING) {
737
- lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
802
+ lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, NULL, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
738
803
  lexbor_array_t *array = lexbor_array_create();
739
804
 
740
805
  while (frag_root->first_child != NULL) {
@@ -822,7 +887,17 @@ static VALUE
822
887
  nl_node_clone(VALUE self)
823
888
  {
824
889
  lxb_dom_node_t *node = nl_rb_node_unwrap(self);
825
- lxb_dom_node_t *clone = lxb_dom_node_clone(node, 1);
890
+ lxb_dom_node_t *clone;
891
+
892
+ switch (node->type) {
893
+ case LXB_DOM_NODE_TYPE_ATTRIBUTE:
894
+ clone = lxb_dom_attr_interface_clone(node->owner_document, lxb_dom_interface_attr(node));
895
+ case LXB_DOM_NODE_TYPE_CDATA_SECTION:
896
+ clone = lxb_dom_cdata_section_interface_clone(node->owner_document, lxb_dom_interface_cdata_section(node));
897
+ default:
898
+ clone = lxb_dom_node_clone(node, true);
899
+ break;
900
+ }
826
901
  return nl_rb_node_create(clone, nl_rb_document_get(self));
827
902
  }
828
903
 
@@ -835,6 +910,8 @@ void Init_nl_node(void)
835
910
  cNokolexborCharacterData = rb_define_class_under(mNokolexbor, "CharacterData", cNokolexborNode);
836
911
 
837
912
  rb_define_singleton_method(cNokolexborNode, "new", nl_node_new, -1);
913
+ rb_define_method(cNokolexborNode, "attribute", nl_node_attribute, 1);
914
+ rb_define_method(cNokolexborNode, "attribute_nodes", nl_node_attribute_nodes, 0);
838
915
  rb_define_method(cNokolexborNode, "content", nl_node_content, 0);
839
916
  rb_define_method(cNokolexborNode, "content=", nl_node_content_set, 1);
840
917
  rb_define_method(cNokolexborNode, "[]", nl_node_get_attr, 1);
@@ -859,7 +936,7 @@ void Init_nl_node(void)
859
936
  rb_define_method(cNokolexborNode, "destroy", nl_node_destroy, 0);
860
937
  rb_define_method(cNokolexborNode, "attrs", nl_node_attrs, 0);
861
938
  rb_define_method(cNokolexborNode, "name", nl_node_name, 0);
862
- rb_define_method(cNokolexborNode, "fragment", nl_node_fragment, 1);
939
+ rb_define_method(cNokolexborNode, "parse", nl_node_parse, 1);
863
940
  rb_define_method(cNokolexborNode, "add_sibling", nl_node_add_sibling, 2);
864
941
  rb_define_method(cNokolexborNode, "add_child", nl_node_add_child, 1);
865
942
  rb_define_method(cNokolexborNode, "node_type", nl_node_get_type, 0);
@@ -0,0 +1,47 @@
1
+ #include "nokolexbor.h"
2
+
3
+ VALUE cNokolexborProcessingInstruction;
4
+ extern VALUE cNokolexborNode;
5
+ extern VALUE mNokolexbor;
6
+
7
+ static VALUE
8
+ nl_processing_instruction_new(int argc, VALUE *argv, VALUE klass)
9
+ {
10
+ lxb_dom_document_t *document;
11
+ VALUE rb_name;
12
+ VALUE rb_content;
13
+ VALUE rb_document;
14
+ VALUE rest;
15
+
16
+ rb_scan_args(argc, argv, "3*", &rb_name, &rb_content, &rb_document, &rest);
17
+
18
+ if (!rb_obj_is_kind_of(rb_document, cNokolexborDocument)) {
19
+ rb_raise(rb_eArgError, "Document must be a Nokolexbor::Document");
20
+ }
21
+
22
+ document = nl_rb_document_unwrap(rb_document);
23
+
24
+ const char *c_name = StringValuePtr(rb_name);
25
+ size_t name_len = RSTRING_LEN(rb_name);
26
+ const char *c_content = StringValuePtr(rb_content);
27
+ size_t content_len = RSTRING_LEN(rb_content);
28
+ lxb_dom_processing_instruction_t *node = lxb_dom_document_create_processing_instruction(document, (const lxb_char_t *)c_name, name_len, (const lxb_char_t *)c_content, content_len);
29
+ if (node == NULL) {
30
+ rb_raise(rb_eRuntimeError, "Error creating processing instruction");
31
+ }
32
+
33
+ VALUE rb_node = nl_rb_node_create(&node->char_data.node, rb_document);
34
+
35
+ if (rb_block_given_p()) {
36
+ rb_yield(rb_node);
37
+ }
38
+
39
+ return rb_node;
40
+ }
41
+
42
+ void Init_nl_processing_instruction(void)
43
+ {
44
+ cNokolexborProcessingInstruction = rb_define_class_under(mNokolexbor, "ProcessingInstruction", cNokolexborNode);
45
+
46
+ rb_define_singleton_method(cNokolexborProcessingInstruction, "new", nl_processing_instruction_new, -1);
47
+ }
@@ -20,7 +20,7 @@ nl_text_new(int argc, VALUE *argv, VALUE klass)
20
20
 
21
21
  document = nl_rb_document_unwrap(rb_document);
22
22
 
23
- const char* c_text = StringValuePtr(rb_text);
23
+ const char *c_text = StringValuePtr(rb_text);
24
24
  size_t text_len = RSTRING_LEN(rb_text);
25
25
  lxb_dom_text_t *element = lxb_dom_document_create_text_node(document, (const lxb_char_t *)c_text, text_len);
26
26
  if (element == NULL) {
@@ -329,9 +329,9 @@ nl_xpath_context_new(VALUE klass, VALUE rb_node)
329
329
  nl_xmlXPathRegisterNs(ctx, NOKOGIRI_PREFIX, NOKOGIRI_URI);
330
330
  nl_xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
331
331
  nl_xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
332
- xpath_builtin_css_class);
332
+ xpath_builtin_css_class);
333
333
  nl_xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
334
- xpath_builtin_local_name_is);
334
+ xpath_builtin_local_name_is);
335
335
 
336
336
  self = Data_Wrap_Struct(klass, 0, free_xml_xpath_context, ctx);
337
337
  rb_iv_set(self, "@document", nl_rb_document_get(rb_node));
@@ -1,56 +1,6 @@
1
1
  #include "nokolexbor.h"
2
2
 
3
3
  VALUE mNokolexbor;
4
- VALUE eLexborError;
5
- VALUE eLexborSyntaxError;
6
-
7
- void nl_raise_lexbor_error(lxb_status_t error)
8
- {
9
- switch (error) {
10
- case LXB_STATUS_ERROR:
11
- rb_raise(eLexborError, "LXB_STATUS_ERROR");
12
- case LXB_STATUS_ERROR_MEMORY_ALLOCATION:
13
- rb_raise(eLexborError, "LXB_STATUS_ERROR_MEMORY_ALLOCATION");
14
- case LXB_STATUS_ERROR_OBJECT_IS_NULL:
15
- rb_raise(eLexborError, "LXB_STATUS_ERROR_OBJECT_IS_NULL");
16
- case LXB_STATUS_ERROR_SMALL_BUFFER:
17
- rb_raise(eLexborError, "LXB_STATUS_ERROR_SMALL_BUFFER");
18
- case LXB_STATUS_ERROR_INCOMPLETE_OBJECT:
19
- rb_raise(eLexborError, "LXB_STATUS_ERROR_INCOMPLETE_OBJECT");
20
- case LXB_STATUS_ERROR_NO_FREE_SLOT:
21
- rb_raise(eLexborError, "LXB_STATUS_ERROR_NO_FREE_SLOT");
22
- case LXB_STATUS_ERROR_TOO_SMALL_SIZE:
23
- rb_raise(eLexborError, "LXB_STATUS_ERROR_TOO_SMALL_SIZE");
24
- case LXB_STATUS_ERROR_NOT_EXISTS:
25
- rb_raise(eLexborError, "LXB_STATUS_ERROR_NOT_EXISTS");
26
- case LXB_STATUS_ERROR_WRONG_ARGS:
27
- rb_raise(eLexborError, "LXB_STATUS_ERROR_WRONG_ARGS");
28
- case LXB_STATUS_ERROR_WRONG_STAGE:
29
- rb_raise(eLexborError, "LXB_STATUS_ERROR_WRONG_STAGE");
30
- case LXB_STATUS_ERROR_UNEXPECTED_RESULT:
31
- rb_raise(eLexborError, "LXB_STATUS_ERROR_UNEXPECTED_RESULT");
32
- case LXB_STATUS_ERROR_UNEXPECTED_DATA:
33
- rb_raise(eLexborSyntaxError, "LXB_STATUS_ERROR_UNEXPECTED_DATA");
34
- case LXB_STATUS_ERROR_OVERFLOW:
35
- rb_raise(eLexborError, "LXB_STATUS_ERROR_OVERFLOW");
36
- case LXB_STATUS_CONTINUE:
37
- rb_raise(eLexborError, "LXB_STATUS_CONTINUE");
38
- case LXB_STATUS_SMALL_BUFFER:
39
- rb_raise(eLexborError, "LXB_STATUS_SMALL_BUFFER");
40
- case LXB_STATUS_ABORTED:
41
- rb_raise(eLexborError, "LXB_STATUS_ABORTED");
42
- case LXB_STATUS_STOPPED:
43
- rb_raise(eLexborError, "LXB_STATUS_STOPPED");
44
- case LXB_STATUS_NEXT:
45
- rb_raise(eLexborError, "LXB_STATUS_NEXT");
46
- case LXB_STATUS_STOP:
47
- rb_raise(eLexborError, "LXB_STATUS_STOP");
48
- case LXB_STATUS_OK:
49
- return;
50
- default:
51
- rb_raise(eLexborError, "LXB_ERROR_UKNOWN(%d)", error);
52
- }
53
- }
54
4
 
55
5
  void Init_nokolexbor(void)
56
6
  {
@@ -58,13 +8,15 @@ void Init_nokolexbor(void)
58
8
  lexbor_memory_setup(ruby_xmalloc, ruby_xrealloc, ruby_xcalloc, ruby_xfree);
59
9
  #endif
60
10
  mNokolexbor = rb_define_module("Nokolexbor");
61
- eLexborError = rb_define_class_under(mNokolexbor, "LexborError", rb_eStandardError);
62
- eLexborSyntaxError = rb_define_class_under(mNokolexbor, "LexborSyntaxError", eLexborError);
11
+ Init_nl_error();
63
12
  Init_nl_node();
64
13
  Init_nl_document();
65
14
  Init_nl_text();
66
15
  Init_nl_comment();
67
16
  Init_nl_cdata();
17
+ Init_nl_processing_instruction();
68
18
  Init_nl_node_set();
19
+ Init_nl_document_fragment();
20
+ Init_nl_attribute();
69
21
  Init_nl_xpath_context();
70
22
  }
@@ -9,12 +9,16 @@
9
9
 
10
10
  extern VALUE cNokolexborDocument;
11
11
 
12
+ void Init_nl_error(void);
12
13
  void Init_nl_document(void);
13
14
  void Init_nl_node(void);
14
- void Init_nl_node_set(void);
15
15
  void Init_nl_text(void);
16
16
  void Init_nl_comment(void);
17
17
  void Init_nl_cdata(void);
18
+ void Init_nl_processing_instruction(void);
19
+ void Init_nl_node_set(void);
20
+ void Init_nl_document_fragment(void);
21
+ void Init_nl_attribute(void);
18
22
  void Init_nl_xpath_context(void);
19
23
 
20
24
  void nl_raise_lexbor_error(lxb_status_t error);
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokolexbor
4
+ class DocumentFragment < Nokolexbor::Node
5
+ def self.parse(tags)
6
+ new(Nokolexbor::Document.new, tags, nil)
7
+ end
8
+
9
+ def initialize(document, tags = nil, ctx = nil)
10
+ return self unless tags
11
+
12
+ ctx ||= document
13
+ node_set = ctx.parse(tags)
14
+ node_set.each { |child| child.parent = self } unless node_set.empty?
15
+ nil
16
+ end
17
+
18
+ def name
19
+ "#document-fragment"
20
+ end
21
+
22
+ alias_method :outer_html, :inner_html
23
+ alias_method :to_html, :outer_html
24
+ alias_method :to_s, :outer_html
25
+ alias_method :serialize, :outer_html
26
+
27
+ def fragment(data)
28
+ document.fragment(data)
29
+ end
30
+ end
31
+ end
@@ -145,13 +145,10 @@ module Nokolexbor
145
145
  ancestors.last.css(selector).any? { |node| node == self }
146
146
  end
147
147
 
148
- def attribute(name)
149
- return nil unless key?(name)
150
- Attribute.new(name, attr(name))
151
- end
152
-
153
148
  def attributes
154
- attrs.map { |k, v| [k, Attribute.new(k, v)] }.to_h
149
+ attribute_nodes.each_with_object({}) do |node, hash|
150
+ hash[node.name] = node
151
+ end
155
152
  end
156
153
 
157
154
  def replace(node)
@@ -182,6 +179,10 @@ module Nokolexbor
182
179
  end
183
180
  end
184
181
 
182
+ def fragment(tags)
183
+ Nokolexbor::DocumentFragment.new(document, tags, self)
184
+ end
185
+
185
186
  alias_method :inner_html=, :children=
186
187
 
187
188
  def css(*args)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nokolexbor
4
- VERSION = '0.3.2'
4
+ VERSION = '0.3.4'
5
5
  end
data/lib/nokolexbor.rb CHANGED
@@ -25,7 +25,7 @@ require 'nokolexbor/version'
25
25
  require 'nokolexbor/node'
26
26
  require 'nokolexbor/document'
27
27
  require 'nokolexbor/node_set'
28
- require 'nokolexbor/attribute'
28
+ require 'nokolexbor/document_fragment'
29
29
  require 'nokolexbor/xpath'
30
30
  require 'nokolexbor/xpath_context'
31
31
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nokolexbor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yicheng Zhou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-09 00:00:00.000000000 Z
11
+ date: 2023-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -78,11 +78,15 @@ files:
78
78
  - ext/nokolexbor/libxml/xpath.h
79
79
  - ext/nokolexbor/libxml/xpathInternals.h
80
80
  - ext/nokolexbor/libxml/xpointer.h
81
+ - ext/nokolexbor/nl_attribute.c
81
82
  - ext/nokolexbor/nl_cdata.c
82
83
  - ext/nokolexbor/nl_comment.c
83
84
  - ext/nokolexbor/nl_document.c
85
+ - ext/nokolexbor/nl_document_fragment.c
86
+ - ext/nokolexbor/nl_error.c
84
87
  - ext/nokolexbor/nl_node.c
85
88
  - ext/nokolexbor/nl_node_set.c
89
+ - ext/nokolexbor/nl_processing_instruction.c
86
90
  - ext/nokolexbor/nl_text.c
87
91
  - ext/nokolexbor/nl_xpath_context.c
88
92
  - ext/nokolexbor/nokolexbor.c
@@ -116,8 +120,8 @@ files:
116
120
  - ext/nokolexbor/xml_tree.c
117
121
  - ext/nokolexbor/xml_xpath.c
118
122
  - lib/nokolexbor.rb
119
- - lib/nokolexbor/attribute.rb
120
123
  - lib/nokolexbor/document.rb
124
+ - lib/nokolexbor/document_fragment.rb
121
125
  - lib/nokolexbor/node.rb
122
126
  - lib/nokolexbor/node_set.rb
123
127
  - lib/nokolexbor/version.rb
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nokolexbor
4
- class Attribute
5
- attr_accessor :name
6
- attr_accessor :value
7
-
8
- def initialize(name, value)
9
- @name = name
10
- @value = value
11
- end
12
-
13
- alias_method :text, :value
14
- alias_method :content, :value
15
- alias_method :to_s, :value
16
- alias_method :to_str, :value
17
- end
18
- end