haori 0.1.2 → 0.1.4
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/LICENSE +21 -21
- package/README.ja.md +182 -167
- package/README.md +184 -169
- package/dist/haori.cjs.js +11 -10
- package/dist/haori.cjs.js.map +1 -1
- package/dist/haori.es.js +889 -683
- package/dist/haori.es.js.map +1 -1
- package/dist/haori.iife.js +10 -9
- package/dist/haori.iife.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/package.json +1 -1
- package/dist/src/expression.d.ts +27 -3
- package/dist/src/expression.d.ts.map +1 -1
- package/dist/src/expression.js +97 -24
- package/dist/src/expression.js.map +1 -1
- package/dist/src/form.d.ts.map +1 -1
- package/dist/src/form.js +17 -3
- package/dist/src/form.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/procedure.d.ts +50 -0
- package/dist/src/procedure.d.ts.map +1 -1
- package/dist/src/procedure.js +166 -20
- package/dist/src/procedure.js.map +1 -1
- package/dist/tests/core.test.js +46 -46
- package/dist/tests/data-each-browserlike.test.js +10 -10
- package/dist/tests/data-each-fragment-debug.test.js +36 -36
- package/dist/tests/data-each-table.test.js +93 -10
- package/dist/tests/data-each-table.test.js.map +1 -1
- package/dist/tests/data-fetch-tbody-dom.test.js +12 -12
- package/dist/tests/expression.test.js +37 -21
- package/dist/tests/expression.test.js.map +1 -1
- package/dist/tests/form.test.js +241 -241
- package/dist/tests/import.test.js +34 -34
- package/dist/tests/procedure-action-operations.test.js +85 -0
- package/dist/tests/procedure-action-operations.test.js.map +1 -1
- package/dist/tests/procedure-fetch-options.test.js +58 -0
- package/dist/tests/procedure-fetch-options.test.js.map +1 -1
- package/dist/tests/procedure_events.test.d.ts.map +1 -1
- package/dist/tests/procedure_events.test.js +65 -0
- package/dist/tests/procedure_events.test.js.map +1 -1
- package/dist/tests/row-move.test.js +67 -67
- package/dist/tests/row-operations.test.js +84 -84
- package/package.json +70 -70
|
@@ -22,15 +22,15 @@ describe('Row operations', () => {
|
|
|
22
22
|
});
|
|
23
23
|
describe('Outside form', () => {
|
|
24
24
|
it('should add a new row (data-click-row-add)', async () => {
|
|
25
|
-
container.innerHTML = `
|
|
26
|
-
<div data-bind='{"items":[{"name":"A"},{"name":"B"}]}'>
|
|
27
|
-
<ul data-each="items" data-each-key="name">
|
|
28
|
-
<li>
|
|
29
|
-
<span>{{name}}</span>
|
|
30
|
-
<button data-click-row-add>+</button>
|
|
31
|
-
</li>
|
|
32
|
-
</ul>
|
|
33
|
-
</div>
|
|
25
|
+
container.innerHTML = `
|
|
26
|
+
<div data-bind='{"items":[{"name":"A"},{"name":"B"}]}'>
|
|
27
|
+
<ul data-each="items" data-each-key="name">
|
|
28
|
+
<li>
|
|
29
|
+
<span>{{name}}</span>
|
|
30
|
+
<button data-click-row-add>+</button>
|
|
31
|
+
</li>
|
|
32
|
+
</ul>
|
|
33
|
+
</div>
|
|
34
34
|
`;
|
|
35
35
|
await Core.scan(container);
|
|
36
36
|
await waitForDomSettled();
|
|
@@ -43,15 +43,15 @@ describe('Row operations', () => {
|
|
|
43
43
|
expect(items.length).toBe(3);
|
|
44
44
|
});
|
|
45
45
|
it('should remove a row (data-click-row-remove)', async () => {
|
|
46
|
-
container.innerHTML = `
|
|
47
|
-
<div data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
48
|
-
<ul data-each="items" data-each-key="name">
|
|
49
|
-
<li>
|
|
50
|
-
<span>{{name}}</span>
|
|
51
|
-
<button data-click-row-remove>-</button>
|
|
52
|
-
</li>
|
|
53
|
-
</ul>
|
|
54
|
-
</div>
|
|
46
|
+
container.innerHTML = `
|
|
47
|
+
<div data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
48
|
+
<ul data-each="items" data-each-key="name">
|
|
49
|
+
<li>
|
|
50
|
+
<span>{{name}}</span>
|
|
51
|
+
<button data-click-row-remove>-</button>
|
|
52
|
+
</li>
|
|
53
|
+
</ul>
|
|
54
|
+
</div>
|
|
55
55
|
`;
|
|
56
56
|
await Core.scan(container);
|
|
57
57
|
await waitForDomSettled();
|
|
@@ -69,15 +69,15 @@ describe('Row operations', () => {
|
|
|
69
69
|
expect(items[1].textContent).toBe('C');
|
|
70
70
|
});
|
|
71
71
|
it('should move row up (data-click-row-prev)', async () => {
|
|
72
|
-
container.innerHTML = `
|
|
73
|
-
<div data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
74
|
-
<ul data-each="items" data-each-key="name">
|
|
75
|
-
<li>
|
|
76
|
-
<span>{{name}}</span>
|
|
77
|
-
<button data-click-row-prev>↑</button>
|
|
78
|
-
</li>
|
|
79
|
-
</ul>
|
|
80
|
-
</div>
|
|
72
|
+
container.innerHTML = `
|
|
73
|
+
<div data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
74
|
+
<ul data-each="items" data-each-key="name">
|
|
75
|
+
<li>
|
|
76
|
+
<span>{{name}}</span>
|
|
77
|
+
<button data-click-row-prev>↑</button>
|
|
78
|
+
</li>
|
|
79
|
+
</ul>
|
|
80
|
+
</div>
|
|
81
81
|
`;
|
|
82
82
|
await Core.scan(container);
|
|
83
83
|
await waitForDomSettled();
|
|
@@ -90,15 +90,15 @@ describe('Row operations', () => {
|
|
|
90
90
|
expect(items[2].textContent).toBe('C');
|
|
91
91
|
});
|
|
92
92
|
it('should move row down (data-click-row-next)', async () => {
|
|
93
|
-
container.innerHTML = `
|
|
94
|
-
<div data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
95
|
-
<ul data-each="items" data-each-key="name">
|
|
96
|
-
<li>
|
|
97
|
-
<span>{{name}}</span>
|
|
98
|
-
<button data-click-row-next>↓</button>
|
|
99
|
-
</li>
|
|
100
|
-
</ul>
|
|
101
|
-
</div>
|
|
93
|
+
container.innerHTML = `
|
|
94
|
+
<div data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
95
|
+
<ul data-each="items" data-each-key="name">
|
|
96
|
+
<li>
|
|
97
|
+
<span>{{name}}</span>
|
|
98
|
+
<button data-click-row-next>↓</button>
|
|
99
|
+
</li>
|
|
100
|
+
</ul>
|
|
101
|
+
</div>
|
|
102
102
|
`;
|
|
103
103
|
await Core.scan(container);
|
|
104
104
|
await waitForDomSettled();
|
|
@@ -113,15 +113,15 @@ describe('Row operations', () => {
|
|
|
113
113
|
});
|
|
114
114
|
describe('Inside form', () => {
|
|
115
115
|
it('should add a new row inside form (data-click-row-add)', async () => {
|
|
116
|
-
container.innerHTML = `
|
|
117
|
-
<form data-bind='{"items":[{"name":"A"},{"name":"B"}]}'>
|
|
118
|
-
<div data-each="items" data-each-key="name">
|
|
119
|
-
<div>
|
|
120
|
-
<span>{{name}}</span>
|
|
121
|
-
<button type="button" data-click-row-add>+</button>
|
|
122
|
-
</div>
|
|
123
|
-
</div>
|
|
124
|
-
</form>
|
|
116
|
+
container.innerHTML = `
|
|
117
|
+
<form data-bind='{"items":[{"name":"A"},{"name":"B"}]}'>
|
|
118
|
+
<div data-each="items" data-each-key="name">
|
|
119
|
+
<div>
|
|
120
|
+
<span>{{name}}</span>
|
|
121
|
+
<button type="button" data-click-row-add>+</button>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</form>
|
|
125
125
|
`;
|
|
126
126
|
await Core.scan(container);
|
|
127
127
|
await waitForDomSettled();
|
|
@@ -134,15 +134,15 @@ describe('Row operations', () => {
|
|
|
134
134
|
expect(items.length).toBe(3);
|
|
135
135
|
});
|
|
136
136
|
it('should remove a row inside form (data-click-row-remove)', async () => {
|
|
137
|
-
container.innerHTML = `
|
|
138
|
-
<form data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
139
|
-
<div data-each="items" data-each-key="name">
|
|
140
|
-
<div>
|
|
141
|
-
<span>{{name}}</span>
|
|
142
|
-
<button type="button" data-click-row-remove>-</button>
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
</form>
|
|
137
|
+
container.innerHTML = `
|
|
138
|
+
<form data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
139
|
+
<div data-each="items" data-each-key="name">
|
|
140
|
+
<div>
|
|
141
|
+
<span>{{name}}</span>
|
|
142
|
+
<button type="button" data-click-row-remove>-</button>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</form>
|
|
146
146
|
`;
|
|
147
147
|
await Core.scan(container);
|
|
148
148
|
await waitForDomSettled();
|
|
@@ -160,15 +160,15 @@ describe('Row operations', () => {
|
|
|
160
160
|
expect(items[1].textContent).toBe('C');
|
|
161
161
|
});
|
|
162
162
|
it('should move row up inside form (data-click-row-prev)', async () => {
|
|
163
|
-
container.innerHTML = `
|
|
164
|
-
<form data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
165
|
-
<div data-each="items" data-each-key="name">
|
|
166
|
-
<div>
|
|
167
|
-
<span>{{name}}</span>
|
|
168
|
-
<button type="button" data-click-row-prev>↑</button>
|
|
169
|
-
</div>
|
|
170
|
-
</div>
|
|
171
|
-
</form>
|
|
163
|
+
container.innerHTML = `
|
|
164
|
+
<form data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
165
|
+
<div data-each="items" data-each-key="name">
|
|
166
|
+
<div>
|
|
167
|
+
<span>{{name}}</span>
|
|
168
|
+
<button type="button" data-click-row-prev>↑</button>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</form>
|
|
172
172
|
`;
|
|
173
173
|
await Core.scan(container);
|
|
174
174
|
await waitForDomSettled();
|
|
@@ -181,15 +181,15 @@ describe('Row operations', () => {
|
|
|
181
181
|
expect(items[2].textContent).toBe('B');
|
|
182
182
|
});
|
|
183
183
|
it('should move row down inside form (data-click-row-next)', async () => {
|
|
184
|
-
container.innerHTML = `
|
|
185
|
-
<form data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
186
|
-
<div data-each="items" data-each-key="name">
|
|
187
|
-
<div>
|
|
188
|
-
<span>{{name}}</span>
|
|
189
|
-
<button type="button" data-click-row-next>↓</button>
|
|
190
|
-
</div>
|
|
191
|
-
</div>
|
|
192
|
-
</form>
|
|
184
|
+
container.innerHTML = `
|
|
185
|
+
<form data-bind='{"items":[{"name":"A"},{"name":"B"},{"name":"C"}]}'>
|
|
186
|
+
<div data-each="items" data-each-key="name">
|
|
187
|
+
<div>
|
|
188
|
+
<span>{{name}}</span>
|
|
189
|
+
<button type="button" data-click-row-next>↓</button>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</form>
|
|
193
193
|
`;
|
|
194
194
|
await Core.scan(container);
|
|
195
195
|
await waitForDomSettled();
|
|
@@ -202,18 +202,18 @@ describe('Row operations', () => {
|
|
|
202
202
|
expect(items[2].textContent).toBe('B');
|
|
203
203
|
});
|
|
204
204
|
it('should handle multiple operations inside form', async () => {
|
|
205
|
-
container.innerHTML = `
|
|
206
|
-
<form data-bind='{"items":[{"name":"A"},{"name":"B"}]}'>
|
|
207
|
-
<div data-each="items" data-each-key="name">
|
|
208
|
-
<div>
|
|
209
|
-
<span>{{name}}</span>
|
|
210
|
-
<button type="button" data-click-row-add>+</button>
|
|
211
|
-
<button type="button" data-click-row-remove>-</button>
|
|
212
|
-
<button type="button" data-click-row-prev>↑</button>
|
|
213
|
-
<button type="button" data-click-row-next>↓</button>
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
216
|
-
</form>
|
|
205
|
+
container.innerHTML = `
|
|
206
|
+
<form data-bind='{"items":[{"name":"A"},{"name":"B"}]}'>
|
|
207
|
+
<div data-each="items" data-each-key="name">
|
|
208
|
+
<div>
|
|
209
|
+
<span>{{name}}</span>
|
|
210
|
+
<button type="button" data-click-row-add>+</button>
|
|
211
|
+
<button type="button" data-click-row-remove>-</button>
|
|
212
|
+
<button type="button" data-click-row-prev>↑</button>
|
|
213
|
+
<button type="button" data-click-row-next>↓</button>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</form>
|
|
217
217
|
`;
|
|
218
218
|
await Core.scan(container);
|
|
219
219
|
await waitForDomSettled();
|
package/package.json
CHANGED
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "haori",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A lightweight HTML-first UI engine powered by declarative data bindings and expressions.",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "vite",
|
|
7
|
-
"build": "vite build",
|
|
8
|
-
"dev:demo": "vite --config demo/vite.config.ts",
|
|
9
|
-
"build:demo": "vite build --config demo/vite.config.ts",
|
|
10
|
-
"preview:demo": "vite preview --config demo/vite.config.ts",
|
|
11
|
-
"test": "vitest run",
|
|
12
|
-
"test:watch": "vitest",
|
|
13
|
-
"lint": "eslint src",
|
|
14
|
-
"lint:fix": "eslint src --fix",
|
|
15
|
-
"format": "prettier --write src/**/*.{ts,js,json}",
|
|
16
|
-
"format:check": "prettier --check src/**/*.{ts,js,json}",
|
|
17
|
-
"type-check": "tsc --noEmit",
|
|
18
|
-
"preview": "vite preview",
|
|
19
|
-
"compile": "tsc",
|
|
20
|
-
"clean": "rm -rf dist",
|
|
21
|
-
"prepare": "npm run compile",
|
|
22
|
-
"pretest": "npm run compile",
|
|
23
|
-
"posttest": "npm run lint"
|
|
24
|
-
},
|
|
25
|
-
"repository": {
|
|
26
|
-
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/meibinlab/haori-js.git"
|
|
28
|
-
},
|
|
29
|
-
"keywords": [
|
|
30
|
-
"html",
|
|
31
|
-
"template",
|
|
32
|
-
"binding",
|
|
33
|
-
"ui-engine",
|
|
34
|
-
"no-javascript",
|
|
35
|
-
"dom",
|
|
36
|
-
"declarative",
|
|
37
|
-
"frontend"
|
|
38
|
-
],
|
|
39
|
-
"author": "meibinlab",
|
|
40
|
-
"license": "MIT",
|
|
41
|
-
"type": "module",
|
|
42
|
-
"exports": {
|
|
43
|
-
".": {
|
|
44
|
-
"import": "./dist/haori.js"
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"main": "dist/haori.es.js",
|
|
48
|
-
"types": "./dist/index.d.ts",
|
|
49
|
-
"files": [
|
|
50
|
-
"dist"
|
|
51
|
-
],
|
|
52
|
-
"bugs": {
|
|
53
|
-
"url": "https://github.com/meibinlab/haori-js/issues"
|
|
54
|
-
},
|
|
55
|
-
"homepage": "https://github.com/meibinlab/haori-js#readme",
|
|
56
|
-
"devDependencies": {
|
|
57
|
-
"@eslint/js": "^9.31.0",
|
|
58
|
-
"@playwright/test": "^1.57.0",
|
|
59
|
-
"@types/node": "^22.7.5",
|
|
60
|
-
"eslint": "^9.31.0",
|
|
61
|
-
"http-server": "^14.1.1",
|
|
62
|
-
"jsdom": "^26.1.0",
|
|
63
|
-
"prettier": "^3.6.2",
|
|
64
|
-
"typescript": "^5.6.3",
|
|
65
|
-
"typescript-eslint": "^8.37.0",
|
|
66
|
-
"vite": "^7.0.4",
|
|
67
|
-
"vite-plugin-dts": "^4.5.4",
|
|
68
|
-
"vitest": "^3.2.4"
|
|
69
|
-
}
|
|
70
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "haori",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "A lightweight HTML-first UI engine powered by declarative data bindings and expressions.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite",
|
|
7
|
+
"build": "vite build",
|
|
8
|
+
"dev:demo": "vite --config demo/vite.config.ts",
|
|
9
|
+
"build:demo": "vite build --config demo/vite.config.ts",
|
|
10
|
+
"preview:demo": "vite preview --config demo/vite.config.ts",
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"test:watch": "vitest",
|
|
13
|
+
"lint": "eslint src",
|
|
14
|
+
"lint:fix": "eslint src --fix",
|
|
15
|
+
"format": "prettier --write src/**/*.{ts,js,json}",
|
|
16
|
+
"format:check": "prettier --check src/**/*.{ts,js,json}",
|
|
17
|
+
"type-check": "tsc --noEmit",
|
|
18
|
+
"preview": "vite preview",
|
|
19
|
+
"compile": "tsc",
|
|
20
|
+
"clean": "rm -rf dist",
|
|
21
|
+
"prepare": "npm run compile",
|
|
22
|
+
"pretest": "npm run compile",
|
|
23
|
+
"posttest": "npm run lint"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/meibinlab/haori-js.git"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"html",
|
|
31
|
+
"template",
|
|
32
|
+
"binding",
|
|
33
|
+
"ui-engine",
|
|
34
|
+
"no-javascript",
|
|
35
|
+
"dom",
|
|
36
|
+
"declarative",
|
|
37
|
+
"frontend"
|
|
38
|
+
],
|
|
39
|
+
"author": "meibinlab",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"type": "module",
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"import": "./dist/haori.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"main": "dist/haori.es.js",
|
|
48
|
+
"types": "./dist/index.d.ts",
|
|
49
|
+
"files": [
|
|
50
|
+
"dist"
|
|
51
|
+
],
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/meibinlab/haori-js/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/meibinlab/haori-js#readme",
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@eslint/js": "^9.31.0",
|
|
58
|
+
"@playwright/test": "^1.57.0",
|
|
59
|
+
"@types/node": "^22.7.5",
|
|
60
|
+
"eslint": "^9.31.0",
|
|
61
|
+
"http-server": "^14.1.1",
|
|
62
|
+
"jsdom": "^26.1.0",
|
|
63
|
+
"prettier": "^3.6.2",
|
|
64
|
+
"typescript": "^5.6.3",
|
|
65
|
+
"typescript-eslint": "^8.37.0",
|
|
66
|
+
"vite": "^7.0.4",
|
|
67
|
+
"vite-plugin-dts": "^4.5.4",
|
|
68
|
+
"vitest": "^3.2.4"
|
|
69
|
+
}
|
|
70
|
+
}
|