nokolexbor 0.3.6 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/nokolexbor/nl_attribute.c +15 -0
- data/ext/nokolexbor/nl_node.c +53 -1
- data/ext/nokolexbor/nl_node_set.c +60 -0
- data/lib/nokolexbor/node_set.rb +83 -0
- data/lib/nokolexbor/version.rb +1 -1
- data/patches/0004-lexbor-fix-template-clone.patch +24 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f60315f588c46f8ae2927633d3e34ee8f3aa3f6fb97575851bc967f306d216a5
|
4
|
+
data.tar.gz: 8e71ffb858e63f59284b94eee695b90808875c9af388175937a4e04cfbff715c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70c50097ea4a844399ee4c74e7d0413a833dbdfd878208a8b7054ad2d01c2d96c35897b62848b199555b675a409f897a30e9cf90d2dd8c3e74c2fdf8b501340f
|
7
|
+
data.tar.gz: 7c772720a861bde11b10c1ff23d4796738a58eaa07d32b43478975a4feaab6402ef5fe8819eb9081619b50b970a422a40b613ce405fa2940b54da4929e352bc8
|
@@ -178,6 +178,20 @@ nl_attribute_next(VALUE self)
|
|
178
178
|
return nl_rb_node_create(attr->next, nl_rb_document_get(self));
|
179
179
|
}
|
180
180
|
|
181
|
+
static VALUE
|
182
|
+
nl_attribute_inspect(VALUE self)
|
183
|
+
{
|
184
|
+
VALUE c = rb_class_name(CLASS_OF(self));
|
185
|
+
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
186
|
+
lxb_dom_attr_t *attr = lxb_dom_interface_attr(node);
|
187
|
+
size_t len;
|
188
|
+
lxb_char_t *attr_value = lxb_dom_attr_value(attr, &len);
|
189
|
+
|
190
|
+
return rb_sprintf("#<%" PRIsVALUE " %s=\"%s\">", c,
|
191
|
+
lxb_dom_attr_qualified_name(attr, &len),
|
192
|
+
attr_value == NULL ? "" : attr_value);
|
193
|
+
}
|
194
|
+
|
181
195
|
void Init_nl_attribute(void)
|
182
196
|
{
|
183
197
|
cNokolexborAttribute = rb_define_class_under(mNokolexbor, "Attribute", cNokolexborNode);
|
@@ -191,6 +205,7 @@ void Init_nl_attribute(void)
|
|
191
205
|
rb_define_method(cNokolexborAttribute, "parent", nl_attribute_parent, 0);
|
192
206
|
rb_define_method(cNokolexborAttribute, "previous", nl_attribute_previous, 0);
|
193
207
|
rb_define_method(cNokolexborAttribute, "next", nl_attribute_next, 0);
|
208
|
+
rb_define_method(cNokolexborAttribute, "inspect", nl_attribute_inspect, 0);
|
194
209
|
|
195
210
|
rb_define_alias(cNokolexborAttribute, "node_name", "name");
|
196
211
|
rb_define_alias(cNokolexborAttribute, "node_name=", "name=");
|
data/ext/nokolexbor/nl_node.c
CHANGED
@@ -9,6 +9,7 @@ extern VALUE mNokolexbor;
|
|
9
9
|
extern VALUE cNokolexborDocument;
|
10
10
|
extern VALUE cNokolexborText;
|
11
11
|
extern VALUE cNokolexborComment;
|
12
|
+
extern VALUE cNokolexborCData;
|
12
13
|
extern VALUE cNokolexborProcessingInstruction;
|
13
14
|
extern VALUE cNokolexborNodeSet;
|
14
15
|
extern VALUE cNokolexborDocumentFragment;
|
@@ -39,7 +40,7 @@ nl_rb_node_create(lxb_dom_node_t *node, VALUE rb_document)
|
|
39
40
|
rb_class = cNokolexborText;
|
40
41
|
break;
|
41
42
|
case LXB_DOM_NODE_TYPE_CDATA_SECTION:
|
42
|
-
rb_class =
|
43
|
+
rb_class = cNokolexborCData;
|
43
44
|
break;
|
44
45
|
// case LXB_DOM_NODE_TYPE_ENTITY_REFERENCE:
|
45
46
|
// break;
|
@@ -801,6 +802,28 @@ nl_node_children(VALUE self)
|
|
801
802
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
802
803
|
}
|
803
804
|
|
805
|
+
/**
|
806
|
+
* Get the element children of this node.
|
807
|
+
*
|
808
|
+
* @return [NodeSet] The set of this node's element children.
|
809
|
+
*/
|
810
|
+
static VALUE
|
811
|
+
nl_node_element_children(VALUE self)
|
812
|
+
{
|
813
|
+
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
814
|
+
lxb_dom_node_t *child = node->first_child;
|
815
|
+
lexbor_array_t *array = lexbor_array_create();
|
816
|
+
|
817
|
+
while (child != NULL) {
|
818
|
+
if (child->type == LXB_DOM_NODE_TYPE_ELEMENT) {
|
819
|
+
lexbor_array_push(array, child);
|
820
|
+
}
|
821
|
+
child = child->next;
|
822
|
+
}
|
823
|
+
|
824
|
+
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
825
|
+
}
|
826
|
+
|
804
827
|
/**
|
805
828
|
* Get the first child of this node.
|
806
829
|
*
|
@@ -1106,6 +1129,32 @@ nl_node_clone(VALUE self)
|
|
1106
1129
|
return nl_rb_node_create(clone, nl_rb_document_get(self));
|
1107
1130
|
}
|
1108
1131
|
|
1132
|
+
static VALUE
|
1133
|
+
nl_node_inspect(int argc, VALUE *argv, VALUE self)
|
1134
|
+
{
|
1135
|
+
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
|
1136
|
+
if (node->type == LXB_DOM_NODE_TYPE_DOCUMENT) {
|
1137
|
+
return rb_call_super(argc, argv);
|
1138
|
+
}
|
1139
|
+
|
1140
|
+
VALUE c = rb_class_name(CLASS_OF(self));
|
1141
|
+
lexbor_str_t str = {0};
|
1142
|
+
lxb_status_t status = lxb_html_serialize_str(node, &str);
|
1143
|
+
if (status != LXB_STATUS_OK) {
|
1144
|
+
if (str.data != NULL) {
|
1145
|
+
lexbor_str_destroy(&str, node->owner_document->text, false);
|
1146
|
+
}
|
1147
|
+
return rb_call_super(argc, argv);
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
if (str.data != NULL) {
|
1151
|
+
VALUE ret = rb_sprintf("#<%" PRIsVALUE " %s>", c, str.data);
|
1152
|
+
lexbor_str_destroy(&str, node->owner_document->text, false);
|
1153
|
+
return ret;
|
1154
|
+
}
|
1155
|
+
return rb_call_super(argc, argv);
|
1156
|
+
}
|
1157
|
+
|
1109
1158
|
void Init_nl_node(void)
|
1110
1159
|
{
|
1111
1160
|
cNokolexborNode = rb_define_class_under(mNokolexbor, "Node", rb_cObject);
|
@@ -1137,6 +1186,7 @@ void Init_nl_node(void)
|
|
1137
1186
|
rb_define_method(cNokolexborNode, "next_element", nl_node_next_element, 0);
|
1138
1187
|
rb_define_method(cNokolexborNode, "children", nl_node_children, 0);
|
1139
1188
|
rb_define_method(cNokolexborNode, "child", nl_node_child, 0);
|
1189
|
+
rb_define_method(cNokolexborNode, "element_children", nl_node_element_children, 0);
|
1140
1190
|
rb_define_method(cNokolexborNode, "remove", nl_node_remove, 0);
|
1141
1191
|
rb_define_method(cNokolexborNode, "destroy", nl_node_destroy, 0);
|
1142
1192
|
rb_define_method(cNokolexborNode, "attrs", nl_node_attrs, 0);
|
@@ -1148,6 +1198,7 @@ void Init_nl_node(void)
|
|
1148
1198
|
rb_define_method(cNokolexborNode, "first_element_child", nl_node_first_element_child, 0);
|
1149
1199
|
rb_define_method(cNokolexborNode, "last_element_child", nl_node_last_element_child, 0);
|
1150
1200
|
rb_define_method(cNokolexborNode, "clone", nl_node_clone, 0);
|
1201
|
+
rb_define_method(cNokolexborNode, "inspect", nl_node_inspect, -1);
|
1151
1202
|
|
1152
1203
|
rb_define_alias(cNokolexborNode, "attr", "[]");
|
1153
1204
|
rb_define_alias(cNokolexborNode, "get_attribute", "[]");
|
@@ -1155,6 +1206,7 @@ void Init_nl_node(void)
|
|
1155
1206
|
rb_define_alias(cNokolexborNode, "set_attribute", "[]=");
|
1156
1207
|
rb_define_alias(cNokolexborNode, "has_attribute?", "key?");
|
1157
1208
|
rb_define_alias(cNokolexborNode, "delete", "remove_attr");
|
1209
|
+
rb_define_alias(cNokolexborNode, "elements", "element_children");
|
1158
1210
|
rb_define_alias(cNokolexborNode, "remove_attribute", "remove_attr");
|
1159
1211
|
rb_define_alias(cNokolexborNode, "text", "content");
|
1160
1212
|
rb_define_alias(cNokolexborNode, "inner_text", "content");
|
@@ -300,6 +300,64 @@ nl_node_set_union(VALUE self, VALUE other)
|
|
300
300
|
return nl_rb_node_set_create_with_data(new_array, nl_rb_document_get(self));
|
301
301
|
}
|
302
302
|
|
303
|
+
/**
|
304
|
+
* @return [NodeSet] A new NodeSet with the common nodes only.
|
305
|
+
*/
|
306
|
+
static VALUE
|
307
|
+
nl_node_set_intersection(VALUE self, VALUE other)
|
308
|
+
{
|
309
|
+
if (!rb_obj_is_kind_of(other, cNokolexborNodeSet)) {
|
310
|
+
rb_raise(rb_eArgError, "Parameter must be a Nokolexbor::NodeSet");
|
311
|
+
}
|
312
|
+
|
313
|
+
lexbor_array_t *self_array = nl_rb_node_set_unwrap(self);
|
314
|
+
lexbor_array_t *other_array = nl_rb_node_set_unwrap(other);
|
315
|
+
|
316
|
+
lexbor_array_t *new_array = lexbor_array_create();
|
317
|
+
|
318
|
+
for (size_t i = 0; i < self_array->length; i++) {
|
319
|
+
for (size_t j = 0; j < other_array->length; j++) {
|
320
|
+
if (self_array->list[i] == other_array->list[j]) {
|
321
|
+
lexbor_array_push(new_array, self_array->list[i]);
|
322
|
+
break;
|
323
|
+
}
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
327
|
+
return nl_rb_node_set_create_with_data(new_array, nl_rb_document_get(self));
|
328
|
+
}
|
329
|
+
|
330
|
+
/**
|
331
|
+
* @return [NodeSet] A new NodeSet with the nodes in this NodeSet that aren't in +other+
|
332
|
+
*/
|
333
|
+
static VALUE
|
334
|
+
nl_node_set_difference(VALUE self, VALUE other)
|
335
|
+
{
|
336
|
+
if (!rb_obj_is_kind_of(other, cNokolexborNodeSet)) {
|
337
|
+
rb_raise(rb_eArgError, "Parameter must be a Nokolexbor::NodeSet");
|
338
|
+
}
|
339
|
+
|
340
|
+
lexbor_array_t *self_array = nl_rb_node_set_unwrap(self);
|
341
|
+
lexbor_array_t *other_array = nl_rb_node_set_unwrap(other);
|
342
|
+
|
343
|
+
lexbor_array_t *new_array = lexbor_array_create();
|
344
|
+
|
345
|
+
for (size_t i = 0; i < self_array->length; i++) {
|
346
|
+
bool found = false;
|
347
|
+
for (size_t j = 0; j < other_array->length; j++) {
|
348
|
+
if (self_array->list[i] == other_array->list[j]) {
|
349
|
+
found = true;
|
350
|
+
break;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
if (!found) {
|
354
|
+
lexbor_array_push(new_array, self_array->list[i]);
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
return nl_rb_node_set_create_with_data(new_array, nl_rb_document_get(self));
|
359
|
+
}
|
360
|
+
|
303
361
|
static lxb_status_t
|
304
362
|
nl_node_set_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx)
|
305
363
|
{
|
@@ -410,6 +468,8 @@ void Init_nl_node_set(void)
|
|
410
468
|
rb_define_method(cNokolexborNodeSet, "[]", nl_node_set_slice, -1);
|
411
469
|
rb_define_method(cNokolexborNodeSet, "push", nl_node_set_push, 1);
|
412
470
|
rb_define_method(cNokolexborNodeSet, "|", nl_node_set_union, 1);
|
471
|
+
rb_define_method(cNokolexborNodeSet, "&", nl_node_set_intersection, 1);
|
472
|
+
rb_define_method(cNokolexborNodeSet, "-", nl_node_set_difference, 1);
|
413
473
|
rb_define_method(cNokolexborNodeSet, "to_a", nl_node_set_to_array, 0);
|
414
474
|
rb_define_method(cNokolexborNodeSet, "delete", nl_node_set_delete, 1);
|
415
475
|
rb_define_method(cNokolexborNodeSet, "include?", nl_node_set_is_include, 1);
|
data/lib/nokolexbor/node_set.rb
CHANGED
@@ -54,6 +54,16 @@ module Nokolexbor
|
|
54
54
|
length == 0
|
55
55
|
end
|
56
56
|
|
57
|
+
# Insert +node+ before the first Node in this NodeSet
|
58
|
+
def before(node)
|
59
|
+
first.before(node)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Insert +node+ after the last Node in this NodeSet
|
63
|
+
def after(node)
|
64
|
+
last.after(node)
|
65
|
+
end
|
66
|
+
|
57
67
|
# @return [Integer] The index of the first node in this NodeSet that is equal to +node+ or meets the given block. Returns nil if no match is found.
|
58
68
|
def index(node = nil)
|
59
69
|
if node
|
@@ -169,6 +179,75 @@ module Nokolexbor
|
|
169
179
|
self
|
170
180
|
end
|
171
181
|
|
182
|
+
# Add the class attribute +name+ to all containing nodes.
|
183
|
+
#
|
184
|
+
# @see Node#add_class
|
185
|
+
def add_class(name)
|
186
|
+
each do |el|
|
187
|
+
el.add_class(name)
|
188
|
+
end
|
189
|
+
self
|
190
|
+
end
|
191
|
+
|
192
|
+
# Append the class attribute +name+ to all containing nodes.
|
193
|
+
#
|
194
|
+
# @see Node#append_class
|
195
|
+
def append_class(name)
|
196
|
+
each do |el|
|
197
|
+
el.append_class(name)
|
198
|
+
end
|
199
|
+
self
|
200
|
+
end
|
201
|
+
|
202
|
+
# Remove the class attribute +name+ from all containing nodes.
|
203
|
+
#
|
204
|
+
# @see Node#remove_class
|
205
|
+
def remove_class(name = nil)
|
206
|
+
each do |el|
|
207
|
+
el.remove_class(name)
|
208
|
+
end
|
209
|
+
self
|
210
|
+
end
|
211
|
+
|
212
|
+
# Remove the attributed named +name+ from all containing nodes.
|
213
|
+
#
|
214
|
+
# @see Node#remove_attr
|
215
|
+
def remove_attr(name)
|
216
|
+
each { |el| el.delete(name) }
|
217
|
+
self
|
218
|
+
end
|
219
|
+
alias_method :remove_attribute, :remove_attr
|
220
|
+
|
221
|
+
# Set attributes on each Node in the NodeSet, or get an
|
222
|
+
# attribute from the first Node in the NodeSet.
|
223
|
+
#
|
224
|
+
# @example Get an attribute from the first Node in a NodeSet.
|
225
|
+
# node_set.attr("href")
|
226
|
+
#
|
227
|
+
# @example Set attributes on each node.
|
228
|
+
# node_set.attr("href" => "http://example.com", "class" => "a")
|
229
|
+
# node_set.attr("href", "http://example.com")
|
230
|
+
# node_set.attr("href") { |node| "http://example.com" }
|
231
|
+
#
|
232
|
+
# @return [NodeSet] +self+, to support chaining of calls.
|
233
|
+
def attr(key, value = nil, &block)
|
234
|
+
unless key.is_a?(Hash) || (key && (value || block))
|
235
|
+
return first&.attribute(key)
|
236
|
+
end
|
237
|
+
|
238
|
+
hash = key.is_a?(Hash) ? key : { key => value }
|
239
|
+
|
240
|
+
hash.each do |k, v|
|
241
|
+
each do |node|
|
242
|
+
node[k] = v || yield(node)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
self
|
247
|
+
end
|
248
|
+
alias_method :set, :attr
|
249
|
+
alias_method :attribute, :attr
|
250
|
+
|
172
251
|
# (see Node#xpath)
|
173
252
|
def xpath(*args)
|
174
253
|
paths, handler, ns, binds = extract_params(args)
|
@@ -196,6 +275,10 @@ module Nokolexbor
|
|
196
275
|
end
|
197
276
|
end
|
198
277
|
|
278
|
+
def inspect
|
279
|
+
"[#{map(&:inspect).join(', ')}]"
|
280
|
+
end
|
281
|
+
|
199
282
|
private
|
200
283
|
|
201
284
|
IMPLIED_XPATH_CONTEXTS = [".//", "self::"].freeze # :nodoc:
|
data/lib/nokolexbor/version.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
diff --git a/source/lexbor/dom/interfaces/document.c b/source/lexbor/dom/interfaces/document.c
|
2
|
+
index a2153f4..8a9c69f 100755
|
3
|
+
--- a/source/lexbor/dom/interfaces/document.c
|
4
|
+
+++ b/source/lexbor/dom/interfaces/document.c
|
5
|
+
@@ -12,6 +12,7 @@
|
6
|
+
#include "lexbor/dom/interfaces/cdata_section.h"
|
7
|
+
#include "lexbor/dom/interfaces/cdata_section.h"
|
8
|
+
#include "lexbor/dom/interfaces/processing_instruction.h"
|
9
|
+
+#include "lexbor/html/interfaces/template_element.h"
|
10
|
+
|
11
|
+
|
12
|
+
lxb_dom_document_t *
|
13
|
+
@@ -449,6 +450,11 @@ lxb_dom_document_import_node(lxb_dom_document_t *doc, lxb_dom_node_t *node,
|
14
|
+
return NULL;
|
15
|
+
}
|
16
|
+
|
17
|
+
+ if (curr->local_name == LXB_TAG_TEMPLATE && curr->first_child != NULL && cnode->type == LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT) {
|
18
|
+
+ lxb_dom_node_remove(curr->first_child);
|
19
|
+
+ lxb_html_interface_template(curr)->content = cnode;
|
20
|
+
+ }
|
21
|
+
+
|
22
|
+
lxb_dom_node_insert_child(curr, cnode);
|
23
|
+
|
24
|
+
if (node->first_child != NULL) {
|
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.
|
4
|
+
version: 0.4.0
|
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-
|
11
|
+
date: 2023-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- patches/0001-lexbor-support-text-pseudo-element.patch
|
131
131
|
- patches/0002-lexbor-match-id-class-case-sensitive.patch
|
132
132
|
- patches/0003-lexbor-attach-template-content-to-self.patch
|
133
|
+
- patches/0004-lexbor-fix-template-clone.patch
|
133
134
|
- vendor/lexbor/CMakeLists.txt
|
134
135
|
- vendor/lexbor/config.cmake
|
135
136
|
- vendor/lexbor/feature.cmake
|