nokolexbor 0.3.2 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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