@noma.to/qwik-testing-library 1.3.2 → 1.5.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.
- package/README.md +16 -26
- package/lib/lib/qwik-testing-library.qwik.cjs +18 -2
- package/lib/lib/qwik-testing-library.qwik.mjs +18 -2
- package/lib/setup.qwik.cjs +8 -0
- package/lib/setup.qwik.mjs +8 -0
- package/lib-types/lib/qwik-testing-library.d.ts +1 -1
- package/lib-types/setup.d.ts +7 -0
- package/package.json +15 -10
- package/lib/lib/qwikloader.qwik.cjs +0 -252
- package/lib/lib/qwikloader.qwik.mjs +0 -252
- package/lib-types/lib/qwikloader.d.ts +0 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ src="https://raw.githubusercontent.com/ianlet/qwik-testing-library/main/high-vol
|
|
|
19
19
|
[![MIT License][license-badge]][license]
|
|
20
20
|
|
|
21
21
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
22
|
-
[](#contributors-)
|
|
23
23
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
24
24
|
[![PRs Welcome][prs-badge]][prs]
|
|
25
25
|
[![Code of Conduct][coc-badge]][coc]
|
|
@@ -131,7 +131,7 @@ should be installed as one of your project's `devDependencies`:
|
|
|
131
131
|
npm install --save-dev @noma.to/qwik-testing-library @testing-library/dom
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
This library supports `qwik` versions `1.
|
|
134
|
+
This library supports `qwik` versions `1.12.0` and above and `@testing-library/dom` versions `10.1.0` and above.
|
|
135
135
|
|
|
136
136
|
You may also be interested in installing `@testing-library/jest-dom` and `@testing-library/user-event` so you can
|
|
137
137
|
use [the custom jest matchers][jest-dom] and [the user event library][user-event] to test interactions with the DOM.
|
|
@@ -141,10 +141,12 @@ npm install --save-dev @testing-library/jest-dom @testing-library/user-event
|
|
|
141
141
|
```
|
|
142
142
|
|
|
143
143
|
Finally, we need a DOM environment to run the tests in.
|
|
144
|
-
This library
|
|
144
|
+
This library is tested with both `jsdom` and `happy-dom`:
|
|
145
145
|
|
|
146
146
|
```shell
|
|
147
147
|
npm install --save-dev jsdom
|
|
148
|
+
# or
|
|
149
|
+
npm install --save-dev happy-dom
|
|
148
150
|
```
|
|
149
151
|
|
|
150
152
|
[npm]: https://www.npmjs.com/
|
|
@@ -160,10 +162,10 @@ npm install --save-dev jsdom
|
|
|
160
162
|
We recommend using `@noma.to/qwik-testing-library` with [Vitest][vitest] as your test
|
|
161
163
|
runner.
|
|
162
164
|
|
|
163
|
-
If you haven't done so already,
|
|
165
|
+
If you haven't done so already, install vitest:
|
|
164
166
|
|
|
165
167
|
```shell
|
|
166
|
-
npm
|
|
168
|
+
npm install --save-dev vitest
|
|
167
169
|
```
|
|
168
170
|
|
|
169
171
|
After that, we need to configure Vitest so it can run your tests.
|
|
@@ -192,8 +194,11 @@ export default defineConfig((configEnv) =>
|
|
|
192
194
|
},
|
|
193
195
|
// configure your test environment
|
|
194
196
|
test: {
|
|
195
|
-
environment: "jsdom",
|
|
196
|
-
setupFiles: [
|
|
197
|
+
environment: "jsdom", // or "happy-dom"
|
|
198
|
+
setupFiles: [
|
|
199
|
+
"@noma.to/qwik-testing-library/setup",
|
|
200
|
+
"@testing-library/jest-dom/vitest", // optional, for DOM matchers
|
|
201
|
+
],
|
|
197
202
|
globals: true,
|
|
198
203
|
},
|
|
199
204
|
}),
|
|
@@ -216,24 +221,8 @@ As the build will try to use `./src/index.ts` as the entry point, we need to cre
|
|
|
216
221
|
*/
|
|
217
222
|
```
|
|
218
223
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
```ts
|
|
222
|
-
// vitest.setup.ts
|
|
223
|
-
|
|
224
|
-
// Configure DOM matchers to work in Vitest
|
|
225
|
-
import "@testing-library/jest-dom/vitest";
|
|
226
|
-
|
|
227
|
-
// This has to run before qdev.ts loads. `beforeAll` is too late
|
|
228
|
-
globalThis.qTest = false; // Forces Qwik to run as if it was in a Browser
|
|
229
|
-
globalThis.qRuntimeQrl = true;
|
|
230
|
-
globalThis.qDev = true;
|
|
231
|
-
globalThis.qInspector = false;
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
This setup will make sure that Qwik is properly configured.
|
|
235
|
-
It also loads `@testing-library/jest-dom/vitest` in your test runner
|
|
236
|
-
so you can use matchers like `expect(...).toBeInTheDocument()`.
|
|
224
|
+
The `@noma.to/qwik-testing-library/setup` module configures Qwik globals (`qTest`, `qRuntimeQrl`, `qDev`,
|
|
225
|
+
`qInspector`) for testing. It must run before any Qwik code loads, which is why it's added to `setupFiles`.
|
|
237
226
|
|
|
238
227
|
By default, Qwik Testing Library cleans everything up automatically for you.
|
|
239
228
|
You can opt out of this by setting the environment variable `QTL_SKIP_AUTO_CLEANUP` to `true`.
|
|
@@ -307,7 +296,7 @@ describe("<Counter />", () => {
|
|
|
307
296
|
await user.click(incrementBtn);
|
|
308
297
|
|
|
309
298
|
// assert that the counter is now 2
|
|
310
|
-
await
|
|
299
|
+
expect(await screen.findByText(/count:2/)).toBeInTheDocument();
|
|
311
300
|
});
|
|
312
301
|
})
|
|
313
302
|
```
|
|
@@ -482,6 +471,7 @@ Thanks goes to these people ([emoji key][emojis]):
|
|
|
482
471
|
<tr>
|
|
483
472
|
<td align="center" valign="top" width="14.28%"><a href="https://noma.to/"><img src="https://avatars.githubusercontent.com/u/6018732?v=4?s=100" width="100px;" alt="Ian Létourneau"/><br /><sub><b>Ian Létourneau</b></sub></a><br /><a href="https://github.com/ianlet/qwik-testing-library/commits?author=ianlet" title="Code">💻</a> <a href="https://github.com/ianlet/qwik-testing-library/commits?author=ianlet" title="Tests">⚠️</a> <a href="#ideas-ianlet" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/ianlet/qwik-testing-library/commits?author=ianlet" title="Documentation">📖</a> <a href="#example-ianlet" title="Examples">💡</a></td>
|
|
484
473
|
<td align="center" valign="top" width="14.28%"><a href="https://brandonpittman.com"><img src="https://avatars.githubusercontent.com/u/967145?v=4?s=100" width="100px;" alt="Brandon Pittman"/><br /><sub><b>Brandon Pittman</b></sub></a><br /><a href="https://github.com/ianlet/qwik-testing-library/commits?author=brandonpittman" title="Documentation">📖</a></td>
|
|
474
|
+
<td align="center" valign="top" width="14.28%"><a href="http://jackshelton.com"><img src="https://avatars.githubusercontent.com/u/104264123?v=4?s=100" width="100px;" alt="Jack Shelton"/><br /><sub><b>Jack Shelton</b></sub></a><br /><a href="https://github.com/ianlet/qwik-testing-library/pulls?q=is%3Apr+reviewed-by%3Athejackshelton" title="Reviewed Pull Requests">👀</a></td>
|
|
485
475
|
</tr>
|
|
486
476
|
</tbody>
|
|
487
477
|
<tfoot>
|
|
@@ -24,7 +24,21 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
25
25
|
const jsxRuntime = require("@builder.io/qwik/jsx-runtime");
|
|
26
26
|
const dom = require("@testing-library/dom");
|
|
27
|
-
const
|
|
27
|
+
const server = require("@builder.io/qwik/server");
|
|
28
|
+
if (typeof HTMLTemplateElement !== "undefined") {
|
|
29
|
+
const testTemplate = document.createElement("template");
|
|
30
|
+
const testNode = document.createComment("test");
|
|
31
|
+
testTemplate.insertBefore(testNode, null);
|
|
32
|
+
const needsPatch = testTemplate.childNodes.length === 0;
|
|
33
|
+
testNode.remove();
|
|
34
|
+
if (needsPatch) {
|
|
35
|
+
Object.defineProperty(HTMLTemplateElement.prototype, "childNodes", {
|
|
36
|
+
get() {
|
|
37
|
+
return this.content.childNodes;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
28
42
|
if (typeof process === "undefined" || !process.env?.QTL_SKIP_AUTO_CLEANUP) {
|
|
29
43
|
if (typeof afterEach === "function") {
|
|
30
44
|
afterEach(() => {
|
|
@@ -46,7 +60,9 @@ async function render(ui, options = {}) {
|
|
|
46
60
|
const wrappedUi = !Wrapper ? ui : /* @__PURE__ */ jsxRuntime.jsx(Wrapper, {
|
|
47
61
|
children: ui
|
|
48
62
|
});
|
|
49
|
-
|
|
63
|
+
const doc = baseElement.ownerDocument;
|
|
64
|
+
const win = doc.defaultView;
|
|
65
|
+
new Function("document", "window", server.getQwikLoaderScript())(doc, win);
|
|
50
66
|
const { cleanup: cleanup2 } = await qwik.render(container, wrappedUi, {
|
|
51
67
|
serverData
|
|
52
68
|
});
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { jsx } from "@builder.io/qwik/jsx-runtime";
|
|
2
2
|
import { getQueriesForElement, prettyDOM } from "@testing-library/dom";
|
|
3
3
|
export * from "@testing-library/dom";
|
|
4
|
-
import {
|
|
4
|
+
import { getQwikLoaderScript } from "@builder.io/qwik/server";
|
|
5
|
+
if (typeof HTMLTemplateElement !== "undefined") {
|
|
6
|
+
const testTemplate = document.createElement("template");
|
|
7
|
+
const testNode = document.createComment("test");
|
|
8
|
+
testTemplate.insertBefore(testNode, null);
|
|
9
|
+
const needsPatch = testTemplate.childNodes.length === 0;
|
|
10
|
+
testNode.remove();
|
|
11
|
+
if (needsPatch) {
|
|
12
|
+
Object.defineProperty(HTMLTemplateElement.prototype, "childNodes", {
|
|
13
|
+
get() {
|
|
14
|
+
return this.content.childNodes;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
5
19
|
if (typeof process === "undefined" || !process.env?.QTL_SKIP_AUTO_CLEANUP) {
|
|
6
20
|
if (typeof afterEach === "function") {
|
|
7
21
|
afterEach(() => {
|
|
@@ -23,7 +37,9 @@ async function render(ui, options = {}) {
|
|
|
23
37
|
const wrappedUi = !Wrapper ? ui : /* @__PURE__ */ jsx(Wrapper, {
|
|
24
38
|
children: ui
|
|
25
39
|
});
|
|
26
|
-
|
|
40
|
+
const doc = baseElement.ownerDocument;
|
|
41
|
+
const win = doc.defaultView;
|
|
42
|
+
new Function("document", "window", getQwikLoaderScript())(doc, win);
|
|
27
43
|
const { cleanup: cleanup2 } = await qwik.render(container, wrappedUi, {
|
|
28
44
|
serverData
|
|
29
45
|
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
globalThis.qTest = false;
|
|
4
|
+
globalThis.qRuntimeQrl = true;
|
|
5
|
+
globalThis.qDev = true;
|
|
6
|
+
globalThis.qInspector = false;
|
|
7
|
+
const __qwikSetupComplete = true;
|
|
8
|
+
exports.__qwikSetupComplete = __qwikSetupComplete;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noma.to/qwik-testing-library",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Simple and complete Qwik testing utilities that encourage good testing practices.",
|
|
5
5
|
"repository": "https://github.com/ianlet/qwik-testing-library",
|
|
6
6
|
"homepage": "https://github.com/ianlet/qwik-testing-library",
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
"types": "./lib-types/index.d.ts",
|
|
14
14
|
"import": "./lib/index.qwik.mjs",
|
|
15
15
|
"require": "./lib/index.qwik.cjs"
|
|
16
|
+
},
|
|
17
|
+
"./setup": {
|
|
18
|
+
"types": "./lib-types/setup.d.ts",
|
|
19
|
+
"import": "./lib/setup.qwik.mjs",
|
|
20
|
+
"require": "./lib/setup.qwik.cjs"
|
|
16
21
|
}
|
|
17
22
|
},
|
|
18
23
|
"files": [
|
|
@@ -35,17 +40,17 @@
|
|
|
35
40
|
},
|
|
36
41
|
"devDependencies": {
|
|
37
42
|
"@types/eslint": "8.56.10",
|
|
38
|
-
"@types/node": "
|
|
39
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
40
|
-
"@typescript-eslint/parser": "8.
|
|
43
|
+
"@types/node": "25.1.0",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "8.54.0",
|
|
45
|
+
"@typescript-eslint/parser": "8.54.0",
|
|
41
46
|
"eslint": "8.57.1",
|
|
42
|
-
"eslint-plugin-qwik": "1.
|
|
43
|
-
"prettier": "3.
|
|
44
|
-
"typescript": "5.
|
|
47
|
+
"eslint-plugin-qwik": "1.19.0",
|
|
48
|
+
"prettier": "3.8.1",
|
|
49
|
+
"typescript": "5.9.3",
|
|
45
50
|
"undici": "*",
|
|
46
|
-
"vite": "
|
|
47
|
-
"vite-tsconfig-paths": "^
|
|
48
|
-
"vitest": "^
|
|
51
|
+
"vite": "7.3.1",
|
|
52
|
+
"vite-tsconfig-paths": "^6.0.5",
|
|
53
|
+
"vitest": "^4.0.18"
|
|
49
54
|
},
|
|
50
55
|
"peerDependencies": {
|
|
51
56
|
"@builder.io/qwik": ">= 1.12.0 < 2",
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
8
|
-
enumerable: true,
|
|
9
|
-
configurable: true,
|
|
10
|
-
writable: true,
|
|
11
|
-
value
|
|
12
|
-
}) : obj[key] = value;
|
|
13
|
-
var __spreadValues = (a, b) => {
|
|
14
|
-
for (var prop in b || (b = {})) {
|
|
15
|
-
__hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
if (__getOwnPropSymbols) {
|
|
18
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
19
|
-
__propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return a;
|
|
23
|
-
};
|
|
24
|
-
var qwikLoader = (doc, hasInitialized) => {
|
|
25
|
-
const Q_CONTEXT = "__q_context__";
|
|
26
|
-
const win = window;
|
|
27
|
-
const events = /* @__PURE__ */ new Set();
|
|
28
|
-
const roots = /* @__PURE__ */ new Set([doc]);
|
|
29
|
-
const nativeQuerySelectorAll = (root, selector) => Array.from(root.querySelectorAll(selector));
|
|
30
|
-
const querySelectorAll = (query) => {
|
|
31
|
-
const elements = [];
|
|
32
|
-
roots.forEach(
|
|
33
|
-
(root) => elements.push(...nativeQuerySelectorAll(root, query))
|
|
34
|
-
);
|
|
35
|
-
return elements;
|
|
36
|
-
};
|
|
37
|
-
const findShadowRoots = (fragment) => {
|
|
38
|
-
processEventOrNode(fragment);
|
|
39
|
-
nativeQuerySelectorAll(fragment, "[q\\:shadowroot]").forEach((parent) => {
|
|
40
|
-
const shadowRoot = parent.shadowRoot;
|
|
41
|
-
shadowRoot && findShadowRoots(shadowRoot);
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
const isPromise = (promise) => promise && "function" == typeof promise.then;
|
|
45
|
-
const broadcast = (infix, ev, type = ev.type) => {
|
|
46
|
-
querySelectorAll("[on" + infix + "\\:" + type + "]").forEach(
|
|
47
|
-
(el) => dispatch(el, infix, ev, type)
|
|
48
|
-
);
|
|
49
|
-
};
|
|
50
|
-
const resolveContainer = (containerEl) => {
|
|
51
|
-
if (void 0 === containerEl._qwikjson_) {
|
|
52
|
-
let script = (containerEl === doc.documentElement ? doc.body : containerEl).lastElementChild;
|
|
53
|
-
while (script) {
|
|
54
|
-
if ("SCRIPT" === script.tagName && "qwik/json" === script.getAttribute("type")) {
|
|
55
|
-
containerEl._qwikjson_ = JSON.parse(
|
|
56
|
-
script.textContent.replace(/\\x3C(\/?script)/gi, "<$1")
|
|
57
|
-
);
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
script = script.previousElementSibling;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
const createEvent = (eventName, detail) => new CustomEvent(eventName, {
|
|
65
|
-
detail
|
|
66
|
-
});
|
|
67
|
-
const dispatch = async (element, onPrefix, ev, eventName = ev.type) => {
|
|
68
|
-
const attrName = "on" + onPrefix + ":" + eventName;
|
|
69
|
-
element.hasAttribute("preventdefault:" + eventName) && ev.preventDefault();
|
|
70
|
-
const ctx = element._qc_;
|
|
71
|
-
const relevantListeners = ctx && ctx.li.filter((li) => li[0] === attrName);
|
|
72
|
-
if (relevantListeners && relevantListeners.length > 0) {
|
|
73
|
-
for (const listener of relevantListeners) {
|
|
74
|
-
const results = listener[1].getFn(
|
|
75
|
-
[element, ev],
|
|
76
|
-
() => element.isConnected
|
|
77
|
-
)(ev, element);
|
|
78
|
-
const cancelBubble = ev.cancelBubble;
|
|
79
|
-
isPromise(results) && await results;
|
|
80
|
-
cancelBubble && ev.stopPropagation();
|
|
81
|
-
}
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const attrValue = element.getAttribute(attrName);
|
|
85
|
-
if (attrValue) {
|
|
86
|
-
const container = element.closest("[q\\:container]");
|
|
87
|
-
const qBase = container.getAttribute("q:base");
|
|
88
|
-
const qVersion = container.getAttribute("q:version") || "unknown";
|
|
89
|
-
const qManifest = container.getAttribute("q:manifest-hash") || "dev";
|
|
90
|
-
const base = new URL(qBase, doc.baseURI);
|
|
91
|
-
for (const qrl of attrValue.split("\n")) {
|
|
92
|
-
const url = new URL(qrl, base);
|
|
93
|
-
const href = url.href;
|
|
94
|
-
const symbol = url.hash.replace(/^#?([^?[|]*).*$/, "$1") || "default";
|
|
95
|
-
const reqTime = performance.now();
|
|
96
|
-
let handler;
|
|
97
|
-
let importError;
|
|
98
|
-
let error;
|
|
99
|
-
const isSync = qrl.startsWith("#");
|
|
100
|
-
const eventData = {
|
|
101
|
-
qBase,
|
|
102
|
-
qManifest,
|
|
103
|
-
qVersion,
|
|
104
|
-
href,
|
|
105
|
-
symbol,
|
|
106
|
-
element,
|
|
107
|
-
reqTime
|
|
108
|
-
};
|
|
109
|
-
if (isSync) {
|
|
110
|
-
const hash = container.getAttribute("q:instance");
|
|
111
|
-
handler = (doc["qFuncs_" + hash] || [])[Number.parseInt(symbol)];
|
|
112
|
-
if (!handler) {
|
|
113
|
-
importError = "sync";
|
|
114
|
-
error = new Error("sync handler error for symbol: " + symbol);
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
const uri = url.href.split("#")[0];
|
|
118
|
-
try {
|
|
119
|
-
const module2 = import(uri);
|
|
120
|
-
resolveContainer(container);
|
|
121
|
-
handler = (await module2)[symbol];
|
|
122
|
-
if (!handler) {
|
|
123
|
-
importError = "no-symbol";
|
|
124
|
-
error = new Error(`${symbol} not in ${uri}`);
|
|
125
|
-
}
|
|
126
|
-
} catch (err) {
|
|
127
|
-
importError || (importError = "async");
|
|
128
|
-
error = err;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (!handler) {
|
|
132
|
-
emitEvent(
|
|
133
|
-
"qerror",
|
|
134
|
-
__spreadValues(
|
|
135
|
-
{
|
|
136
|
-
importError,
|
|
137
|
-
error
|
|
138
|
-
},
|
|
139
|
-
eventData
|
|
140
|
-
)
|
|
141
|
-
);
|
|
142
|
-
console.error(error);
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
const previousCtx = doc[Q_CONTEXT];
|
|
146
|
-
if (element.isConnected) {
|
|
147
|
-
try {
|
|
148
|
-
doc[Q_CONTEXT] = [element, ev, url];
|
|
149
|
-
isSync || emitEvent("qsymbol", __spreadValues({}, eventData));
|
|
150
|
-
const results = handler(ev, element);
|
|
151
|
-
isPromise(results) && await results;
|
|
152
|
-
} catch (error2) {
|
|
153
|
-
emitEvent(
|
|
154
|
-
"qerror",
|
|
155
|
-
__spreadValues(
|
|
156
|
-
{
|
|
157
|
-
error: error2
|
|
158
|
-
},
|
|
159
|
-
eventData
|
|
160
|
-
)
|
|
161
|
-
);
|
|
162
|
-
} finally {
|
|
163
|
-
doc[Q_CONTEXT] = previousCtx;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
const emitEvent = (eventName, detail) => {
|
|
170
|
-
doc.dispatchEvent(createEvent(eventName, detail));
|
|
171
|
-
};
|
|
172
|
-
const camelToKebab = (str) => str.replace(/([A-Z])/g, (a) => "-" + a.toLowerCase());
|
|
173
|
-
const processDocumentEvent = async (ev) => {
|
|
174
|
-
let type = camelToKebab(ev.type);
|
|
175
|
-
let element = ev.target;
|
|
176
|
-
broadcast("-document", ev, type);
|
|
177
|
-
while (element && element.getAttribute) {
|
|
178
|
-
const results = dispatch(element, "", ev, type);
|
|
179
|
-
let cancelBubble = ev.cancelBubble;
|
|
180
|
-
isPromise(results) && await results;
|
|
181
|
-
cancelBubble = cancelBubble || ev.cancelBubble || element.hasAttribute("stoppropagation:" + ev.type);
|
|
182
|
-
element = ev.bubbles && true !== cancelBubble ? element.parentElement : null;
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
const processWindowEvent = (ev) => {
|
|
186
|
-
broadcast("-window", ev, camelToKebab(ev.type));
|
|
187
|
-
};
|
|
188
|
-
const processReadyStateChange = () => {
|
|
189
|
-
var _a;
|
|
190
|
-
const readyState = doc.readyState;
|
|
191
|
-
if (!hasInitialized && ("interactive" == readyState || "complete" == readyState)) {
|
|
192
|
-
roots.forEach(findShadowRoots);
|
|
193
|
-
hasInitialized = 1;
|
|
194
|
-
emitEvent("qinit");
|
|
195
|
-
(null != (_a = win.requestIdleCallback) ? _a : win.setTimeout).bind(win)(
|
|
196
|
-
() => emitEvent("qidle")
|
|
197
|
-
);
|
|
198
|
-
if (events.has("qvisible")) {
|
|
199
|
-
const results = querySelectorAll("[on\\:qvisible]");
|
|
200
|
-
const observer = new IntersectionObserver((entries) => {
|
|
201
|
-
for (const entry of entries) {
|
|
202
|
-
if (entry.isIntersecting) {
|
|
203
|
-
observer.unobserve(entry.target);
|
|
204
|
-
dispatch(entry.target, "", createEvent("qvisible", entry));
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
results.forEach((el) => observer.observe(el));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
const addEventListener = (el, eventName, handler, capture = false) => el.addEventListener(eventName, handler, {
|
|
213
|
-
capture,
|
|
214
|
-
passive: false
|
|
215
|
-
});
|
|
216
|
-
const processEventOrNode = (...eventNames) => {
|
|
217
|
-
for (const eventNameOrNode of eventNames) {
|
|
218
|
-
if ("string" == typeof eventNameOrNode) {
|
|
219
|
-
if (!events.has(eventNameOrNode)) {
|
|
220
|
-
roots.forEach(
|
|
221
|
-
(root) => addEventListener(root, eventNameOrNode, processDocumentEvent, true)
|
|
222
|
-
);
|
|
223
|
-
addEventListener(win, eventNameOrNode, processWindowEvent, true);
|
|
224
|
-
events.add(eventNameOrNode);
|
|
225
|
-
}
|
|
226
|
-
} else if (!roots.has(eventNameOrNode)) {
|
|
227
|
-
events.forEach(
|
|
228
|
-
(eventName) => addEventListener(
|
|
229
|
-
eventNameOrNode,
|
|
230
|
-
eventName,
|
|
231
|
-
processDocumentEvent,
|
|
232
|
-
true
|
|
233
|
-
)
|
|
234
|
-
);
|
|
235
|
-
roots.add(eventNameOrNode);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
if (!(Q_CONTEXT in doc)) {
|
|
240
|
-
doc[Q_CONTEXT] = 0;
|
|
241
|
-
const qwikevents = win.qwikevents;
|
|
242
|
-
Array.isArray(qwikevents) && processEventOrNode(...qwikevents);
|
|
243
|
-
win.qwikevents = {
|
|
244
|
-
events,
|
|
245
|
-
roots,
|
|
246
|
-
push: processEventOrNode
|
|
247
|
-
};
|
|
248
|
-
addEventListener(doc, "readystatechange", processReadyStateChange);
|
|
249
|
-
processReadyStateChange();
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
exports.qwikLoader = qwikLoader;
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
configurable: true,
|
|
8
|
-
writable: true,
|
|
9
|
-
value
|
|
10
|
-
}) : obj[key] = value;
|
|
11
|
-
var __spreadValues = (a, b) => {
|
|
12
|
-
for (var prop in b || (b = {})) {
|
|
13
|
-
__hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
14
|
-
}
|
|
15
|
-
if (__getOwnPropSymbols) {
|
|
16
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
-
__propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return a;
|
|
21
|
-
};
|
|
22
|
-
var qwikLoader = (doc, hasInitialized) => {
|
|
23
|
-
const Q_CONTEXT = "__q_context__";
|
|
24
|
-
const win = window;
|
|
25
|
-
const events = /* @__PURE__ */ new Set();
|
|
26
|
-
const roots = /* @__PURE__ */ new Set([doc]);
|
|
27
|
-
const nativeQuerySelectorAll = (root, selector) => Array.from(root.querySelectorAll(selector));
|
|
28
|
-
const querySelectorAll = (query) => {
|
|
29
|
-
const elements = [];
|
|
30
|
-
roots.forEach(
|
|
31
|
-
(root) => elements.push(...nativeQuerySelectorAll(root, query))
|
|
32
|
-
);
|
|
33
|
-
return elements;
|
|
34
|
-
};
|
|
35
|
-
const findShadowRoots = (fragment) => {
|
|
36
|
-
processEventOrNode(fragment);
|
|
37
|
-
nativeQuerySelectorAll(fragment, "[q\\:shadowroot]").forEach((parent) => {
|
|
38
|
-
const shadowRoot = parent.shadowRoot;
|
|
39
|
-
shadowRoot && findShadowRoots(shadowRoot);
|
|
40
|
-
});
|
|
41
|
-
};
|
|
42
|
-
const isPromise = (promise) => promise && "function" == typeof promise.then;
|
|
43
|
-
const broadcast = (infix, ev, type = ev.type) => {
|
|
44
|
-
querySelectorAll("[on" + infix + "\\:" + type + "]").forEach(
|
|
45
|
-
(el) => dispatch(el, infix, ev, type)
|
|
46
|
-
);
|
|
47
|
-
};
|
|
48
|
-
const resolveContainer = (containerEl) => {
|
|
49
|
-
if (void 0 === containerEl._qwikjson_) {
|
|
50
|
-
let script = (containerEl === doc.documentElement ? doc.body : containerEl).lastElementChild;
|
|
51
|
-
while (script) {
|
|
52
|
-
if ("SCRIPT" === script.tagName && "qwik/json" === script.getAttribute("type")) {
|
|
53
|
-
containerEl._qwikjson_ = JSON.parse(
|
|
54
|
-
script.textContent.replace(/\\x3C(\/?script)/gi, "<$1")
|
|
55
|
-
);
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
script = script.previousElementSibling;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
const createEvent = (eventName, detail) => new CustomEvent(eventName, {
|
|
63
|
-
detail
|
|
64
|
-
});
|
|
65
|
-
const dispatch = async (element, onPrefix, ev, eventName = ev.type) => {
|
|
66
|
-
const attrName = "on" + onPrefix + ":" + eventName;
|
|
67
|
-
element.hasAttribute("preventdefault:" + eventName) && ev.preventDefault();
|
|
68
|
-
const ctx = element._qc_;
|
|
69
|
-
const relevantListeners = ctx && ctx.li.filter((li) => li[0] === attrName);
|
|
70
|
-
if (relevantListeners && relevantListeners.length > 0) {
|
|
71
|
-
for (const listener of relevantListeners) {
|
|
72
|
-
const results = listener[1].getFn(
|
|
73
|
-
[element, ev],
|
|
74
|
-
() => element.isConnected
|
|
75
|
-
)(ev, element);
|
|
76
|
-
const cancelBubble = ev.cancelBubble;
|
|
77
|
-
isPromise(results) && await results;
|
|
78
|
-
cancelBubble && ev.stopPropagation();
|
|
79
|
-
}
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const attrValue = element.getAttribute(attrName);
|
|
83
|
-
if (attrValue) {
|
|
84
|
-
const container = element.closest("[q\\:container]");
|
|
85
|
-
const qBase = container.getAttribute("q:base");
|
|
86
|
-
const qVersion = container.getAttribute("q:version") || "unknown";
|
|
87
|
-
const qManifest = container.getAttribute("q:manifest-hash") || "dev";
|
|
88
|
-
const base = new URL(qBase, doc.baseURI);
|
|
89
|
-
for (const qrl of attrValue.split("\n")) {
|
|
90
|
-
const url = new URL(qrl, base);
|
|
91
|
-
const href = url.href;
|
|
92
|
-
const symbol = url.hash.replace(/^#?([^?[|]*).*$/, "$1") || "default";
|
|
93
|
-
const reqTime = performance.now();
|
|
94
|
-
let handler;
|
|
95
|
-
let importError;
|
|
96
|
-
let error;
|
|
97
|
-
const isSync = qrl.startsWith("#");
|
|
98
|
-
const eventData = {
|
|
99
|
-
qBase,
|
|
100
|
-
qManifest,
|
|
101
|
-
qVersion,
|
|
102
|
-
href,
|
|
103
|
-
symbol,
|
|
104
|
-
element,
|
|
105
|
-
reqTime
|
|
106
|
-
};
|
|
107
|
-
if (isSync) {
|
|
108
|
-
const hash = container.getAttribute("q:instance");
|
|
109
|
-
handler = (doc["qFuncs_" + hash] || [])[Number.parseInt(symbol)];
|
|
110
|
-
if (!handler) {
|
|
111
|
-
importError = "sync";
|
|
112
|
-
error = new Error("sync handler error for symbol: " + symbol);
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
const uri = url.href.split("#")[0];
|
|
116
|
-
try {
|
|
117
|
-
const module = import(uri);
|
|
118
|
-
resolveContainer(container);
|
|
119
|
-
handler = (await module)[symbol];
|
|
120
|
-
if (!handler) {
|
|
121
|
-
importError = "no-symbol";
|
|
122
|
-
error = new Error(`${symbol} not in ${uri}`);
|
|
123
|
-
}
|
|
124
|
-
} catch (err) {
|
|
125
|
-
importError || (importError = "async");
|
|
126
|
-
error = err;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (!handler) {
|
|
130
|
-
emitEvent(
|
|
131
|
-
"qerror",
|
|
132
|
-
__spreadValues(
|
|
133
|
-
{
|
|
134
|
-
importError,
|
|
135
|
-
error
|
|
136
|
-
},
|
|
137
|
-
eventData
|
|
138
|
-
)
|
|
139
|
-
);
|
|
140
|
-
console.error(error);
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
const previousCtx = doc[Q_CONTEXT];
|
|
144
|
-
if (element.isConnected) {
|
|
145
|
-
try {
|
|
146
|
-
doc[Q_CONTEXT] = [element, ev, url];
|
|
147
|
-
isSync || emitEvent("qsymbol", __spreadValues({}, eventData));
|
|
148
|
-
const results = handler(ev, element);
|
|
149
|
-
isPromise(results) && await results;
|
|
150
|
-
} catch (error2) {
|
|
151
|
-
emitEvent(
|
|
152
|
-
"qerror",
|
|
153
|
-
__spreadValues(
|
|
154
|
-
{
|
|
155
|
-
error: error2
|
|
156
|
-
},
|
|
157
|
-
eventData
|
|
158
|
-
)
|
|
159
|
-
);
|
|
160
|
-
} finally {
|
|
161
|
-
doc[Q_CONTEXT] = previousCtx;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
const emitEvent = (eventName, detail) => {
|
|
168
|
-
doc.dispatchEvent(createEvent(eventName, detail));
|
|
169
|
-
};
|
|
170
|
-
const camelToKebab = (str) => str.replace(/([A-Z])/g, (a) => "-" + a.toLowerCase());
|
|
171
|
-
const processDocumentEvent = async (ev) => {
|
|
172
|
-
let type = camelToKebab(ev.type);
|
|
173
|
-
let element = ev.target;
|
|
174
|
-
broadcast("-document", ev, type);
|
|
175
|
-
while (element && element.getAttribute) {
|
|
176
|
-
const results = dispatch(element, "", ev, type);
|
|
177
|
-
let cancelBubble = ev.cancelBubble;
|
|
178
|
-
isPromise(results) && await results;
|
|
179
|
-
cancelBubble = cancelBubble || ev.cancelBubble || element.hasAttribute("stoppropagation:" + ev.type);
|
|
180
|
-
element = ev.bubbles && true !== cancelBubble ? element.parentElement : null;
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
const processWindowEvent = (ev) => {
|
|
184
|
-
broadcast("-window", ev, camelToKebab(ev.type));
|
|
185
|
-
};
|
|
186
|
-
const processReadyStateChange = () => {
|
|
187
|
-
var _a;
|
|
188
|
-
const readyState = doc.readyState;
|
|
189
|
-
if (!hasInitialized && ("interactive" == readyState || "complete" == readyState)) {
|
|
190
|
-
roots.forEach(findShadowRoots);
|
|
191
|
-
hasInitialized = 1;
|
|
192
|
-
emitEvent("qinit");
|
|
193
|
-
(null != (_a = win.requestIdleCallback) ? _a : win.setTimeout).bind(win)(
|
|
194
|
-
() => emitEvent("qidle")
|
|
195
|
-
);
|
|
196
|
-
if (events.has("qvisible")) {
|
|
197
|
-
const results = querySelectorAll("[on\\:qvisible]");
|
|
198
|
-
const observer = new IntersectionObserver((entries) => {
|
|
199
|
-
for (const entry of entries) {
|
|
200
|
-
if (entry.isIntersecting) {
|
|
201
|
-
observer.unobserve(entry.target);
|
|
202
|
-
dispatch(entry.target, "", createEvent("qvisible", entry));
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
results.forEach((el) => observer.observe(el));
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
const addEventListener = (el, eventName, handler, capture = false) => el.addEventListener(eventName, handler, {
|
|
211
|
-
capture,
|
|
212
|
-
passive: false
|
|
213
|
-
});
|
|
214
|
-
const processEventOrNode = (...eventNames) => {
|
|
215
|
-
for (const eventNameOrNode of eventNames) {
|
|
216
|
-
if ("string" == typeof eventNameOrNode) {
|
|
217
|
-
if (!events.has(eventNameOrNode)) {
|
|
218
|
-
roots.forEach(
|
|
219
|
-
(root) => addEventListener(root, eventNameOrNode, processDocumentEvent, true)
|
|
220
|
-
);
|
|
221
|
-
addEventListener(win, eventNameOrNode, processWindowEvent, true);
|
|
222
|
-
events.add(eventNameOrNode);
|
|
223
|
-
}
|
|
224
|
-
} else if (!roots.has(eventNameOrNode)) {
|
|
225
|
-
events.forEach(
|
|
226
|
-
(eventName) => addEventListener(
|
|
227
|
-
eventNameOrNode,
|
|
228
|
-
eventName,
|
|
229
|
-
processDocumentEvent,
|
|
230
|
-
true
|
|
231
|
-
)
|
|
232
|
-
);
|
|
233
|
-
roots.add(eventNameOrNode);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
if (!(Q_CONTEXT in doc)) {
|
|
238
|
-
doc[Q_CONTEXT] = 0;
|
|
239
|
-
const qwikevents = win.qwikevents;
|
|
240
|
-
Array.isArray(qwikevents) && processEventOrNode(...qwikevents);
|
|
241
|
-
win.qwikevents = {
|
|
242
|
-
events,
|
|
243
|
-
roots,
|
|
244
|
-
push: processEventOrNode
|
|
245
|
-
};
|
|
246
|
-
addEventListener(doc, "readystatechange", processReadyStateChange);
|
|
247
|
-
processReadyStateChange();
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
export {
|
|
251
|
-
qwikLoader
|
|
252
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export function qwikLoader(doc: any, hasInitialized: any): void;
|