nokolexbor 0.2.3 → 0.2.5

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: b5eb708d3b21135112c1e1f373b89f94b83c4926043da9743aff108f4d4eed72
4
- data.tar.gz: 5ba497f52ea19c49816e1ec9c2b5e12449ae4f812cb011f2953ba7cf1a0b971b
3
+ metadata.gz: d4f935c5e81aed7b5d964e7332a9abeaa1f44dec7e2532f01c89dfd17df14ded
4
+ data.tar.gz: 91c58aca5a9b16a3cfa7e2436dfb86feeb777daa3615b8b3a95b234981cc67d0
5
5
  SHA512:
6
- metadata.gz: ff508a1599f36608c4c7ae0b360d4f2eb6f4740c059a945215dcdbc27a457a74293a2de6ba4043b5db5601dacccd4befac396b85a824e615163ab36f2a603bcb
7
- data.tar.gz: 1699d675b60d76a12da000e6bc0844842a31f910b80350a5e87bedaf4474e8078099623eeaeb1e1169c16ec23a51a4d0112aebf76c9ef25ac358a347992f32da
6
+ metadata.gz: af6ae7b07bde270ea275a5b21221c7e90923f195a6a62ed7b85174f1d9f31f017661dc50c7d8dd1c3d39096a5c1ecbb3469f4496f2e628a3b7026f82ca3994c5
7
+ data.tar.gz: eea3a38dcbd81cdb7c54996248d6eaa2d2c51b964d79d3131ba04594dd449a141b32b225bc7a879844c92418f3c04e6b63c77c9c6bef86f8ee619fa6a47b03a3
@@ -1,16 +1,22 @@
1
1
  require 'mkmf'
2
2
  require 'timeout'
3
3
 
4
- # For debugging
5
- # CONFIG["optflags"] = "-O0"
6
- # CONFIG["debugflags"] = "-ggdb3"
7
-
8
4
  cmake_flags = [ ENV["CMAKE_FLAGS"] ]
9
5
  cmake_flags << "-DLEXBOR_BUILD_TESTS_CPP=OFF"
10
6
  cmake_flags << "-DLEXBOR_BUILD_SHARED=OFF"
11
7
  cmake_flags << "-DLEXBOR_BUILD_STATIC=ON"
12
- # For debugging
13
- # cmake_flags << "-DLEXBOR_OPTIMIZATION_LEVEL='-O0 -g'"
8
+
9
+ if ENV['NOKOLEXBOR_DEBUG'] || ENV['NOKOLEXBOR_ASAN']
10
+ CONFIG["optflags"] = "-O0"
11
+ CONFIG["debugflags"] = "-ggdb3"
12
+ cmake_flags << "-DLEXBOR_OPTIMIZATION_LEVEL='-O0 -g'"
13
+ end
14
+
15
+ if ENV['NOKOLEXBOR_ASAN']
16
+ $LDFLAGS << " -fsanitize=address"
17
+ $CFLAGS << " -fsanitize=address -DNOKOLEXBOR_ASAN"
18
+ cmake_flags << "-DLEXBOR_BUILD_WITH_ASAN=ON"
19
+ end
14
20
 
15
21
  append_cflags("-DLEXBOR_STATIC")
16
22
  append_cflags("-DLIBXML_STATIC")
@@ -13,6 +13,11 @@
13
13
  #include <ruby.h>
14
14
  #include "lexbor/core/base.h"
15
15
 
16
+ // Disable using ruby memory functions when ASAN is enabled,
17
+ // otherwise memory leak info will be all about ruby which
18
+ // is useless.
19
+ #ifndef NOKOLEXBOR_ASAN
20
+
16
21
  void *
17
22
  lexbor_malloc(size_t size)
18
23
  {
@@ -37,3 +42,5 @@ lexbor_free(void *dst)
37
42
  ruby_xfree(dst);
38
43
  return NULL;
39
44
  }
45
+
46
+ #endif
@@ -5,7 +5,7 @@ extern VALUE cNokolexborNode;
5
5
  VALUE cNokolexborDocument;
6
6
 
7
7
  static void
8
- free_nl_document(lxb_dom_document_t *document)
8
+ free_nl_document(lxb_html_document_t *document)
9
9
  {
10
10
  lxb_html_document_destroy(document);
11
11
  }
@@ -22,10 +22,20 @@ const rb_data_type_t nl_document_type = {
22
22
  };
23
23
 
24
24
  static VALUE
25
- nl_document_parse(VALUE self, VALUE rb_html)
25
+ nl_document_parse(VALUE self, VALUE rb_string_or_io)
26
26
  {
27
+ VALUE id_read = rb_intern("read");
28
+ VALUE rb_html;
29
+ if (rb_respond_to(rb_string_or_io, id_read))
30
+ {
31
+ rb_html = rb_funcall(rb_string_or_io, id_read, 0);
32
+ }
33
+ else
34
+ {
35
+ rb_html = rb_string_or_io;
36
+ }
27
37
  const char *html_c = StringValuePtr(rb_html);
28
- int html_len = RSTRING_LEN(rb_html);
38
+ size_t html_len = RSTRING_LEN(rb_html);
29
39
 
30
40
  lxb_html_document_t *document;
31
41
 
@@ -35,13 +45,13 @@ nl_document_parse(VALUE self, VALUE rb_html)
35
45
  rb_raise(rb_eRuntimeError, "Error creating document");
36
46
  }
37
47
 
38
- lxb_status_t status = lxb_html_document_parse(document, html_c, html_len);
48
+ lxb_status_t status = lxb_html_document_parse(document, (const lxb_char_t *)html_c, html_len);
39
49
  if (status != LXB_STATUS_OK)
40
50
  {
41
51
  nl_raise_lexbor_error(status);
42
52
  }
43
53
 
44
- return TypedData_Wrap_Struct(cNokolexborDocument, &nl_document_type, &document->dom_document);
54
+ return TypedData_Wrap_Struct(cNokolexborDocument, &nl_document_type, document);
45
55
  }
46
56
 
47
57
  static VALUE
@@ -50,6 +60,14 @@ nl_document_new(VALUE self)
50
60
  return nl_document_parse(self, rb_str_new("", 0));
51
61
  }
52
62
 
63
+ lxb_dom_document_t *
64
+ nl_rb_document_unwrap(VALUE rb_doc)
65
+ {
66
+ lxb_dom_document_t *doc;
67
+ TypedData_Get_Struct(rb_doc, lxb_dom_document_t, &nl_document_type, doc);
68
+ return doc;
69
+ }
70
+
53
71
  void Init_nl_document(void)
54
72
  {
55
73
  cNokolexborDocument = rb_define_class_under(mNokolexbor, "Document", cNokolexborNode);
@@ -43,7 +43,7 @@ nl_rb_node_unwrap(VALUE rb_node)
43
43
  lxb_dom_node_t *node;
44
44
  if (rb_obj_class(rb_node) == cNokolexborDocument)
45
45
  {
46
- TypedData_Get_Struct(rb_node, lxb_dom_document_t, &nl_document_type, node);
46
+ TypedData_Get_Struct(rb_node, lxb_dom_node_t, &nl_document_type, node);
47
47
  }
48
48
  else
49
49
  {
@@ -56,7 +56,6 @@ static VALUE
56
56
  nl_node_new(int argc, VALUE *argv, VALUE klass)
57
57
  {
58
58
  lxb_dom_document_t *document;
59
- lxb_dom_node_t *node;
60
59
  VALUE rb_name;
61
60
  VALUE rb_document;
62
61
  VALUE rest;
@@ -68,9 +67,9 @@ nl_node_new(int argc, VALUE *argv, VALUE klass)
68
67
  rb_raise(rb_eArgError, "Document must be a Nokolexbor::Document");
69
68
  }
70
69
 
71
- TypedData_Get_Struct(rb_document, lxb_dom_document_t, &nl_document_type, document);
70
+ document = nl_rb_document_unwrap(rb_document);
72
71
 
73
- lxb_dom_element_t *element = lxb_dom_document_create_element(document, StringValueCStr(rb_name), RSTRING_LEN(rb_name), NULL);
72
+ lxb_dom_element_t *element = lxb_dom_document_create_element(document, (const lxb_char_t *)StringValueCStr(rb_name), RSTRING_LEN(rb_name), NULL);
74
73
  if (element == NULL)
75
74
  {
76
75
  rb_raise(rb_eRuntimeError, "Error creating element");
@@ -97,7 +96,7 @@ nl_node_content(VALUE self)
97
96
  {
98
97
  return rb_str_new("", 0);
99
98
  }
100
- VALUE rb_str = rb_utf8_str_new(text, str_len);
99
+ VALUE rb_str = rb_utf8_str_new((char *)text, str_len);
101
100
  lxb_dom_document_destroy_text(node->owner_document, text);
102
101
 
103
102
  return rb_str;
@@ -115,19 +114,19 @@ nl_node_get_attr(VALUE self, VALUE rb_attr)
115
114
 
116
115
  VALUE rb_attr_s = rb_String(rb_attr);
117
116
  const char *attr_c = RSTRING_PTR(rb_attr_s);
118
- int attr_len = RSTRING_LEN(rb_attr_s);
117
+ size_t attr_len = RSTRING_LEN(rb_attr_s);
119
118
 
120
- lxb_dom_element_t *element = lxb_html_interface_element(node);
119
+ lxb_dom_element_t *element = lxb_dom_interface_element(node);
121
120
 
122
- if (!lxb_dom_element_has_attribute(element, attr_c, attr_len))
121
+ if (!lxb_dom_element_has_attribute(element, (const lxb_char_t *)attr_c, attr_len))
123
122
  {
124
123
  return Qnil;
125
124
  }
126
125
 
127
126
  size_t attr_value_len;
128
- char *attr_value = lxb_dom_element_get_attribute(element, attr_c, attr_len, &attr_value_len);
127
+ const lxb_char_t *attr_value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)attr_c, attr_len, &attr_value_len);
129
128
 
130
- return rb_utf8_str_new(attr_value, attr_value_len);
129
+ return rb_utf8_str_new((const char *)attr_value, attr_value_len);
131
130
  }
132
131
 
133
132
  static VALUE
@@ -144,13 +143,13 @@ nl_node_set_attr(VALUE self, VALUE rb_attr, VALUE rb_value)
144
143
  VALUE rb_value_s = rb_String(rb_value);
145
144
 
146
145
  const char *attr_c = RSTRING_PTR(rb_attr_s);
147
- int attr_len = RSTRING_LEN(rb_attr_s);
146
+ size_t attr_len = RSTRING_LEN(rb_attr_s);
148
147
  const char *value_c = RSTRING_PTR(rb_value_s);
149
- int value_len = RSTRING_LEN(rb_value_s);
148
+ size_t value_len = RSTRING_LEN(rb_value_s);
150
149
 
151
- lxb_dom_element_t *element = lxb_html_interface_element(node);
150
+ lxb_dom_element_t *element = lxb_dom_interface_element(node);
152
151
 
153
- lxb_dom_element_set_attribute(element, attr_c, attr_len, value_c, value_len);
152
+ lxb_dom_element_set_attribute(element, (const lxb_char_t *)attr_c, attr_len, (const lxb_char_t *)value_c, value_len);
154
153
 
155
154
  return rb_value;
156
155
  }
@@ -168,14 +167,14 @@ nl_node_remove_attr(VALUE self, VALUE rb_attr)
168
167
  VALUE rb_attr_s = rb_String(rb_attr);
169
168
 
170
169
  const char *attr_c = RSTRING_PTR(rb_attr_s);
171
- int attr_len = RSTRING_LEN(rb_attr_s);
170
+ size_t attr_len = RSTRING_LEN(rb_attr_s);
172
171
 
173
- lxb_dom_element_t *element = lxb_html_interface_element(node);
172
+ lxb_dom_element_t *element = lxb_dom_interface_element(node);
174
173
 
175
- return lxb_dom_element_remove_attribute(element, attr_c, attr_len) == LXB_STATUS_OK ? Qtrue : Qfalse;
174
+ return lxb_dom_element_remove_attribute(element, (const lxb_char_t *)attr_c, attr_len) == LXB_STATUS_OK ? Qtrue : Qfalse;
176
175
  }
177
176
 
178
- static lxb_status_t
177
+ lxb_status_t
179
178
  nl_node_at_css_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t *spec, void *ctx)
180
179
  {
181
180
  lexbor_array_t *array = (lexbor_array_t *)ctx;
@@ -188,7 +187,7 @@ nl_node_at_css_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t *sp
188
187
  return LXB_STATUS_STOP;
189
188
  }
190
189
 
191
- static lxb_status_t
190
+ lxb_status_t
192
191
  nl_node_css_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t *spec, void *ctx)
193
192
  {
194
193
  lexbor_array_t *array = (lexbor_array_t *)ctx;
@@ -200,45 +199,52 @@ nl_node_css_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t *spec,
200
199
  return LXB_STATUS_OK;
201
200
  }
202
201
 
203
- static void
202
+ lxb_status_t
204
203
  nl_node_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx)
205
204
  {
206
205
  const char *selector_c = StringValuePtr(selector);
207
- int selector_len = RSTRING_LEN(selector);
206
+ size_t selector_len = RSTRING_LEN(selector);
208
207
 
209
208
  lxb_dom_node_t *node = nl_rb_node_unwrap(self);
210
209
 
210
+ lxb_status_t status;
211
+ lxb_css_parser_t *parser = NULL;
212
+ lxb_selectors_t *selectors = NULL;
213
+ lxb_css_selector_list_t *list = NULL;
214
+
211
215
  /* Create CSS parser. */
212
- lxb_css_parser_t *parser = lxb_css_parser_create();
213
- lxb_status_t status = lxb_css_parser_init(parser, NULL, NULL);
216
+ parser = lxb_css_parser_create();
217
+ status = lxb_css_parser_init(parser, NULL, NULL);
214
218
  if (status != LXB_STATUS_OK)
215
219
  {
216
- nl_raise_lexbor_error(status);
220
+ goto cleanup;
217
221
  }
218
222
 
219
223
  /* Selectors. */
220
- lxb_selectors_t *selectors = lxb_selectors_create();
224
+ selectors = lxb_selectors_create();
221
225
  status = lxb_selectors_init(selectors);
222
226
  if (status != LXB_STATUS_OK)
223
227
  {
224
- nl_raise_lexbor_error(status);
228
+ goto cleanup;
225
229
  }
226
230
 
227
231
  /* Parse and get the log. */
228
232
  // TODO: Cache the list for reuse, improves performance
229
- lxb_css_selector_list_t *list = lxb_css_selectors_parse_relative_list(parser, selector_c, selector_len);
233
+ list = lxb_css_selectors_parse_relative_list(parser, (const lxb_char_t *)selector_c, selector_len);
230
234
  if (parser->status != LXB_STATUS_OK)
231
235
  {
232
- nl_raise_lexbor_error(parser->status);
236
+ status = parser->status;
237
+ goto cleanup;
233
238
  }
234
239
 
235
240
  /* Find HTML nodes by CSS Selectors. */
236
241
  status = lxb_selectors_find(selectors, node, list, cb, ctx);
237
242
  if (status != LXB_STATUS_OK)
238
243
  {
239
- nl_raise_lexbor_error(status);
244
+ goto cleanup;
240
245
  }
241
246
 
247
+ cleanup:
242
248
  /* Destroy Selectors object. */
243
249
  (void)lxb_selectors_destroy(selectors, true);
244
250
 
@@ -247,20 +253,22 @@ nl_node_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx)
247
253
 
248
254
  /* Destroy all object for all CSS Selector List. */
249
255
  lxb_css_selector_list_destroy_memory(list);
256
+
257
+ return status;
250
258
  }
251
259
 
252
260
  static void
253
261
  mark_node_orders(lxb_dom_node_t *root)
254
262
  {
255
- int count = 1;
256
- root->user = count;
263
+ size_t count = 1;
264
+ root->user = (void *)count;
257
265
  lxb_dom_node_t *node = root;
258
266
  do
259
267
  {
260
268
  if (node->first_child != NULL)
261
269
  {
262
270
  node = node->first_child;
263
- node->user = ++count;
271
+ node->user = (void *)++count;
264
272
  }
265
273
  else
266
274
  {
@@ -275,7 +283,7 @@ mark_node_orders(lxb_dom_node_t *root)
275
283
  }
276
284
 
277
285
  node = node->next;
278
- node->user = ++count;
286
+ node->user = (void *)++count;
279
287
  }
280
288
 
281
289
  } while (true);
@@ -290,7 +298,7 @@ void sort_nodes_if_necessary(VALUE selector, lxb_dom_document_t *doc, lexbor_arr
290
298
  int need_order = 0;
291
299
  // Check if we have already markded orders, note that
292
300
  // we need to order again if new nodes are added to the document
293
- for (int i = 0; i < array->length; i++)
301
+ for (size_t i = 0; i < array->length; i++)
294
302
  {
295
303
  if (((lxb_dom_node_t *)array->list[i])->user == 0)
296
304
  {
@@ -300,37 +308,53 @@ void sort_nodes_if_necessary(VALUE selector, lxb_dom_document_t *doc, lexbor_arr
300
308
  }
301
309
  if (need_order)
302
310
  {
303
- mark_node_orders(doc);
311
+ mark_node_orders(&doc->node);
304
312
  }
305
- css_result_tim_sort(&array->list[0], array->length);
313
+ css_result_tim_sort((lxb_dom_node_t **)&array->list[0], array->length);
306
314
  }
307
315
  }
308
316
 
309
- VALUE
317
+ static VALUE
310
318
  nl_node_at_css(VALUE self, VALUE selector)
311
319
  {
312
320
  lxb_dom_node_t *node = nl_rb_node_unwrap(self);
313
321
  lexbor_array_t *array = lexbor_array_create();
314
322
 
315
- nl_node_find(self, selector, nl_node_at_css_callback, array);
323
+ lxb_status_t status = nl_node_find(self, selector, nl_node_at_css_callback, array);
324
+
325
+ if (status != LXB_STATUS_OK)
326
+ {
327
+ lexbor_array_destroy(array, true);
328
+ nl_raise_lexbor_error(status);
329
+ }
316
330
 
317
331
  if (array->length == 0)
318
332
  {
333
+ lexbor_array_destroy(array, true);
319
334
  return Qnil;
320
335
  }
321
336
 
322
337
  sort_nodes_if_necessary(selector, node->owner_document, array);
323
338
 
324
- return nl_rb_node_create(array->list[0], nl_rb_document_get(self));
339
+ VALUE ret = nl_rb_node_create(array->list[0], nl_rb_document_get(self));
340
+
341
+ lexbor_array_destroy(array, true);
342
+
343
+ return ret;
325
344
  }
326
345
 
327
- VALUE
346
+ static VALUE
328
347
  nl_node_css(VALUE self, VALUE selector)
329
348
  {
330
349
  lxb_dom_node_t *node = nl_rb_node_unwrap(self);
331
350
  lexbor_array_t *array = lexbor_array_create();
332
351
 
333
- nl_node_find(self, selector, nl_node_css_callback, array);
352
+ lxb_status_t status = nl_node_find(self, selector, nl_node_css_callback, array);
353
+ if (status != LXB_STATUS_OK)
354
+ {
355
+ lexbor_array_destroy(array, true);
356
+ nl_raise_lexbor_error(status);
357
+ }
334
358
 
335
359
  sort_nodes_if_necessary(selector, node->owner_document, array);
336
360
 
@@ -354,7 +378,7 @@ nl_node_inner_html(VALUE self)
354
378
 
355
379
  if (str.data != NULL)
356
380
  {
357
- VALUE ret = rb_utf8_str_new(str.data, str.length);
381
+ VALUE ret = rb_utf8_str_new((const char *)str.data, str.length);
358
382
  lexbor_str_destroy(&str, node->owner_document->text, false);
359
383
  return ret;
360
384
  }
@@ -379,7 +403,7 @@ nl_node_outer_html(VALUE self)
379
403
 
380
404
  if (str.data != NULL)
381
405
  {
382
- VALUE ret = rb_utf8_str_new(str.data, str.length);
406
+ VALUE ret = rb_utf8_str_new((const char *)str.data, str.length);
383
407
  lexbor_str_destroy(&str, node->owner_document->text, false);
384
408
  return ret;
385
409
  }
@@ -399,11 +423,11 @@ nl_node_has_key(VALUE self, VALUE rb_attr)
399
423
 
400
424
  VALUE rb_attr_s = rb_String(rb_attr);
401
425
  const char *attr_c = RSTRING_PTR(rb_attr_s);
402
- int attr_len = RSTRING_LEN(rb_attr_s);
426
+ size_t attr_len = RSTRING_LEN(rb_attr_s);
403
427
 
404
- lxb_dom_element_t *element = lxb_html_interface_element(node);
428
+ lxb_dom_element_t *element = lxb_dom_interface_element(node);
405
429
 
406
- return lxb_dom_element_has_attribute(element, attr_c, attr_len) ? Qtrue : Qfalse;
430
+ return lxb_dom_element_has_attribute(element, (const lxb_char_t *)attr_c, attr_len) ? Qtrue : Qfalse;
407
431
  }
408
432
 
409
433
  static VALUE
@@ -417,13 +441,13 @@ nl_node_keys(VALUE self)
417
441
  return ary_keys;
418
442
  }
419
443
 
420
- lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_html_interface_element(node));
444
+ lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
421
445
 
422
446
  while (attr != NULL)
423
447
  {
424
448
  size_t tmp_len;
425
- lxb_char_t *tmp = lxb_dom_attr_qualified_name(attr, &tmp_len);
426
- rb_ary_push(ary_keys, rb_utf8_str_new(tmp, tmp_len));
449
+ const lxb_char_t *tmp = lxb_dom_attr_qualified_name(attr, &tmp_len);
450
+ rb_ary_push(ary_keys, rb_utf8_str_new((const char *)tmp, tmp_len));
427
451
 
428
452
  attr = lxb_dom_element_next_attribute(attr);
429
453
  }
@@ -442,15 +466,19 @@ nl_node_values(VALUE self)
442
466
  return ary_values;
443
467
  }
444
468
 
445
- lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_html_interface_element(node));
469
+ lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
446
470
 
447
471
  while (attr != NULL)
448
472
  {
449
473
  size_t tmp_len;
450
- lxb_char_t *tmp = lxb_dom_attr_value(attr, &tmp_len);
474
+ const lxb_char_t *tmp = lxb_dom_attr_value(attr, &tmp_len);
451
475
  if (tmp != NULL)
452
476
  {
453
- rb_ary_push(ary_values, rb_utf8_str_new(tmp, tmp_len));
477
+ rb_ary_push(ary_values, rb_utf8_str_new((const char *)tmp, tmp_len));
478
+ }
479
+ else
480
+ {
481
+ rb_ary_push(ary_values, rb_str_new("", 0));
454
482
  }
455
483
 
456
484
  attr = lxb_dom_element_next_attribute(attr);
@@ -470,16 +498,16 @@ nl_node_attrs(VALUE self)
470
498
  return rb_hash;
471
499
  }
472
500
 
473
- lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_html_interface_element(node));
501
+ lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
474
502
 
475
503
  while (attr != NULL)
476
504
  {
477
505
  size_t tmp_len;
478
- lxb_char_t *tmp = lxb_dom_attr_qualified_name(attr, &tmp_len);
479
- VALUE rb_key = rb_utf8_str_new(tmp, tmp_len);
506
+ const lxb_char_t *tmp = lxb_dom_attr_qualified_name(attr, &tmp_len);
507
+ VALUE rb_key = rb_utf8_str_new((const char *)tmp, tmp_len);
480
508
 
481
509
  tmp = lxb_dom_attr_value(attr, &tmp_len);
482
- VALUE rb_value = tmp != NULL ? rb_utf8_str_new(tmp, tmp_len) : Qnil;
510
+ VALUE rb_value = tmp != NULL ? rb_utf8_str_new((const char *)tmp, tmp_len) : rb_str_new("", 0);
483
511
 
484
512
  rb_hash_aset(rb_hash, rb_key, rb_value);
485
513
 
@@ -604,15 +632,16 @@ nl_node_name(VALUE self)
604
632
  {
605
633
  lxb_dom_node_t *node = nl_rb_node_unwrap(self);
606
634
  size_t len;
607
- lxb_char_t *name = lxb_dom_node_name_qualified(node, &len);
608
- return rb_utf8_str_new(name, len);
635
+ const lxb_char_t *name = lxb_dom_node_name_qualified(node, &len);
636
+ return rb_utf8_str_new((const char *)name, len);
609
637
  }
610
638
 
611
639
  static lxb_dom_node_t *
612
- nl_node_parse_fragment(lxb_html_document_t *doc, lxb_char_t *html, size_t size)
640
+ nl_node_parse_fragment(lxb_dom_document_t *doc, lxb_char_t *html, size_t size)
613
641
  {
614
642
  size_t tag_name_len;
615
- lxb_char_t *tag_name = lxb_tag_name_by_id(lxb_html_document_tags(doc), LXB_TAG__UNDEF, &tag_name_len);
643
+ lxb_html_document_t *html_doc = lxb_html_interface_document(doc);
644
+ const lxb_char_t *tag_name = lxb_tag_name_by_id(lxb_html_document_tags(html_doc), LXB_TAG__UNDEF, &tag_name_len);
616
645
  if (tag_name == NULL)
617
646
  {
618
647
  rb_raise(rb_eRuntimeError, "Error getting tag name");
@@ -622,7 +651,7 @@ nl_node_parse_fragment(lxb_html_document_t *doc, lxb_char_t *html, size_t size)
622
651
  {
623
652
  rb_raise(rb_eRuntimeError, "Error creating element");
624
653
  }
625
- lxb_dom_node_t *frag_root = lxb_html_document_parse_fragment(doc, element, html, size);
654
+ lxb_dom_node_t *frag_root = lxb_html_document_parse_fragment(html_doc, element, html, size);
626
655
  if (frag_root == NULL)
627
656
  {
628
657
  rb_raise(rb_eArgError, "Error parsing HTML");
@@ -637,7 +666,7 @@ nl_node_fragment(VALUE self, VALUE html)
637
666
  lxb_dom_node_t *node = nl_rb_node_unwrap(self);
638
667
  lxb_dom_document_t *doc = node->owner_document;
639
668
 
640
- lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, RSTRING_PTR(html), RSTRING_LEN(html));
669
+ lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, (lxb_char_t *)RSTRING_PTR(html), RSTRING_LEN(html));
641
670
  return nl_rb_node_create(frag_root, nl_rb_document_get(self));
642
671
  }
643
672
 
@@ -663,7 +692,7 @@ nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
663
692
 
664
693
  if (TYPE(new) == T_STRING)
665
694
  {
666
- lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, RSTRING_PTR(new), RSTRING_LEN(new));
695
+ lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
667
696
 
668
697
  while (frag_root->first_child != NULL)
669
698
  {
@@ -694,7 +723,7 @@ nl_node_add_child(VALUE self, VALUE new)
694
723
 
695
724
  if (TYPE(new) == T_STRING)
696
725
  {
697
- lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, RSTRING_PTR(new), RSTRING_LEN(new));
726
+ lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, (lxb_char_t *)RSTRING_PTR(new), RSTRING_LEN(new));
698
727
 
699
728
  while (frag_root->first_child != NULL)
700
729
  {
@@ -832,11 +861,13 @@ void Init_nl_node(void)
832
861
 
833
862
  rb_define_alias(cNokolexborNode, "attr", "[]");
834
863
  rb_define_alias(cNokolexborNode, "set_attr", "[]=");
864
+ rb_define_alias(cNokolexborNode, "delete", "remove_attr");
835
865
  rb_define_alias(cNokolexborNode, "text", "content");
836
866
  rb_define_alias(cNokolexborNode, "inner_text", "content");
837
867
  rb_define_alias(cNokolexborNode, "to_str", "content");
838
868
  rb_define_alias(cNokolexborNode, "to_html", "outer_html");
839
869
  rb_define_alias(cNokolexborNode, "to_s", "outer_html");
870
+ rb_define_alias(cNokolexborNode, "unlink", "remove");
840
871
  rb_define_alias(cNokolexborNode, "type", "node_type");
841
872
  rb_define_alias(cNokolexborNode, "dup", "clone");
842
873
  }