@salve-software/react-native-nitro-jsdom 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/LICENSE +21 -0
  2. package/NitroJsdom.podspec +63 -0
  3. package/README.md +95 -0
  4. package/android/CMakeLists.txt +86 -0
  5. package/android/build.gradle +148 -0
  6. package/android/fix-prefab.gradle +51 -0
  7. package/android/gradle.properties +5 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +9 -0
  10. package/android/src/main/java/com/nitrojsdom/NitroJsdomPackage.kt +20 -0
  11. package/cpp/HybridHtmlSandbox.cpp +171 -0
  12. package/cpp/HybridHtmlSandbox.hpp +47 -0
  13. package/cpp/lexbor/LexborDocument.cpp +365 -0
  14. package/cpp/lexbor/LexborDocument.hpp +71 -0
  15. package/cpp/quickjs/DOMBindings.cpp +57 -0
  16. package/cpp/quickjs/DOMBindings.hpp +21 -0
  17. package/cpp/quickjs/DOMBindingsInternal.cpp +157 -0
  18. package/cpp/quickjs/DOMBindingsInternal.hpp +83 -0
  19. package/cpp/quickjs/MutationObservers.cpp +546 -0
  20. package/cpp/quickjs/MutationObservers.hpp +127 -0
  21. package/cpp/quickjs/QuickJSRuntime.cpp +475 -0
  22. package/cpp/quickjs/QuickJSRuntime.hpp +110 -0
  23. package/cpp/quickjs/Storage.cpp +130 -0
  24. package/cpp/quickjs/Storage.hpp +40 -0
  25. package/cpp/quickjs/bindings/ClassListBindings.cpp +241 -0
  26. package/cpp/quickjs/bindings/ClassListBindings.hpp +29 -0
  27. package/cpp/quickjs/bindings/DatasetBindings.cpp +120 -0
  28. package/cpp/quickjs/bindings/DatasetBindings.hpp +20 -0
  29. package/cpp/quickjs/bindings/DocumentBindings.cpp +155 -0
  30. package/cpp/quickjs/bindings/DocumentBindings.hpp +19 -0
  31. package/cpp/quickjs/bindings/ElementBindings.cpp +1106 -0
  32. package/cpp/quickjs/bindings/ElementBindings.hpp +19 -0
  33. package/cpp/quickjs/bindings/EventBindings.cpp +352 -0
  34. package/cpp/quickjs/bindings/EventBindings.hpp +21 -0
  35. package/cpp/quickjs/bindings/FetchBindings.cpp +347 -0
  36. package/cpp/quickjs/bindings/FetchBindings.hpp +16 -0
  37. package/cpp/quickjs/bindings/StyleBindings.cpp +245 -0
  38. package/cpp/quickjs/bindings/StyleBindings.hpp +22 -0
  39. package/cpp/quickjs/bindings/TimerBindings.cpp +94 -0
  40. package/cpp/quickjs/bindings/TimerBindings.hpp +16 -0
  41. package/cpp/quickjs/bindings/WindowBindings.cpp +211 -0
  42. package/cpp/quickjs/bindings/WindowBindings.hpp +16 -0
  43. package/ios/Bridge.h +8 -0
  44. package/lib/commonjs/classes/JSDOM/JSDOM.class.js +138 -0
  45. package/lib/commonjs/classes/JSDOM/JSDOM.class.js.map +1 -0
  46. package/lib/commonjs/classes/JSDOM/index.js +17 -0
  47. package/lib/commonjs/classes/JSDOM/index.js.map +1 -0
  48. package/lib/commonjs/classes/JSDOM/types/IFetchOptions.js +2 -0
  49. package/lib/commonjs/classes/JSDOM/types/IFetchOptions.js.map +1 -0
  50. package/lib/commonjs/classes/JSDOM/types/IJSDOMOptions.js +6 -0
  51. package/lib/commonjs/classes/JSDOM/types/IJSDOMOptions.js.map +1 -0
  52. package/lib/commonjs/classes/JSDOM/types/index.js +2 -0
  53. package/lib/commonjs/classes/JSDOM/types/index.js.map +1 -0
  54. package/lib/commonjs/classes/index.js +17 -0
  55. package/lib/commonjs/classes/index.js.map +1 -0
  56. package/lib/commonjs/index.js +17 -0
  57. package/lib/commonjs/index.js.map +1 -0
  58. package/lib/commonjs/package.json +1 -0
  59. package/lib/commonjs/specs/HtmlSandbox.nitro.js +6 -0
  60. package/lib/commonjs/specs/HtmlSandbox.nitro.js.map +1 -0
  61. package/lib/module/classes/JSDOM/JSDOM.class.js +133 -0
  62. package/lib/module/classes/JSDOM/JSDOM.class.js.map +1 -0
  63. package/lib/module/classes/JSDOM/index.js +4 -0
  64. package/lib/module/classes/JSDOM/index.js.map +1 -0
  65. package/lib/module/classes/JSDOM/types/IFetchOptions.js +2 -0
  66. package/lib/module/classes/JSDOM/types/IFetchOptions.js.map +1 -0
  67. package/lib/module/classes/JSDOM/types/IJSDOMOptions.js +4 -0
  68. package/lib/module/classes/JSDOM/types/IJSDOMOptions.js.map +1 -0
  69. package/lib/module/classes/JSDOM/types/index.js +2 -0
  70. package/lib/module/classes/JSDOM/types/index.js.map +1 -0
  71. package/lib/module/classes/index.js +4 -0
  72. package/lib/module/classes/index.js.map +1 -0
  73. package/lib/module/index.js +4 -0
  74. package/lib/module/index.js.map +1 -0
  75. package/lib/module/specs/HtmlSandbox.nitro.js +4 -0
  76. package/lib/module/specs/HtmlSandbox.nitro.js.map +1 -0
  77. package/lib/typescript/src/classes/JSDOM/JSDOM.class.d.ts +74 -0
  78. package/lib/typescript/src/classes/JSDOM/JSDOM.class.d.ts.map +1 -0
  79. package/lib/typescript/src/classes/JSDOM/index.d.ts +3 -0
  80. package/lib/typescript/src/classes/JSDOM/index.d.ts.map +1 -0
  81. package/lib/typescript/src/classes/JSDOM/types/IFetchOptions.d.ts +14 -0
  82. package/lib/typescript/src/classes/JSDOM/types/IFetchOptions.d.ts.map +1 -0
  83. package/lib/typescript/src/classes/JSDOM/types/IJSDOMOptions.d.ts +57 -0
  84. package/lib/typescript/src/classes/JSDOM/types/IJSDOMOptions.d.ts.map +1 -0
  85. package/lib/typescript/src/classes/JSDOM/types/index.d.ts +3 -0
  86. package/lib/typescript/src/classes/JSDOM/types/index.d.ts.map +1 -0
  87. package/lib/typescript/src/classes/index.d.ts +2 -0
  88. package/lib/typescript/src/classes/index.d.ts.map +1 -0
  89. package/lib/typescript/src/index.d.ts +2 -0
  90. package/lib/typescript/src/index.d.ts.map +1 -0
  91. package/lib/typescript/src/specs/HtmlSandbox.nitro.d.ts +13 -0
  92. package/lib/typescript/src/specs/HtmlSandbox.nitro.d.ts.map +1 -0
  93. package/nitro.json +26 -0
  94. package/nitrogen/generated/.gitattributes +1 -0
  95. package/nitrogen/generated/android/NitroJsdom+autolinking.cmake +81 -0
  96. package/nitrogen/generated/android/NitroJsdom+autolinking.gradle +27 -0
  97. package/nitrogen/generated/android/NitroJsdomOnLoad.cpp +49 -0
  98. package/nitrogen/generated/android/NitroJsdomOnLoad.hpp +34 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrojsdom/NitroJsdomOnLoad.kt +35 -0
  100. package/nitrogen/generated/ios/NitroJsdom+autolinking.rb +62 -0
  101. package/nitrogen/generated/ios/NitroJsdom-Swift-Cxx-Bridge.cpp +17 -0
  102. package/nitrogen/generated/ios/NitroJsdom-Swift-Cxx-Bridge.hpp +27 -0
  103. package/nitrogen/generated/ios/NitroJsdom-Swift-Cxx-Umbrella.hpp +38 -0
  104. package/nitrogen/generated/ios/NitroJsdomAutolinking.mm +35 -0
  105. package/nitrogen/generated/ios/NitroJsdomAutolinking.swift +16 -0
  106. package/nitrogen/generated/shared/c++/HybridHtmlSandboxSpec.cpp +26 -0
  107. package/nitrogen/generated/shared/c++/HybridHtmlSandboxSpec.hpp +73 -0
  108. package/package.json +131 -0
  109. package/src/classes/JSDOM/JSDOM.class.ts +145 -0
  110. package/src/classes/JSDOM/index.ts +2 -0
  111. package/src/classes/JSDOM/types/IFetchOptions.ts +14 -0
  112. package/src/classes/JSDOM/types/IJSDOMOptions.ts +57 -0
  113. package/src/classes/JSDOM/types/index.ts +2 -0
  114. package/src/classes/index.ts +1 -0
  115. package/src/index.ts +1 -0
  116. package/src/specs/HtmlSandbox.nitro.ts +33 -0
@@ -0,0 +1,157 @@
1
+ #include "DOMBindingsInternal.hpp"
2
+ #include "QuickJSRuntime.hpp"
3
+ #include "../lexbor/LexborDocument.hpp"
4
+ #include <lexbor/html/html.h>
5
+ #include <lexbor/dom/dom.h>
6
+ #include <cctype>
7
+ #include <sstream>
8
+
9
+ namespace margelo::nitro::nitrojsdom {
10
+
11
+ JSClassID js_element_class_id = 0;
12
+ JSClassID js_node_class_id = 0;
13
+
14
+ namespace {
15
+ JSClassDef js_element_class = { "Element", .finalizer = nullptr };
16
+ } // namespace
17
+
18
+ JSValue make_element(JSContext* ctx, void* ptr) {
19
+ if (!ptr) return JS_NULL;
20
+
21
+ RuntimeContext* rctx = get_ctx(ctx);
22
+ if (rctx) {
23
+ auto it = rctx->node_wrapper_cache.find(ptr);
24
+ if (it != rctx->node_wrapper_cache.end()) {
25
+ JSValue* cached = static_cast<JSValue*>(it->second);
26
+ return JS_DupValue(ctx, *cached);
27
+ }
28
+ }
29
+
30
+ lxb_dom_node_t* node = static_cast<lxb_dom_node_t*>(ptr);
31
+ JSValue obj;
32
+ if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) {
33
+ obj = JS_NewObjectClass(ctx, js_element_class_id);
34
+ } else {
35
+ obj = JS_NewObjectClass(ctx, js_node_class_id);
36
+ }
37
+ JS_SetOpaque(obj, ptr);
38
+
39
+ if (rctx) {
40
+ rctx->node_wrapper_cache[ptr] = new JSValue(JS_DupValue(ctx, obj));
41
+ }
42
+
43
+ return obj;
44
+ }
45
+
46
+ void invalidate_node_cache(JSContext* ctx, RuntimeContext* rctx, void* node) {
47
+ if (!rctx || !node) return;
48
+ auto it = rctx->node_wrapper_cache.find(node);
49
+ if (it != rctx->node_wrapper_cache.end()) {
50
+ JSValue* v = static_cast<JSValue*>(it->second);
51
+ JS_SetOpaque(*v, nullptr);
52
+ JS_FreeValue(ctx, *v);
53
+ delete v;
54
+ rctx->node_wrapper_cache.erase(it);
55
+ }
56
+ }
57
+
58
+ void invalidate_node_cache_batch(JSContext* ctx, RuntimeContext* rctx, const std::vector<void*>& nodes) {
59
+ for (void* n : nodes) invalidate_node_cache(ctx, rctx, n);
60
+ }
61
+
62
+ void clear_node_cache(JSContext* ctx, RuntimeContext* rctx) {
63
+ if (!rctx) return;
64
+ for (auto& kv : rctx->node_wrapper_cache) {
65
+ JSValue* v = static_cast<JSValue*>(kv.second);
66
+ JS_SetOpaque(*v, nullptr);
67
+ JS_FreeValue(ctx, *v);
68
+ delete v;
69
+ }
70
+ rctx->node_wrapper_cache.clear();
71
+ }
72
+
73
+ JSValue make_element_array(JSContext* ctx, const std::vector<void*>& elements) {
74
+ JSValue arr = JS_NewArray(ctx);
75
+ for (size_t i = 0; i < elements.size(); i++)
76
+ JS_SetPropertyUint32(ctx, arr, (uint32_t)i, make_element(ctx, elements[i]));
77
+ return arr;
78
+ }
79
+
80
+ lxb_dom_element_t* unwrap_element(JSContext* ctx, JSValue val) {
81
+ return static_cast<lxb_dom_element_t*>(JS_GetOpaque(val, js_element_class_id));
82
+ }
83
+
84
+ lxb_dom_node_t* unwrap_node(JSContext* ctx, JSValue val) {
85
+ void* p = JS_GetOpaque(val, js_element_class_id);
86
+ if (p) return static_cast<lxb_dom_node_t*>(p);
87
+ p = JS_GetOpaque(val, js_node_class_id);
88
+ return static_cast<lxb_dom_node_t*>(p);
89
+ }
90
+
91
+ std::string serialize_node(lxb_dom_node_t* node) {
92
+ std::string result;
93
+ lxb_html_serialize_tree_cb(node,
94
+ [](const lxb_char_t* data, size_t len, void* ctx) -> lxb_status_t {
95
+ static_cast<std::string*>(ctx)->append(reinterpret_cast<const char*>(data), len);
96
+ return LXB_STATUS_OK;
97
+ }, &result);
98
+ return result;
99
+ }
100
+
101
+ RuntimeContext* get_ctx(JSContext* ctx) {
102
+ return static_cast<RuntimeContext*>(JS_GetContextOpaque(ctx));
103
+ }
104
+
105
+ LexborDocument* get_doc(JSContext* ctx) {
106
+ auto* rctx = get_ctx(ctx);
107
+ return rctx ? rctx->document : nullptr;
108
+ }
109
+
110
+ void define_prop(JSContext* ctx, JSValue obj, const char* name, GetterFn getter, SetterFn setter) {
111
+ JSAtom atom = JS_NewAtom(ctx, name);
112
+ JSValue get_fn = JS_NewCFunction2(ctx, (JSCFunction*)getter, name, 0, JS_CFUNC_getter, 0);
113
+ JSValue set_fn = setter
114
+ ? JS_NewCFunction2(ctx, (JSCFunction*)setter, name, 1, JS_CFUNC_setter, 0)
115
+ : JS_UNDEFINED;
116
+ JS_DefinePropertyGetSet(ctx, obj, atom, get_fn, set_fn, JS_PROP_CONFIGURABLE);
117
+ JS_FreeAtom(ctx, atom);
118
+ }
119
+
120
+ bool get_bool_prop(JSContext* ctx, JSValue obj, const char* name) {
121
+ JSValue v = JS_GetPropertyStr(ctx, obj, name);
122
+ bool b = JS_ToBool(ctx, v) > 0;
123
+ JS_FreeValue(ctx, v);
124
+ return b;
125
+ }
126
+
127
+ std::string classNames_to_selector(const std::string& names) {
128
+ std::string sel;
129
+ std::istringstream iss(names);
130
+ std::string cls;
131
+ while (iss >> cls) { sel += '.'; sel += cls; }
132
+ return sel;
133
+ }
134
+
135
+ // data-foo-bar -> fooBar ; background-color -> backgroundColor
136
+ std::string attr_suffix_to_camel(const std::string& suffix) {
137
+ std::string out;
138
+ bool upper_next = false;
139
+ for (char c : suffix) {
140
+ if (c == '-') { upper_next = true; continue; }
141
+ out += upper_next ? (char)std::toupper((unsigned char)c) : c;
142
+ upper_next = false;
143
+ }
144
+ return out;
145
+ }
146
+
147
+ // fooBar -> foo-bar ; backgroundColor -> background-color
148
+ std::string camel_to_attr_suffix(const std::string& camel) {
149
+ std::string out;
150
+ for (char c : camel) {
151
+ if (std::isupper((unsigned char)c)) { out += '-'; out += (char)std::tolower((unsigned char)c); }
152
+ else out += c;
153
+ }
154
+ return out;
155
+ }
156
+
157
+ } // namespace margelo::nitro::nitrojsdom
@@ -0,0 +1,83 @@
1
+ #pragma once
2
+
3
+ // Internal header shared across the QuickJS binding translation units
4
+ // (ElementBindings.cpp, DocumentBindings.cpp, EventBindings.cpp, TimerBindings.cpp,
5
+ // WindowBindings.cpp, FetchBindings.cpp, MutationObservers.cpp, ...).
6
+ //
7
+ // DOMBindings::install() (DOMBindings.cpp) is the only orchestrator: it calls each
8
+ // of the *Bindings::install(ctx) entry points in order. Everything below is the
9
+ // small set of helpers those entry points need from one another.
10
+
11
+ #include "quickjs.h"
12
+ #include <string>
13
+ #include <vector>
14
+
15
+ // Forward-declared at global scope (not inside our namespace) so this matches
16
+ // the real lxb_dom_element_t/lxb_dom_node_t typedefs from lexbor's own headers
17
+ // bit-for-bit when both are included in the same translation unit.
18
+ struct lxb_dom_element;
19
+ struct lxb_dom_node;
20
+ typedef struct lxb_dom_element lxb_dom_element_t;
21
+ typedef struct lxb_dom_node lxb_dom_node_t;
22
+
23
+ namespace margelo::nitro::nitrojsdom {
24
+
25
+ struct RuntimeContext;
26
+ class LexborDocument;
27
+
28
+ // ── Element / Node class IDs + wrapping ──────────────────────────────────────
29
+ // js_element_class_id wraps lxb_dom_element_t* — real element nodes only.
30
+ // js_node_class_id wraps lxb_dom_node_t* — text, comment, document, etc.
31
+ //
32
+ // make_element() dispatches on the node type: Element nodes get the element
33
+ // class (which exposes getAttribute, classList, etc.); all other nodes get the
34
+ // node class (Node traversal only). This prevents non-element nodes from
35
+ // reaching lxb_dom_element_* calls.
36
+ //
37
+ // unwrap_element() returns non-null only for element-class objects.
38
+ // unwrap_node() returns non-null for either class (shared Node methods).
39
+
40
+ extern JSClassID js_element_class_id;
41
+ extern JSClassID js_node_class_id;
42
+
43
+ JSValue make_element(JSContext* ctx, void* node_or_el);
44
+ JSValue make_element_array(JSContext* ctx, const std::vector<void*>& elements);
45
+ lxb_dom_element_t* unwrap_element(JSContext* ctx, JSValue val);
46
+ lxb_dom_node_t* unwrap_node(JSContext* ctx, JSValue val);
47
+ std::string serialize_node(lxb_dom_node_t* node);
48
+
49
+ // ── RuntimeContext access ─────────────────────────────────────────────────────
50
+
51
+ RuntimeContext* get_ctx(JSContext* ctx);
52
+ LexborDocument* get_doc(JSContext* ctx);
53
+
54
+ // ── Node wrapper cache ────────────────────────────────────────────────────────
55
+
56
+ void invalidate_node_cache(JSContext* ctx, RuntimeContext* rctx, void* node);
57
+ void invalidate_node_cache_batch(JSContext* ctx, RuntimeContext* rctx, const std::vector<void*>& nodes);
58
+ void clear_node_cache(JSContext* ctx, RuntimeContext* rctx);
59
+
60
+ // ── Accessor property helper ──────────────────────────────────────────────────
61
+
62
+ using GetterFn = JSValue (*)(JSContext*, JSValue);
63
+ using SetterFn = JSValue (*)(JSContext*, JSValue, JSValue);
64
+
65
+ void define_prop(JSContext* ctx, JSValue obj, const char* name, GetterFn getter, SetterFn setter = nullptr);
66
+
67
+ // ── Misc shared helpers ───────────────────────────────────────────────────────
68
+
69
+ // Reads a boolean-ish property off any JS object (used by Event dispatch to read
70
+ // bubbles/cancelable/defaultPrevented/internal propagation flags).
71
+ bool get_bool_prop(JSContext* ctx, JSValue obj, const char* name);
72
+
73
+ // Builds a CSS selector matching elements with every class in `names` (a
74
+ // space-separated list), e.g. "foo bar" -> ".foo.bar". Shared by
75
+ // Element::getElementsByClassName and document.getElementsByClassName.
76
+ std::string classNames_to_selector(const std::string& names);
77
+
78
+ // camelCase <-> kebab-case conversion shared by DatasetBindings (data-foo-bar
79
+ // <-> fooBar) and StyleBindings (background-color <-> backgroundColor).
80
+ std::string attr_suffix_to_camel(const std::string& suffix);
81
+ std::string camel_to_attr_suffix(const std::string& camel);
82
+
83
+ } // namespace margelo::nitro::nitrojsdom