haori 0.7.0 → 0.9.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.ja.md +15 -2
- package/README.md +15 -2
- package/dist/haori.cjs.js +11 -11
- package/dist/haori.cjs.js.map +1 -1
- package/dist/haori.es.js +760 -564
- package/dist/haori.es.js.map +1 -1
- package/dist/haori.iife.js +11 -11
- package/dist/haori.iife.js.map +1 -1
- package/dist/index.d.ts +118 -5
- package/dist/package.json +1 -1
- package/dist/src/core.d.ts +80 -1
- package/dist/src/core.d.ts.map +1 -1
- package/dist/src/core.js +184 -10
- package/dist/src/core.js.map +1 -1
- package/dist/src/event.d.ts +12 -0
- package/dist/src/event.d.ts.map +1 -1
- package/dist/src/event.js +14 -0
- package/dist/src/event.js.map +1 -1
- package/dist/src/form.d.ts +8 -3
- package/dist/src/form.d.ts.map +1 -1
- package/dist/src/form.js +11 -4
- package/dist/src/form.js.map +1 -1
- package/dist/src/haori.d.ts +12 -0
- package/dist/src/haori.d.ts.map +1 -1
- package/dist/src/haori.js +14 -0
- package/dist/src/haori.js.map +1 -1
- package/dist/src/index.d.ts +10 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/procedure.d.ts +5 -0
- package/dist/src/procedure.d.ts.map +1 -1
- package/dist/src/procedure.js +31 -5
- package/dist/src/procedure.js.map +1 -1
- package/dist/src/queue.d.ts +7 -0
- package/dist/src/queue.d.ts.map +1 -1
- package/dist/src/queue.js +52 -0
- package/dist/src/queue.js.map +1 -1
- package/dist/tests/bindcomplete-and-scope.test.d.ts +2 -0
- package/dist/tests/bindcomplete-and-scope.test.d.ts.map +1 -0
- package/dist/tests/bindcomplete-and-scope.test.js +115 -0
- package/dist/tests/bindcomplete-and-scope.test.js.map +1 -0
- package/dist/tests/click-no-disabled.test.d.ts +2 -0
- package/dist/tests/click-no-disabled.test.d.ts.map +1 -0
- package/dist/tests/click-no-disabled.test.js +67 -0
- package/dist/tests/click-no-disabled.test.js.map +1 -0
- package/dist/tests/data-bind-arg-reeval.test.d.ts +2 -0
- package/dist/tests/data-bind-arg-reeval.test.d.ts.map +1 -0
- package/dist/tests/data-bind-arg-reeval.test.js +119 -0
- package/dist/tests/data-bind-arg-reeval.test.js.map +1 -0
- package/dist/tests/data-bind-merge.test.d.ts +2 -0
- package/dist/tests/data-bind-merge.test.d.ts.map +1 -0
- package/dist/tests/data-bind-merge.test.js +86 -0
- package/dist/tests/data-bind-merge.test.js.map +1 -0
- package/dist/tests/data-form-container.test.d.ts +2 -0
- package/dist/tests/data-form-container.test.d.ts.map +1 -0
- package/dist/tests/data-form-container.test.js +87 -0
- package/dist/tests/data-form-container.test.js.map +1 -0
- package/dist/tests/data-if-falsy.test.d.ts +2 -0
- package/dist/tests/data-if-falsy.test.d.ts.map +1 -0
- package/dist/tests/data-if-falsy.test.js +73 -0
- package/dist/tests/data-if-falsy.test.js.map +1 -0
- package/dist/tests/data-load-on-show.test.d.ts +2 -0
- package/dist/tests/data-load-on-show.test.d.ts.map +1 -0
- package/dist/tests/data-load-on-show.test.js +98 -0
- package/dist/tests/data-load-on-show.test.js.map +1 -0
- package/dist/tests/each-update-event.test.d.ts +2 -0
- package/dist/tests/each-update-event.test.d.ts.map +1 -0
- package/dist/tests/each-update-event.test.js +83 -0
- package/dist/tests/each-update-event.test.js.map +1 -0
- package/dist/tests/render-wait.test.d.ts +2 -0
- package/dist/tests/render-wait.test.d.ts.map +1 -0
- package/dist/tests/render-wait.test.js +68 -0
- package/dist/tests/render-wait.test.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -66,6 +66,8 @@ export declare class Core {
|
|
|
66
66
|
private static readonly REACTIVE_IMPORT_STATES;
|
|
67
67
|
/** data-derive subtree skip の開発用プロファイル */
|
|
68
68
|
private static readonly DERIVE_SUBTREE_PROFILES;
|
|
69
|
+
/** data-each の差分更新の再入制御状態 */
|
|
70
|
+
private static readonly EACH_UPDATE_STATES;
|
|
69
71
|
/**
|
|
70
72
|
* 遅延属性かどうか(完全名で判定)を判定します。
|
|
71
73
|
*
|
|
@@ -217,6 +219,30 @@ export declare class Core {
|
|
|
217
219
|
* @returns Promise (DOM操作が完了したときに解決される)
|
|
218
220
|
*/
|
|
219
221
|
static setBindingData(element: HTMLElement, data: Record<string, unknown>, skipFragments?: ReadonlySet<ElementFragment>): Promise<void>;
|
|
222
|
+
/**
|
|
223
|
+
* 指定要素の式評価で見えるバインディングスコープをダンプします(デバッグ用)。
|
|
224
|
+
*
|
|
225
|
+
* 式(`data-if` / `{{...}}` など)の識別子は、その要素を起点に DOM のネストを
|
|
226
|
+
* たどって解決されます(内側のスコープが外側を上書き)。本メソッドは解決済みの
|
|
227
|
+
* スコープ(`resolved`)と、各キーがどの要素・どの種類(`bind` または `derive`)に
|
|
228
|
+
* 由来するか(`sources`)を返します。開発モード時はコンソールにも出力します。
|
|
229
|
+
*
|
|
230
|
+
* 注意: フォームの入力値(`name` 属性)は、変更(change)や明示的な同期が行われる
|
|
231
|
+
* までフォームの binding data に反映されません。したがって初期表示時点では、入力名と
|
|
232
|
+
* 同名の識別子は**外側のスコープ**にフォールバックして解決されます。
|
|
233
|
+
*
|
|
234
|
+
* @param element 対象要素
|
|
235
|
+
* @return 解決済みスコープと各キーの由来情報
|
|
236
|
+
*/
|
|
237
|
+
static dumpScope(element: HTMLElement): {
|
|
238
|
+
resolved: Record<string, unknown>;
|
|
239
|
+
sources: Record<string, {
|
|
240
|
+
value: unknown;
|
|
241
|
+
source: string;
|
|
242
|
+
kind: 'bind' | 'derive';
|
|
243
|
+
depth: number;
|
|
244
|
+
}>;
|
|
245
|
+
};
|
|
220
246
|
/**
|
|
221
247
|
* data-bind 属性の値をパースします。
|
|
222
248
|
*
|
|
@@ -283,21 +309,74 @@ export declare class Core {
|
|
|
283
309
|
* @returns Promise (DOM操作が完了したときに解決される)
|
|
284
310
|
*/
|
|
285
311
|
static evaluateText(fragment: TextFragment): Promise<void>;
|
|
312
|
+
/**
|
|
313
|
+
* data-if の評価値が「非表示」とみなされるかどうかを判定します。
|
|
314
|
+
*
|
|
315
|
+
* JavaScript の falsy 判定に準拠し、`false`・`null`・`undefined`・`NaN` に加えて
|
|
316
|
+
* `0`・空文字列 `''` も非表示とします(例: `data-if="items.length"` は要素数 0 で
|
|
317
|
+
* 非表示)。空配列 `[]` や空オブジェクト `{}` は JavaScript 同様 truthy なので表示されます。
|
|
318
|
+
*
|
|
319
|
+
* @param condition data-if の評価結果
|
|
320
|
+
* @return 非表示とみなす場合は true
|
|
321
|
+
*/
|
|
322
|
+
private static isHiddenIfCondition;
|
|
286
323
|
/**
|
|
287
324
|
* if要素を評価します。
|
|
288
|
-
* 値がfalse
|
|
325
|
+
* 値が falsy(false・null・undefined・NaN・0・空文字列)の場合は非表示にし、
|
|
326
|
+
* それ以外の場合は表示します。
|
|
289
327
|
*
|
|
290
328
|
* @param fragment 対象フラグメント
|
|
291
329
|
* @return Promise (DOM操作が完了したときに解決される)
|
|
292
330
|
*/
|
|
293
331
|
static evaluateIf(fragment: ElementFragment): Promise<void>;
|
|
332
|
+
/**
|
|
333
|
+
* data-if 表示時に data-load-* 手続きを発火します。
|
|
334
|
+
*
|
|
335
|
+
* 対象要素が data-load-* 属性を持つ場合のみ、load 種別の Procedure を1回実行します。
|
|
336
|
+
* 結果は待機せず(fire-and-forget)、表示処理の完了をブロックしません。
|
|
337
|
+
*
|
|
338
|
+
* @param fragment 対象フラグメント
|
|
339
|
+
* @return 戻り値はありません。
|
|
340
|
+
*/
|
|
341
|
+
private static triggerLoadOnShow;
|
|
342
|
+
/**
|
|
343
|
+
* data-each フラグメントの差分更新の再入制御状態を取得します。
|
|
344
|
+
*
|
|
345
|
+
* @param fragment 対象フラグメント
|
|
346
|
+
* @return 再入制御状態
|
|
347
|
+
*/
|
|
348
|
+
private static getEachUpdateState;
|
|
294
349
|
/**
|
|
295
350
|
* each要素を評価します。
|
|
296
351
|
* 非表示または未マウントの場合は処理をスキップします。
|
|
297
352
|
*
|
|
353
|
+
* 同一フラグメントに対する差分更新が並行・再入しないように直列化します。
|
|
354
|
+
* 実行中に再度呼び出された場合は再評価要求を記録し、現在進行中の更新の完了
|
|
355
|
+
* Promise(後続の再実行も含む)を返します。これにより、bind 直後のリアクティブ
|
|
356
|
+
* 再評価が重なっても data-each の描画が破壊されず、かつ呼び出し元(`evaluateAll`→
|
|
357
|
+
* `setBindingData`→`haori:bindcomplete`)が**最終的な DOM 反映まで確実に待機**できます。
|
|
358
|
+
*
|
|
298
359
|
* @param fragment 対象フラグメント
|
|
360
|
+
* @return 差分更新(再実行を含む)の完了 Promise
|
|
299
361
|
*/
|
|
300
362
|
static evaluateEach(fragment: ElementFragment): Promise<void>;
|
|
363
|
+
/**
|
|
364
|
+
* data-each の差分更新を、再評価要求が無くなるまで直列に繰り返し実行します。
|
|
365
|
+
* 進行中・後続の再実行を含む完了 Promise を state に保持し、再入した呼び出し元が
|
|
366
|
+
* 同じ Promise を待てるようにします。
|
|
367
|
+
*
|
|
368
|
+
* @param fragment 対象フラグメント
|
|
369
|
+
* @param state 再入制御状態
|
|
370
|
+
* @return すべての差分更新が安定するまでの完了 Promise
|
|
371
|
+
*/
|
|
372
|
+
private static runEachUpdateLoop;
|
|
373
|
+
/**
|
|
374
|
+
* data-each の差分更新本体を実行します(再入制御は呼び出し側で行います)。
|
|
375
|
+
*
|
|
376
|
+
* @param fragment 対象フラグメント
|
|
377
|
+
* @return 差分更新完了の Promise
|
|
378
|
+
*/
|
|
379
|
+
private static performEachUpdate;
|
|
301
380
|
/**
|
|
302
381
|
* data-each 属性値を仕様に従って配列へ正規化します。
|
|
303
382
|
*
|
|
@@ -1042,10 +1121,15 @@ export declare class Form {
|
|
|
1042
1121
|
*/
|
|
1043
1122
|
private static findFragmentByKeyParts;
|
|
1044
1123
|
/**
|
|
1045
|
-
*
|
|
1046
|
-
*
|
|
1124
|
+
* 対象のフラグメントがフォームコンテナであればそれを返し、
|
|
1125
|
+
* そうでなければ先祖要素をたどってフォームコンテナを探します。
|
|
1126
|
+
*
|
|
1127
|
+
* フォームコンテナは `<form>` 要素、または `data-form` 属性を持つ任意の要素です。
|
|
1128
|
+
* 後者は `<table>` 内など `<form>` を直接置けない箇所で、`<tr>` などを値収集の
|
|
1129
|
+
* コンテナとして扱うために使用します(`data-click-form` 等が対象を探す際に利用)。
|
|
1047
1130
|
*
|
|
1048
|
-
* @param fragment
|
|
1131
|
+
* @param fragment 探索の起点フラグメント
|
|
1132
|
+
* @returns フォームコンテナのフラグメント。見つからなければ null
|
|
1049
1133
|
*/
|
|
1050
1134
|
static getFormFragment(fragment: ElementFragment): ElementFragment | null;
|
|
1051
1135
|
}
|
|
@@ -1161,6 +1245,18 @@ declare class Haori {
|
|
|
1161
1245
|
* @return 戻り値はありません。
|
|
1162
1246
|
*/
|
|
1163
1247
|
static setRuntime(runtime: string): void;
|
|
1248
|
+
/**
|
|
1249
|
+
* 進行中・追従して投入されるものを含め、すべてのレンダリングタスクの完了を待ちます。
|
|
1250
|
+
*
|
|
1251
|
+
* `data-each` の大量行のように複数フレームに分割される描画でも、安定して完了する
|
|
1252
|
+
* まで待機します。Playwright などの外部テストから、タブ切り替えやクリック後に
|
|
1253
|
+
* 描画完了を安全に待機するために利用できます。
|
|
1254
|
+
*
|
|
1255
|
+
* 例: `await page.evaluate(() => Haori.waitForRenders())`
|
|
1256
|
+
*
|
|
1257
|
+
* @return すべてのレンダリングが完了したら解決される Promise
|
|
1258
|
+
*/
|
|
1259
|
+
static waitForRenders(): Promise<void>;
|
|
1164
1260
|
/**
|
|
1165
1261
|
* 通知ダイアログを表示します。
|
|
1166
1262
|
*
|
|
@@ -1288,6 +1384,13 @@ export declare class Queue {
|
|
|
1288
1384
|
* 全てのキュー処理が完了するまで待機します。
|
|
1289
1385
|
*/
|
|
1290
1386
|
static wait(): Promise<void>;
|
|
1387
|
+
/**
|
|
1388
|
+
* レンダリング(追従して投入されるタスクを含む)が安定して完了するまで待機します。
|
|
1389
|
+
*
|
|
1390
|
+
* @param maxIterations 無限ループ防止の最大反復回数
|
|
1391
|
+
* @returns レンダリングが安定するまで解決されない Promise
|
|
1392
|
+
*/
|
|
1393
|
+
static waitForIdle(maxIterations?: number): Promise<void>;
|
|
1291
1394
|
}
|
|
1292
1395
|
|
|
1293
1396
|
/**
|
|
@@ -1343,6 +1446,16 @@ declare class TextFragment extends Fragment {
|
|
|
1343
1446
|
evaluate(): Promise<void>;
|
|
1344
1447
|
}
|
|
1345
1448
|
|
|
1346
|
-
export declare const version = "0.
|
|
1449
|
+
export declare const version = "0.9.0";
|
|
1450
|
+
|
|
1451
|
+
/**
|
|
1452
|
+
* すべてのレンダリングタスク(追従投入分を含む)の完了を待ちます。
|
|
1453
|
+
*
|
|
1454
|
+
* iife グローバルからは `Haori.waitForRenders()`、ESM では
|
|
1455
|
+
* `import {waitForRenders} from 'haori'` で利用できます。
|
|
1456
|
+
*
|
|
1457
|
+
* @return すべてのレンダリングが完了したら解決される Promise
|
|
1458
|
+
*/
|
|
1459
|
+
export declare const waitForRenders: () => Promise<void>;
|
|
1347
1460
|
|
|
1348
1461
|
export { }
|
package/dist/package.json
CHANGED
package/dist/src/core.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export default class Core {
|
|
|
20
20
|
private static readonly REACTIVE_IMPORT_STATES;
|
|
21
21
|
/** data-derive subtree skip の開発用プロファイル */
|
|
22
22
|
private static readonly DERIVE_SUBTREE_PROFILES;
|
|
23
|
+
/** data-each の差分更新の再入制御状態 */
|
|
24
|
+
private static readonly EACH_UPDATE_STATES;
|
|
23
25
|
/**
|
|
24
26
|
* 遅延属性かどうか(完全名で判定)を判定します。
|
|
25
27
|
*
|
|
@@ -171,6 +173,30 @@ export default class Core {
|
|
|
171
173
|
* @returns Promise (DOM操作が完了したときに解決される)
|
|
172
174
|
*/
|
|
173
175
|
static setBindingData(element: HTMLElement, data: Record<string, unknown>, skipFragments?: ReadonlySet<ElementFragment>): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* 指定要素の式評価で見えるバインディングスコープをダンプします(デバッグ用)。
|
|
178
|
+
*
|
|
179
|
+
* 式(`data-if` / `{{...}}` など)の識別子は、その要素を起点に DOM のネストを
|
|
180
|
+
* たどって解決されます(内側のスコープが外側を上書き)。本メソッドは解決済みの
|
|
181
|
+
* スコープ(`resolved`)と、各キーがどの要素・どの種類(`bind` または `derive`)に
|
|
182
|
+
* 由来するか(`sources`)を返します。開発モード時はコンソールにも出力します。
|
|
183
|
+
*
|
|
184
|
+
* 注意: フォームの入力値(`name` 属性)は、変更(change)や明示的な同期が行われる
|
|
185
|
+
* までフォームの binding data に反映されません。したがって初期表示時点では、入力名と
|
|
186
|
+
* 同名の識別子は**外側のスコープ**にフォールバックして解決されます。
|
|
187
|
+
*
|
|
188
|
+
* @param element 対象要素
|
|
189
|
+
* @return 解決済みスコープと各キーの由来情報
|
|
190
|
+
*/
|
|
191
|
+
static dumpScope(element: HTMLElement): {
|
|
192
|
+
resolved: Record<string, unknown>;
|
|
193
|
+
sources: Record<string, {
|
|
194
|
+
value: unknown;
|
|
195
|
+
source: string;
|
|
196
|
+
kind: 'bind' | 'derive';
|
|
197
|
+
depth: number;
|
|
198
|
+
}>;
|
|
199
|
+
};
|
|
174
200
|
/**
|
|
175
201
|
* data-bind 属性の値をパースします。
|
|
176
202
|
*
|
|
@@ -237,21 +263,74 @@ export default class Core {
|
|
|
237
263
|
* @returns Promise (DOM操作が完了したときに解決される)
|
|
238
264
|
*/
|
|
239
265
|
static evaluateText(fragment: TextFragment): Promise<void>;
|
|
266
|
+
/**
|
|
267
|
+
* data-if の評価値が「非表示」とみなされるかどうかを判定します。
|
|
268
|
+
*
|
|
269
|
+
* JavaScript の falsy 判定に準拠し、`false`・`null`・`undefined`・`NaN` に加えて
|
|
270
|
+
* `0`・空文字列 `''` も非表示とします(例: `data-if="items.length"` は要素数 0 で
|
|
271
|
+
* 非表示)。空配列 `[]` や空オブジェクト `{}` は JavaScript 同様 truthy なので表示されます。
|
|
272
|
+
*
|
|
273
|
+
* @param condition data-if の評価結果
|
|
274
|
+
* @return 非表示とみなす場合は true
|
|
275
|
+
*/
|
|
276
|
+
private static isHiddenIfCondition;
|
|
240
277
|
/**
|
|
241
278
|
* if要素を評価します。
|
|
242
|
-
* 値がfalse
|
|
279
|
+
* 値が falsy(false・null・undefined・NaN・0・空文字列)の場合は非表示にし、
|
|
280
|
+
* それ以外の場合は表示します。
|
|
243
281
|
*
|
|
244
282
|
* @param fragment 対象フラグメント
|
|
245
283
|
* @return Promise (DOM操作が完了したときに解決される)
|
|
246
284
|
*/
|
|
247
285
|
static evaluateIf(fragment: ElementFragment): Promise<void>;
|
|
286
|
+
/**
|
|
287
|
+
* data-if 表示時に data-load-* 手続きを発火します。
|
|
288
|
+
*
|
|
289
|
+
* 対象要素が data-load-* 属性を持つ場合のみ、load 種別の Procedure を1回実行します。
|
|
290
|
+
* 結果は待機せず(fire-and-forget)、表示処理の完了をブロックしません。
|
|
291
|
+
*
|
|
292
|
+
* @param fragment 対象フラグメント
|
|
293
|
+
* @return 戻り値はありません。
|
|
294
|
+
*/
|
|
295
|
+
private static triggerLoadOnShow;
|
|
296
|
+
/**
|
|
297
|
+
* data-each フラグメントの差分更新の再入制御状態を取得します。
|
|
298
|
+
*
|
|
299
|
+
* @param fragment 対象フラグメント
|
|
300
|
+
* @return 再入制御状態
|
|
301
|
+
*/
|
|
302
|
+
private static getEachUpdateState;
|
|
248
303
|
/**
|
|
249
304
|
* each要素を評価します。
|
|
250
305
|
* 非表示または未マウントの場合は処理をスキップします。
|
|
251
306
|
*
|
|
307
|
+
* 同一フラグメントに対する差分更新が並行・再入しないように直列化します。
|
|
308
|
+
* 実行中に再度呼び出された場合は再評価要求を記録し、現在進行中の更新の完了
|
|
309
|
+
* Promise(後続の再実行も含む)を返します。これにより、bind 直後のリアクティブ
|
|
310
|
+
* 再評価が重なっても data-each の描画が破壊されず、かつ呼び出し元(`evaluateAll`→
|
|
311
|
+
* `setBindingData`→`haori:bindcomplete`)が**最終的な DOM 反映まで確実に待機**できます。
|
|
312
|
+
*
|
|
252
313
|
* @param fragment 対象フラグメント
|
|
314
|
+
* @return 差分更新(再実行を含む)の完了 Promise
|
|
253
315
|
*/
|
|
254
316
|
static evaluateEach(fragment: ElementFragment): Promise<void>;
|
|
317
|
+
/**
|
|
318
|
+
* data-each の差分更新を、再評価要求が無くなるまで直列に繰り返し実行します。
|
|
319
|
+
* 進行中・後続の再実行を含む完了 Promise を state に保持し、再入した呼び出し元が
|
|
320
|
+
* 同じ Promise を待てるようにします。
|
|
321
|
+
*
|
|
322
|
+
* @param fragment 対象フラグメント
|
|
323
|
+
* @param state 再入制御状態
|
|
324
|
+
* @return すべての差分更新が安定するまでの完了 Promise
|
|
325
|
+
*/
|
|
326
|
+
private static runEachUpdateLoop;
|
|
327
|
+
/**
|
|
328
|
+
* data-each の差分更新本体を実行します(再入制御は呼び出し側で行います)。
|
|
329
|
+
*
|
|
330
|
+
* @param fragment 対象フラグメント
|
|
331
|
+
* @return 差分更新完了の Promise
|
|
332
|
+
*/
|
|
333
|
+
private static performEachUpdate;
|
|
255
334
|
/**
|
|
256
335
|
* data-each 属性値を仕様に従って配列へ正規化します。
|
|
257
336
|
*
|
package/dist/src/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"AAUA,OAAiB,EAAC,eAAe,EAAE,YAAY,EAAC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/src/core.js
CHANGED
|
@@ -411,10 +411,7 @@ class Core {
|
|
|
411
411
|
static shouldSkipChildInitialization(fragment, stopAtEach) {
|
|
412
412
|
const condition = fragment.getAttribute(`${Env.prefix}if`);
|
|
413
413
|
if (fragment.hasAttribute(`${Env.prefix}if`) &&
|
|
414
|
-
(condition
|
|
415
|
-
condition === undefined ||
|
|
416
|
-
condition === null ||
|
|
417
|
-
Number.isNaN(condition))) {
|
|
414
|
+
Core.isHiddenIfCondition(condition)) {
|
|
418
415
|
return true;
|
|
419
416
|
}
|
|
420
417
|
return stopAtEach && fragment.hasAttribute(`${Env.prefix}each`);
|
|
@@ -541,6 +538,67 @@ class Core {
|
|
|
541
538
|
HaoriEvent.bindChange(element, previous, data, 'manual');
|
|
542
539
|
return chain.then(() => undefined);
|
|
543
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* 指定要素の式評価で見えるバインディングスコープをダンプします(デバッグ用)。
|
|
543
|
+
*
|
|
544
|
+
* 式(`data-if` / `{{...}}` など)の識別子は、その要素を起点に DOM のネストを
|
|
545
|
+
* たどって解決されます(内側のスコープが外側を上書き)。本メソッドは解決済みの
|
|
546
|
+
* スコープ(`resolved`)と、各キーがどの要素・どの種類(`bind` または `derive`)に
|
|
547
|
+
* 由来するか(`sources`)を返します。開発モード時はコンソールにも出力します。
|
|
548
|
+
*
|
|
549
|
+
* 注意: フォームの入力値(`name` 属性)は、変更(change)や明示的な同期が行われる
|
|
550
|
+
* までフォームの binding data に反映されません。したがって初期表示時点では、入力名と
|
|
551
|
+
* 同名の識別子は**外側のスコープ**にフォールバックして解決されます。
|
|
552
|
+
*
|
|
553
|
+
* @param element 対象要素
|
|
554
|
+
* @return 解決済みスコープと各キーの由来情報
|
|
555
|
+
*/
|
|
556
|
+
static dumpScope(element) {
|
|
557
|
+
const fragment = Fragment.get(element);
|
|
558
|
+
if (!fragment) {
|
|
559
|
+
return { resolved: {}, sources: {} };
|
|
560
|
+
}
|
|
561
|
+
const resolved = fragment.getBindingData();
|
|
562
|
+
const sources = {};
|
|
563
|
+
const describe = (frag) => {
|
|
564
|
+
const target = frag.getTarget();
|
|
565
|
+
if (target.id) {
|
|
566
|
+
return `#${target.id}`;
|
|
567
|
+
}
|
|
568
|
+
return target.tagName.toLowerCase();
|
|
569
|
+
};
|
|
570
|
+
const record = (data, frag, kind, depth) => {
|
|
571
|
+
if (!data) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
for (const key of Object.keys(data)) {
|
|
575
|
+
if (!(key in sources)) {
|
|
576
|
+
sources[key] = {
|
|
577
|
+
value: data[key],
|
|
578
|
+
source: describe(frag),
|
|
579
|
+
kind,
|
|
580
|
+
depth,
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
let current = fragment;
|
|
586
|
+
let depth = 0;
|
|
587
|
+
while (current) {
|
|
588
|
+
// 子孫から見ると derive は同要素の bind より優先されるため derive を先に記録する。
|
|
589
|
+
// ただし起点要素自身の derive は自身のスコープには現れない(子孫にのみ公開)。
|
|
590
|
+
if (current !== fragment) {
|
|
591
|
+
record(current.getRawDerivedBindingData(), current, 'derive', depth);
|
|
592
|
+
}
|
|
593
|
+
record(current.getRawBindingData(), current, 'bind', depth);
|
|
594
|
+
current = current.getParent();
|
|
595
|
+
depth += 1;
|
|
596
|
+
}
|
|
597
|
+
if (Dev.isEnabled()) {
|
|
598
|
+
Log.info('[Haori]', 'scope dump for', element, { resolved, sources });
|
|
599
|
+
}
|
|
600
|
+
return { resolved, sources };
|
|
601
|
+
}
|
|
544
602
|
/**
|
|
545
603
|
* data-bind 属性の値をパースします。
|
|
546
604
|
*
|
|
@@ -827,9 +885,23 @@ class Core {
|
|
|
827
885
|
static evaluateText(fragment) {
|
|
828
886
|
return fragment.evaluate();
|
|
829
887
|
}
|
|
888
|
+
/**
|
|
889
|
+
* data-if の評価値が「非表示」とみなされるかどうかを判定します。
|
|
890
|
+
*
|
|
891
|
+
* JavaScript の falsy 判定に準拠し、`false`・`null`・`undefined`・`NaN` に加えて
|
|
892
|
+
* `0`・空文字列 `''` も非表示とします(例: `data-if="items.length"` は要素数 0 で
|
|
893
|
+
* 非表示)。空配列 `[]` や空オブジェクト `{}` は JavaScript 同様 truthy なので表示されます。
|
|
894
|
+
*
|
|
895
|
+
* @param condition data-if の評価結果
|
|
896
|
+
* @return 非表示とみなす場合は true
|
|
897
|
+
*/
|
|
898
|
+
static isHiddenIfCondition(condition) {
|
|
899
|
+
return !condition;
|
|
900
|
+
}
|
|
830
901
|
/**
|
|
831
902
|
* if要素を評価します。
|
|
832
|
-
* 値がfalse
|
|
903
|
+
* 値が falsy(false・null・undefined・NaN・0・空文字列)の場合は非表示にし、
|
|
904
|
+
* それ以外の場合は表示します。
|
|
833
905
|
*
|
|
834
906
|
* @param fragment 対象フラグメント
|
|
835
907
|
* @return Promise (DOM操作が完了したときに解決される)
|
|
@@ -837,15 +909,14 @@ class Core {
|
|
|
837
909
|
static evaluateIf(fragment) {
|
|
838
910
|
const promises = [];
|
|
839
911
|
const condition = fragment.getAttribute(`${Env.prefix}if`);
|
|
840
|
-
if (condition
|
|
841
|
-
condition === undefined ||
|
|
842
|
-
condition === null ||
|
|
843
|
-
Number.isNaN(condition)) {
|
|
912
|
+
if (Core.isHiddenIfCondition(condition)) {
|
|
844
913
|
promises.push(fragment.hide().then(() => {
|
|
845
914
|
HaoriEvent.hide(fragment.getTarget());
|
|
846
915
|
}));
|
|
847
916
|
}
|
|
848
917
|
else {
|
|
918
|
+
// 非表示→表示への遷移を検出するため、show() 前の表示状態を退避する。
|
|
919
|
+
const wasVisible = fragment.isVisible();
|
|
849
920
|
const childPromises = [];
|
|
850
921
|
fragment.getChildren().forEach(child => {
|
|
851
922
|
if (child instanceof ElementFragment) {
|
|
@@ -860,21 +931,118 @@ class Core {
|
|
|
860
931
|
});
|
|
861
932
|
promises.push(fragment.show().then(() => {
|
|
862
933
|
HaoriEvent.show(fragment.getTarget());
|
|
934
|
+
// 非表示→表示へ遷移したときだけ data-load-* を発火する。
|
|
935
|
+
// ボタンや div などネイティブの load イベントが発生しない要素でも、
|
|
936
|
+
// data-if による表示(haori:show)を契機に data-load-* を実行できるようにする。
|
|
937
|
+
// 毎回の再評価で発火させると無限ループや過剰実行を招くため、遷移時に限定する。
|
|
938
|
+
if (!wasVisible) {
|
|
939
|
+
Core.triggerLoadOnShow(fragment);
|
|
940
|
+
}
|
|
863
941
|
}));
|
|
864
942
|
promises.push(Promise.all(childPromises).then(() => undefined));
|
|
865
943
|
}
|
|
866
944
|
return Promise.all(promises).then(() => undefined);
|
|
867
945
|
}
|
|
946
|
+
/**
|
|
947
|
+
* data-if 表示時に data-load-* 手続きを発火します。
|
|
948
|
+
*
|
|
949
|
+
* 対象要素が data-load-* 属性を持つ場合のみ、load 種別の Procedure を1回実行します。
|
|
950
|
+
* 結果は待機せず(fire-and-forget)、表示処理の完了をブロックしません。
|
|
951
|
+
*
|
|
952
|
+
* @param fragment 対象フラグメント
|
|
953
|
+
* @return 戻り値はありません。
|
|
954
|
+
*/
|
|
955
|
+
static triggerLoadOnShow(fragment) {
|
|
956
|
+
const loadPrefix = `${Env.prefix}load-`;
|
|
957
|
+
const hasLoadAttribute = fragment
|
|
958
|
+
.getTarget()
|
|
959
|
+
.getAttributeNames()
|
|
960
|
+
.some(name => name.startsWith(loadPrefix));
|
|
961
|
+
if (!hasLoadAttribute) {
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
void new Procedure(fragment, 'load').run().catch(error => {
|
|
965
|
+
Log.error('[Haori]', 'data-load procedure error (on show):', error);
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* data-each フラグメントの差分更新の再入制御状態を取得します。
|
|
970
|
+
*
|
|
971
|
+
* @param fragment 対象フラグメント
|
|
972
|
+
* @return 再入制御状態
|
|
973
|
+
*/
|
|
974
|
+
static getEachUpdateState(fragment) {
|
|
975
|
+
let state = Core.EACH_UPDATE_STATES.get(fragment);
|
|
976
|
+
if (!state) {
|
|
977
|
+
state = { running: false, rerunRequested: false, settled: null };
|
|
978
|
+
Core.EACH_UPDATE_STATES.set(fragment, state);
|
|
979
|
+
}
|
|
980
|
+
return state;
|
|
981
|
+
}
|
|
868
982
|
/**
|
|
869
983
|
* each要素を評価します。
|
|
870
984
|
* 非表示または未マウントの場合は処理をスキップします。
|
|
871
985
|
*
|
|
986
|
+
* 同一フラグメントに対する差分更新が並行・再入しないように直列化します。
|
|
987
|
+
* 実行中に再度呼び出された場合は再評価要求を記録し、現在進行中の更新の完了
|
|
988
|
+
* Promise(後続の再実行も含む)を返します。これにより、bind 直後のリアクティブ
|
|
989
|
+
* 再評価が重なっても data-each の描画が破壊されず、かつ呼び出し元(`evaluateAll`→
|
|
990
|
+
* `setBindingData`→`haori:bindcomplete`)が**最終的な DOM 反映まで確実に待機**できます。
|
|
991
|
+
*
|
|
872
992
|
* @param fragment 対象フラグメント
|
|
993
|
+
* @return 差分更新(再実行を含む)の完了 Promise
|
|
873
994
|
*/
|
|
874
995
|
static evaluateEach(fragment) {
|
|
875
996
|
if (!fragment.isVisible() || !fragment.isMounted()) {
|
|
876
997
|
return Promise.resolve();
|
|
877
998
|
}
|
|
999
|
+
const state = Core.getEachUpdateState(fragment);
|
|
1000
|
+
if (state.running) {
|
|
1001
|
+
// 実行中は再評価要求を記録し、進行中の settle Promise を待つ
|
|
1002
|
+
// (最新データの描画完了まで待てるようにする)。
|
|
1003
|
+
state.rerunRequested = true;
|
|
1004
|
+
return state.settled ?? Promise.resolve();
|
|
1005
|
+
}
|
|
1006
|
+
return Core.runEachUpdateLoop(fragment, state);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* data-each の差分更新を、再評価要求が無くなるまで直列に繰り返し実行します。
|
|
1010
|
+
* 進行中・後続の再実行を含む完了 Promise を state に保持し、再入した呼び出し元が
|
|
1011
|
+
* 同じ Promise を待てるようにします。
|
|
1012
|
+
*
|
|
1013
|
+
* @param fragment 対象フラグメント
|
|
1014
|
+
* @param state 再入制御状態
|
|
1015
|
+
* @return すべての差分更新が安定するまでの完了 Promise
|
|
1016
|
+
*/
|
|
1017
|
+
static runEachUpdateLoop(fragment, state) {
|
|
1018
|
+
state.running = true;
|
|
1019
|
+
// 新しい描画サイクルの開始時に完了マーカーを外す。
|
|
1020
|
+
fragment.getTarget().removeAttribute(`${Env.prefix}each-done`);
|
|
1021
|
+
const settled = (async () => {
|
|
1022
|
+
try {
|
|
1023
|
+
do {
|
|
1024
|
+
state.rerunRequested = false;
|
|
1025
|
+
await Core.performEachUpdate(fragment);
|
|
1026
|
+
} while (state.rerunRequested);
|
|
1027
|
+
// 全行の描画が安定して完了したことを示すマーカーを付与する。
|
|
1028
|
+
// 外部テストは `[data-each-done]` を待機して描画完了を検知できる。
|
|
1029
|
+
fragment.getTarget().setAttribute(`${Env.prefix}each-done`, '');
|
|
1030
|
+
}
|
|
1031
|
+
finally {
|
|
1032
|
+
state.running = false;
|
|
1033
|
+
state.settled = null;
|
|
1034
|
+
}
|
|
1035
|
+
})();
|
|
1036
|
+
state.settled = settled;
|
|
1037
|
+
return settled;
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* data-each の差分更新本体を実行します(再入制御は呼び出し側で行います)。
|
|
1041
|
+
*
|
|
1042
|
+
* @param fragment 対象フラグメント
|
|
1043
|
+
* @return 差分更新完了の Promise
|
|
1044
|
+
*/
|
|
1045
|
+
static performEachUpdate(fragment) {
|
|
878
1046
|
const data = Core.resolveEachItems(fragment);
|
|
879
1047
|
if (data === null) {
|
|
880
1048
|
return Promise.reject(new Error('Invalid each attribute.'));
|
|
@@ -1331,7 +1499,11 @@ class Core {
|
|
|
1331
1499
|
return Promise.all(removalPromises)
|
|
1332
1500
|
.then(() => chain)
|
|
1333
1501
|
.then(() => {
|
|
1334
|
-
// eachupdate
|
|
1502
|
+
// eachupdate イベントを発火する。
|
|
1503
|
+
// chain は全新規行の initializeFreshEachRow(= 行内容の描画)完了まで await
|
|
1504
|
+
// しているため、本イベントは「今回の差分で追加・削除・並べ替えされた全行が
|
|
1505
|
+
// DOM に反映され、各行の {{...}} 補間などの内容描画が完了した後」に発火する。
|
|
1506
|
+
// これにより外部から data-each の描画完了を検知できる(仕様上の保証)。
|
|
1335
1507
|
const validNewKeys = newKeys.filter((key) => key !== null);
|
|
1336
1508
|
const validSrcKeys = srcKeys.filter((key) => key !== null);
|
|
1337
1509
|
const validSrcKeySet = new Set(validSrcKeys);
|
|
@@ -1560,5 +1732,7 @@ Core.REACTIVE_FETCH_STATES = new WeakMap();
|
|
|
1560
1732
|
Core.REACTIVE_IMPORT_STATES = new WeakMap();
|
|
1561
1733
|
/** data-derive subtree skip の開発用プロファイル */
|
|
1562
1734
|
Core.DERIVE_SUBTREE_PROFILES = new WeakMap();
|
|
1735
|
+
/** data-each の差分更新の再入制御状態 */
|
|
1736
|
+
Core.EACH_UPDATE_STATES = new WeakMap();
|
|
1563
1737
|
export default Core;
|
|
1564
1738
|
//# sourceMappingURL=core.js.map
|