targetj 1.0.231 → 1.0.233
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 +143 -116
- package/build/LocationManager.js +1 -0
- package/build/PageManager.js +39 -28
- package/build/RunScheduler.js +87 -23
- package/build/TModelManager.js +10 -5
- package/build/TUtil.js +12 -1
- package/build/TargetUtil.js +33 -20
- package/build/Viewport.js +6 -0
- package/dist/targetjs.js +1 -1
- package/dist/targetjs.js.gz +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
# TargetJS: State as Destination,
|
|
1
|
+
# TargetJS: State as Destination, Code Order as UI Sequence
|
|
2
2
|
|
|
3
3
|
**[targetjs.io](https://targetjs.io)**
|
|
4
4
|
[](https://github.com/livetrails/targetjs/blob/main/LICENSE)
|
|
5
5
|
[](https://github.com/livetrails/targetjs/stargazers)
|
|
6
6
|
[](https://www.npmjs.com/package/targetj)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Most frameworks are great at rendering the next state. TargetJS is designed for the journey between states.
|
|
9
|
+
|
|
10
|
+
TargetJS is a JavaScript UI framework that replaces the "State → Render" model with "State → transition → Render". It also lets code order directly define the UI sequence. It unifies UI, animations, API calls, event handling, and state into self-contained "Targets" that stack together like intelligent Lego pieces using Code-Ordered Reactivity.
|
|
9
11
|
|
|
10
12
|
It can be used as a full-featured framework or as a lightweight library alongside other frameworks. It is also a highly performant web framework, as shown in the [framework benchmark](https://krausest.github.io/js-framework-benchmark/current.html).
|
|
11
13
|
|
|
@@ -36,6 +38,14 @@ TargetJS code order and target reactivity allow the implementation to more close
|
|
|
36
38
|
|
|
37
39
|
With its compact style, TargetJS makes the journey from A → B explicit and efficient, with significantly less code than traditional frameworks.
|
|
38
40
|
|
|
41
|
+
## 🚀 Why TargetJS?
|
|
42
|
+
|
|
43
|
+
1. Unified State: State isn't "elsewhere". It is built into every Target.
|
|
44
|
+
2. Animation by Default: High-performance animations are baked into the logic.
|
|
45
|
+
3. Ultra-Compact: Write 30% to 70% less code than standard frameworks.
|
|
46
|
+
4. UI as Sequence: Code describes the UI story from top to bottom, exactly how the user experiences the interaction: "When this finishes, do that."
|
|
47
|
+
5. Zero Boilerplate Async: Targets can handle waiting for asynchronous operations automatically.
|
|
48
|
+
|
|
39
49
|
## ⚡ Quick Start (30 Seconds)
|
|
40
50
|
|
|
41
51
|
**1. Install**
|
|
@@ -65,18 +75,21 @@ App({
|
|
|
65
75
|
In TargetJS, targets are the fundamental unit of behavior instead of methods.
|
|
66
76
|
Methods and properties both are internally transformed into targets that the framework schedules and executes.
|
|
67
77
|
|
|
78
|
+
### Mental Model
|
|
68
79
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
A target can:
|
|
81
|
+
- execute a method
|
|
82
|
+
- hold a value
|
|
83
|
+
- move toward that value over time
|
|
84
|
+
- wait for previous targets
|
|
85
|
+
- react when previous targets update
|
|
86
|
+
- fetch data
|
|
87
|
+
- react to an event
|
|
88
|
+
- create children
|
|
89
|
+
- run callbacks
|
|
90
|
+
- control its own lifecycle
|
|
79
91
|
|
|
92
|
+
This lets UI code follow the same order as the user experience.
|
|
80
93
|
|
|
81
94
|
### Target Controls
|
|
82
95
|
|
|
@@ -94,10 +107,24 @@ A target can also be defined as an object with optional controls that manage its
|
|
|
94
107
|
| `easing` | Predefined easing function controlling how values update over steps. |
|
|
95
108
|
| `onComplete` | Callback triggered when this target (and its children) finishes. |
|
|
96
109
|
| `onValueChange` | Callback triggered when the target emits a new value. |
|
|
110
|
+
| `onChange` | Callback triggered when the target emits a new value. |
|
|
111
|
+
| `on<PropertyName>Step` | Callback triggered on every step of a specific property. |
|
|
112
|
+
|
|
113
|
+
### Compact Execution Syntax
|
|
114
|
+
|
|
115
|
+
Target names can include special symbols that define when they execute. This provides a compact alternative to implementing the same behavior with callbacks.
|
|
116
|
+
|
|
117
|
+
| Symbol | Name | Behavior |
|
|
118
|
+
|------|------|------|
|
|
119
|
+
| `name` | Standard | Runs immediately in the order it appears. |
|
|
120
|
+
| `name$` | Reactive | Runs every time the previous sibling target updates. Equivalent to using `on<PropertyName>Step()` or `onValueChange()` to activate the next target . |
|
|
121
|
+
| `name$$` | Deferred | Runs only after the entire preceding target chain, including children, animations, and API calls, completes. Equivalent to using `onComplete()` to activate the next target. |
|
|
122
|
+
| `_name` | Inactive | Does not run automatically. Trigger it manually with `.activateTarget()`. Equivalent to `{ active: false }`. |
|
|
123
|
+
|
|
97
124
|
|
|
98
125
|
## Examples: Like Button → Animated Like (in 3 Steps)
|
|
99
126
|
|
|
100
|
-
Let’s see how TargetJS handles a complex interaction that would usually require 50+ lines of React/CSS. The example demonstrates how to run four asynchronous operations in a strict
|
|
127
|
+
Let’s see how TargetJS handles a complex interaction that would usually require 50+ lines of React/CSS. The example demonstrates how to run four asynchronous operations in a strict sequence. In other words, each step has to wait for all the previous ones to complete.
|
|
101
128
|
|
|
102
129
|
### 1) Like button
|
|
103
130
|
|
|
@@ -203,9 +230,8 @@ Each target has its own state and lifecycle. Targets execute automatically in th
|
|
|
203
230
|
|
|
204
231
|
1. [📦 Alternative Installation Via CDN](#-alternative-installation-via-cdn)
|
|
205
232
|
1. [Using TargetJS as a Library](#using-targetjs-as-a-library)
|
|
206
|
-
1. [🚀 Why TargetJS?](#-why-targetjs)
|
|
207
233
|
1. Deeper Examples:
|
|
208
|
-
- [
|
|
234
|
+
- [Search → Fetch → Replace → Highlight Example](#search--fetch--replace--highlight)
|
|
209
235
|
- [Infinite Loading and Scrolling Example](#infinite-loading-and-scrolling-example)
|
|
210
236
|
1. [Special Target Names](#special-target-names)
|
|
211
237
|
1. [How to Debug in TargetJS](#how-to-debug-in-targetjs)
|
|
@@ -283,90 +309,86 @@ export default function TargetIsland() {
|
|
|
283
309
|
}
|
|
284
310
|
```
|
|
285
311
|
|
|
286
|
-
## 🚀 Why TargetJS?
|
|
287
|
-
|
|
288
|
-
1. Zero Boilerplate Async: The $$ postfix handles the "wait" for you.
|
|
289
|
-
2. Unified State: State isn't "elsewhere". It's built into every Target.
|
|
290
|
-
3. Animation by Default: High-performance animations are baked into the logic.
|
|
291
|
-
4. Ultra-Compact: Write 70% less code than standard frameworks.
|
|
292
|
-
5. Lower Cognitive Load: Code reads from top to bottom, exactly how the user experiences the interaction.
|
|
293
|
-
|
|
294
312
|
## Deeper Examples
|
|
295
313
|
|
|
296
|
-
###
|
|
314
|
+
### Search → Fetch → Replace → Highlight
|
|
297
315
|
|
|
298
|
-
|
|
316
|
+
This example shows how TargetJS models a UI workflow directly in code order:
|
|
317
|
+
Click → animate button → fetch users → remove old results → add new results → pause → highlight one result
|
|
299
318
|
|
|
300
|
-
|
|
301
|
-
- `child` is a special target that adds a new item to the parent each time it executes. Because it ends with `$` in this example, it executes every time an API call returns a result.
|
|
302
|
-
- TargetJS ensures that API results are processed in the same sequence as the API calls. For example, if the user1 API result arrives before user0, `child` will not execute until the result for user0 has been received.
|
|
319
|
+
The `fetch` target is initially set to `active: false`, which means it waits for an explicit trigger. When the user clicks, the `fetch` target is activated. TargetJS understands that fetching data is an asynchronous operation.
|
|
303
320
|
|
|
304
|
-
|
|
321
|
+
The `$$` postfix means that a target waits for the preceding sibling targets to complete before running. In this example, `removeChildren$$` waits for `fetch` to complete before it begins. `addChildren$$` begins after both `fetch` and `removeChildren$$` are completed.
|
|
305
322
|
|
|
306
|
-
|
|
307
|
-
<div id="users"></div>
|
|
308
|
-
```
|
|
309
|
-
```javascript
|
|
310
|
-
import { App } from "targetj";
|
|
323
|
+
Notice how `fetch`, `removeChildren$$`, and `addChildren$$` appear in the same order as the UI sequence. The code is organized around the experience itself.
|
|
311
324
|
|
|
312
|
-
|
|
313
|
-
gap: 10,
|
|
314
|
-
fetch: ['https://targetjs.io/api/randomUser?id=user0',
|
|
315
|
-
'https://targetjs.io/api/randomUser?id=user1',
|
|
316
|
-
'https://targetjs.io/api/randomUser?id=user2',
|
|
317
|
-
'https://targetjs.io/api/randomUser?id=user3',
|
|
318
|
-
'https://targetjs.io/api/randomUser?id=user4'
|
|
319
|
-
],
|
|
320
|
-
child$() {
|
|
321
|
-
// prevTargetValue Holds the previous target’s value. For fetch targets, this is each API result in code order,
|
|
322
|
-
// not the order in which responses arrive in the browser.
|
|
323
|
-
const user = this.prevTargetValue;
|
|
324
|
-
return {
|
|
325
|
-
width: 200,
|
|
326
|
-
height: 65,
|
|
327
|
-
borderRadius: 10,
|
|
328
|
-
boxSizing: "border-box",
|
|
329
|
-
padding: 10,
|
|
330
|
-
fontSize: 14,
|
|
331
|
-
backgroundColor: "#f0f0f0",
|
|
332
|
-
scale: { value: [0.8, 1], steps: 14, interval: 12 },
|
|
333
|
-
userName$$: {
|
|
334
|
-
padding: "10px 0 5px 10px",
|
|
335
|
-
boxSizing: "border-box",
|
|
336
|
-
fontWeight: 600,
|
|
337
|
-
opacity: { value: [0, 1], steps: 50 },
|
|
338
|
-
html: user.name
|
|
339
|
-
},
|
|
340
|
-
userEmail$$: {
|
|
341
|
-
paddingLeft: 10,
|
|
342
|
-
boxSizing: "border-box",
|
|
343
|
-
opacity: { value: [0, 0.7], steps: 50 },
|
|
344
|
-
html: user.email
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
}).mount("#users");
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
It can also be written using a target’s `cycles` and `interval` properties/methods to fetch users at intervals instead of in a single batch. In this example, we set interval to 1000, making the API call once every second.
|
|
325
|
+
Lastly, `pause$$` adds a short pause before highlighting the first user with an animation. `setTarget` is an imperative way to implement targets within methods.
|
|
352
326
|
|
|
353
|
-
<img src="https://targetjs.io/img/fetch-5-users2.gif" width="130" />
|
|
354
327
|
|
|
328
|
+
```js
|
|
329
|
+
import { App } from "targetj";
|
|
355
330
|
|
|
356
|
-
```javascript
|
|
357
331
|
App({
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
332
|
+
searchButton: {
|
|
333
|
+
element: 'button',
|
|
334
|
+
type: 'button',
|
|
335
|
+
y: 20, x: 20,
|
|
336
|
+
width: 220, height: 60, lineHeight: 60,
|
|
337
|
+
borderRadius: 10, border: 0, backgroundColor: '#f5f5f5',
|
|
338
|
+
cursor: 'pointer', textAlign: 'center',
|
|
339
|
+
html: 'Search',
|
|
340
|
+
onClick() {
|
|
341
|
+
this.setTarget('scale', {value: [1, 1.15, 1], steps: 8, interval: 12 });
|
|
342
|
+
this.setTarget('backgroundColor', {value: [ '#ffe8ec', '#f5f5f5' ], steps: 12, interval: 12});
|
|
343
|
+
this.parent.getChild('users').activateTarget('fetch', { reset: true });
|
|
344
|
+
}
|
|
363
345
|
},
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
346
|
+
users: {
|
|
347
|
+
y: 90,
|
|
348
|
+
x: 20,
|
|
349
|
+
gap: 10,
|
|
350
|
+
containerOverflowMode: 'always',
|
|
351
|
+
fetch: {
|
|
352
|
+
active: false,
|
|
353
|
+
value: 'https://targetjs.io/api/randomUsers'
|
|
354
|
+
},
|
|
355
|
+
removeChildren$$() {
|
|
356
|
+
this.removeChildren();
|
|
357
|
+
},
|
|
358
|
+
addChildren$$: {
|
|
359
|
+
cycles() { return this.val('fetch').length; },
|
|
360
|
+
value(i) {
|
|
361
|
+
const user = this.val('fetch')[i];
|
|
362
|
+
return {
|
|
363
|
+
width: 360,
|
|
364
|
+
backgroundColor: "#fafafa",
|
|
365
|
+
scale: {value: {list: [0.8, 1]}, steps: 14},
|
|
366
|
+
boxShadow: "0 6px 16px rgba(0,0,0,.08)",
|
|
367
|
+
containerOverflowMode: 'always',
|
|
368
|
+
userName: {
|
|
369
|
+
padding: 10,
|
|
370
|
+
height: 30,
|
|
371
|
+
fontWeight: 600,
|
|
372
|
+
opacity: { value: [0, 1], steps: 50 },
|
|
373
|
+
html() { return user.name; }
|
|
374
|
+
},
|
|
375
|
+
userEmail: {
|
|
376
|
+
padding: 10,
|
|
377
|
+
opacity: { value: [0, 0.7], steps: 50 },
|
|
378
|
+
html() { return user.email; }
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
pause$$: { interval: 150 },
|
|
384
|
+
highlightOne$$() {
|
|
385
|
+
const user = this.getChild(0);
|
|
386
|
+
user.setTarget('backgroundColor', { value: ['#fff7cc', '#fff1a8'], steps: 14 });
|
|
387
|
+
user.setTarget('scale', { value: [1, 1.04, 1], steps: 14 });
|
|
388
|
+
user.setTarget('boxShadow', '0 10px 24px rgba(0,0,0,.14)');
|
|
389
|
+
}
|
|
368
390
|
}
|
|
369
|
-
}).mount(
|
|
391
|
+
}).mount('#app');
|
|
370
392
|
```
|
|
371
393
|
|
|
372
394
|
### Infinite Loading and Scrolling Example
|
|
@@ -403,42 +425,47 @@ App({
|
|
|
403
425
|
height() { return getScreenHeight(); },
|
|
404
426
|
x() { return (getScreenWidth() - this.getWidth()) / 2; },
|
|
405
427
|
containerOverflowMode: "always",
|
|
406
|
-
addChildren
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
428
|
+
addChildren: {
|
|
429
|
+
waitForChildren: 'visible',
|
|
430
|
+
value() {
|
|
431
|
+
return Array.from({ length: 10 }, (_, i) => ({
|
|
432
|
+
height: 56,
|
|
433
|
+
width() { return this.parent.getWidth(); },
|
|
434
|
+
bottomMargin: 8,
|
|
435
|
+
borderRadius: 12,
|
|
436
|
+
backgroundColor: "white",
|
|
437
|
+
boxShadow: "0 8px 20px rgba(0,0,0,0.08)",
|
|
438
|
+
photo: {
|
|
439
|
+
x: 10, y: 10, width: 34, height: 34,
|
|
440
|
+
borderRadius: "50%",
|
|
441
|
+
backgroundColor: "#ddd"
|
|
442
|
+
},
|
|
443
|
+
userName: {
|
|
444
|
+
x: 60, y: 10, width: 180, height: 30,
|
|
445
|
+
overflow: "hidden",
|
|
446
|
+
borderRadius: 5,
|
|
447
|
+
backgroundColor: "#ddd"
|
|
448
|
+
},
|
|
449
|
+
pause$$: { interval: 100 },
|
|
450
|
+
fetch$$: "https://targetjs.io/api/randomUser",
|
|
451
|
+
reveal$$() {
|
|
452
|
+
const userName = this.getChild("userName");
|
|
453
|
+
userName.setTarget("html", this.val("fetch$$").name);
|
|
454
|
+
userName.setTarget("backgroundColor", { value: "white", steps: 20 });
|
|
455
|
+
this.getChild("photo").setTarget("backgroundColor", { value: "#" + Math.random().toString(16).slice(-6), steps: 20 });
|
|
456
|
+
},
|
|
457
|
+
}));
|
|
458
|
+
}
|
|
434
459
|
},
|
|
435
460
|
wave$$: {
|
|
436
461
|
interval: 30,
|
|
437
462
|
cycles() { return this.visibleChildren.length; },
|
|
438
463
|
value(i) {
|
|
439
464
|
const child = this.visibleChildren[i];
|
|
440
|
-
child
|
|
441
|
-
|
|
465
|
+
if (child) {
|
|
466
|
+
child.setTarget("scale", { value: [1, 1.06, 1], steps: 18 });
|
|
467
|
+
child.setTarget("opacity", { value: [1, 0.92, 1], steps: 18 });
|
|
468
|
+
}
|
|
442
469
|
}
|
|
443
470
|
},
|
|
444
471
|
onScroll() {
|
package/build/LocationManager.js
CHANGED
|
@@ -452,6 +452,7 @@ var LocationManager = exports.LocationManager = /*#__PURE__*/function () {
|
|
|
452
452
|
} else {
|
|
453
453
|
nowVisible = !!tmodel.targets.isVisible;
|
|
454
454
|
}
|
|
455
|
+
tmodel.actualValues.isVisible = nowVisible;
|
|
455
456
|
tmodel.isNowVisible = !wasVisible && nowVisible;
|
|
456
457
|
tmodel.isNowInvisible = (wasVisible || wasVisible === undefined) && !nowVisible;
|
|
457
458
|
} else {
|
package/build/PageManager.js
CHANGED
|
@@ -68,33 +68,42 @@ var PageManager = exports.PageManager = /*#__PURE__*/function () {
|
|
|
68
68
|
return _App.tApp.reset();
|
|
69
69
|
case 4:
|
|
70
70
|
link = _TUtil.TUtil.getFullLink(link);
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
_App.App.tmodelIdMap = {};
|
|
75
|
-
_App.tApp.tRoot = _App.tApp.tRootFactory();
|
|
76
|
-
this.lastLink = link;
|
|
77
|
-
_App.tApp.start();
|
|
78
|
-
} else {
|
|
79
|
-
_App.tApp.tRoot = this.pageCache[link].tRoot;
|
|
80
|
-
_App.App.oids = this.pageCache[link].oids;
|
|
81
|
-
_App.App.tmodelIdMap = this.pageCache[link].tmodelIdMap;
|
|
82
|
-
_App.tApp.tRoot.$dom = _$Dom.$Dom.query('#tgjs-root') ? new _$Dom.$Dom('#tgjs-root') : new _$Dom.$Dom('body');
|
|
83
|
-
_App.tApp.tRoot.$dom.innerHTML(this.pageCache[link].html);
|
|
84
|
-
visibles = Object.values(this.pageCache[link].visibleOidMap);
|
|
85
|
-
newVisibles = _DomInit.DomInit.initCacheDoms(visibles);
|
|
86
|
-
visibles.forEach(function (tmodel) {
|
|
87
|
-
tmodel.visibilityStatus = undefined;
|
|
88
|
-
});
|
|
89
|
-
_App.tApp.manager.visibleOidMap = _objectSpread({}, this.pageCache[link].visibleOidMap);
|
|
90
|
-
newVisibles.forEach(function (visible) {
|
|
91
|
-
_App.tApp.manager.visibleOidMap[visible.oid] = visible;
|
|
92
|
-
});
|
|
93
|
-
window.scrollTo(this.pageCache[link].scrollLeft, this.pageCache[link].scrollTop);
|
|
94
|
-
this.lastLink = link;
|
|
95
|
-
_App.tApp.start();
|
|
71
|
+
if (this.pageCache[link]) {
|
|
72
|
+
_context.next = 15;
|
|
73
|
+
break;
|
|
96
74
|
}
|
|
97
|
-
|
|
75
|
+
_App.tApp.tRoot.$dom.innerHTML("");
|
|
76
|
+
_App.App.oids = {};
|
|
77
|
+
_App.App.tmodelIdMap = {};
|
|
78
|
+
_App.tApp.tRoot = _App.tApp.tRootFactory();
|
|
79
|
+
this.lastLink = link;
|
|
80
|
+
_context.next = 13;
|
|
81
|
+
return _App.tApp.start();
|
|
82
|
+
case 13:
|
|
83
|
+
_context.next = 30;
|
|
84
|
+
break;
|
|
85
|
+
case 15:
|
|
86
|
+
_App.tApp.tRoot = this.pageCache[link].tRoot;
|
|
87
|
+
_App.App.oids = this.pageCache[link].oids;
|
|
88
|
+
_App.App.tmodelIdMap = this.pageCache[link].tmodelIdMap;
|
|
89
|
+
_App.tApp.tRoot.$dom = _$Dom.$Dom.query('#tgjs-root') ? new _$Dom.$Dom('#tgjs-root') : new _$Dom.$Dom('body');
|
|
90
|
+
_App.tApp.tRoot.$dom.innerHTML(this.pageCache[link].html);
|
|
91
|
+
visibles = Object.values(this.pageCache[link].visibleOidMap);
|
|
92
|
+
newVisibles = _DomInit.DomInit.initCacheDoms(visibles);
|
|
93
|
+
visibles.forEach(function (tmodel) {
|
|
94
|
+
tmodel.visibilityStatus = undefined;
|
|
95
|
+
});
|
|
96
|
+
_App.tApp.manager.visibleOidMap = _objectSpread({}, this.pageCache[link].visibleOidMap);
|
|
97
|
+
newVisibles.forEach(function (visible) {
|
|
98
|
+
_App.tApp.manager.visibleOidMap[visible.oid] = visible;
|
|
99
|
+
});
|
|
100
|
+
window.scrollTo(this.pageCache[link].scrollLeft, this.pageCache[link].scrollTop);
|
|
101
|
+
this.lastLink = link;
|
|
102
|
+
_context.next = 29;
|
|
103
|
+
return _App.tApp.start();
|
|
104
|
+
case 29:
|
|
105
|
+
(0, _App.getRunScheduler)().restoreSnapshot(this.pageCache[link].runSnapshot);
|
|
106
|
+
case 30:
|
|
98
107
|
case "end":
|
|
99
108
|
return _context.stop();
|
|
100
109
|
}
|
|
@@ -176,7 +185,8 @@ var PageManager = exports.PageManager = /*#__PURE__*/function () {
|
|
|
176
185
|
visibleOidMap: _objectSpread({}, _App.tApp.manager.visibleOidMap),
|
|
177
186
|
scrollLeft: _$Dom.$Dom.getWindowScrollLeft() || 0,
|
|
178
187
|
scrollTop: _$Dom.$Dom.getWindowScrollTop() || 0,
|
|
179
|
-
tRoot: _App.tApp.tRoot
|
|
188
|
+
tRoot: _App.tApp.tRoot,
|
|
189
|
+
runSnapshot: (0, _App.getRunScheduler)().getSnapshot()
|
|
180
190
|
};
|
|
181
191
|
}
|
|
182
192
|
if (updateHistory) {
|
|
@@ -211,7 +221,8 @@ var PageManager = exports.PageManager = /*#__PURE__*/function () {
|
|
|
211
221
|
visibleOidMap: _objectSpread({}, _App.tApp.manager.visibleOidMap),
|
|
212
222
|
scrollLeft: _$Dom.$Dom.getWindowScrollLeft() || 0,
|
|
213
223
|
scrollTop: _$Dom.$Dom.getWindowScrollTop() || 0,
|
|
214
|
-
tRoot: _App.tApp.tRoot
|
|
224
|
+
tRoot: _App.tApp.tRoot,
|
|
225
|
+
runSnapshot: (0, _App.getRunScheduler)().getSnapshot()
|
|
215
226
|
};
|
|
216
227
|
if (updateHistory) {
|
|
217
228
|
history.pushState({
|
package/build/RunScheduler.js
CHANGED
|
@@ -43,7 +43,6 @@ var RunScheduler = exports.RunScheduler = /*#__PURE__*/function () {
|
|
|
43
43
|
key: "resetRuns",
|
|
44
44
|
value: function () {
|
|
45
45
|
var _resetRuns = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
46
|
-
var _this$delayProcess;
|
|
47
46
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
48
47
|
while (1) switch (_context.prev = _context.next) {
|
|
49
48
|
case 0:
|
|
@@ -53,9 +52,7 @@ var RunScheduler = exports.RunScheduler = /*#__PURE__*/function () {
|
|
|
53
52
|
return requestAnimationFrame(resolve);
|
|
54
53
|
});
|
|
55
54
|
case 3:
|
|
56
|
-
|
|
57
|
-
clearTimeout(this.delayProcess.timeoutId);
|
|
58
|
-
}
|
|
55
|
+
this.clearDelayProcess();
|
|
59
56
|
this.nextRuns = [];
|
|
60
57
|
this.domProcessing = 0;
|
|
61
58
|
this.runningFlag = false;
|
|
@@ -113,7 +110,7 @@ var RunScheduler = exports.RunScheduler = /*#__PURE__*/function () {
|
|
|
113
110
|
key: "run",
|
|
114
111
|
value: function () {
|
|
115
112
|
var _run = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(delay, runId) {
|
|
116
|
-
var _this$
|
|
113
|
+
var _this$delayProcess;
|
|
117
114
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
118
115
|
while (1) switch (_context2.prev = _context2.next) {
|
|
119
116
|
case 0:
|
|
@@ -137,7 +134,7 @@ var RunScheduler = exports.RunScheduler = /*#__PURE__*/function () {
|
|
|
137
134
|
this.runningFlag = true;
|
|
138
135
|
this.runStartTime = _TUtil.TUtil.now();
|
|
139
136
|
if (_App.tApp.debugLevel === 1) {
|
|
140
|
-
_TUtil.TUtil.log(true)("Request from: ".concat(runId, " delay: ").concat(delay, " runningStep:").concat(this.runningStep, " dom:").concat(this.domProcessing, " runs:").concat(this.nextRuns.length, " D:").concat((_this$
|
|
137
|
+
_TUtil.TUtil.log(true)("Request from: ".concat(runId, " delay: ").concat(delay, " runningStep:").concat(this.runningStep, " dom:").concat(this.domProcessing, " runs:").concat(this.nextRuns.length, " D:").concat((_this$delayProcess = this.delayProcess) === null || _this$delayProcess === void 0 ? void 0 : _this$delayProcess.delay, " events:").concat((0, _App.getEvents)().eventQueue.length));
|
|
141
138
|
}
|
|
142
139
|
if (!(this.phase === 0)) {
|
|
143
140
|
_context2.next = 16;
|
|
@@ -291,31 +288,52 @@ var RunScheduler = exports.RunScheduler = /*#__PURE__*/function () {
|
|
|
291
288
|
_this3.needsRerun();
|
|
292
289
|
});
|
|
293
290
|
}
|
|
291
|
+
}, {
|
|
292
|
+
key: "clearDelayProcess",
|
|
293
|
+
value: function clearDelayProcess() {
|
|
294
|
+
var _this$delayProcess2;
|
|
295
|
+
if ((_this$delayProcess2 = this.delayProcess) !== null && _this$delayProcess2 !== void 0 && _this$delayProcess2.timeoutId) {
|
|
296
|
+
clearTimeout(this.delayProcess.timeoutId);
|
|
297
|
+
this.delayProcess.timeoutId = undefined;
|
|
298
|
+
}
|
|
299
|
+
this.delayProcess = undefined;
|
|
300
|
+
}
|
|
294
301
|
}, {
|
|
295
302
|
key: "setDelayProcess",
|
|
296
303
|
value: function setDelayProcess(runId, insertTime, interval, runTime, delay) {
|
|
297
304
|
var _this4 = this;
|
|
298
|
-
|
|
305
|
+
var delayProcess = {
|
|
299
306
|
runId: runId,
|
|
300
307
|
insertTime: insertTime,
|
|
301
308
|
runTime: runTime,
|
|
302
309
|
interval: interval,
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
while (1) switch (_context3.prev = _context3.next) {
|
|
306
|
-
case 0:
|
|
307
|
-
_this4.delayProcess.timeoutId = undefined;
|
|
308
|
-
_context3.next = 3;
|
|
309
|
-
return _this4.run(delay, runId);
|
|
310
|
-
case 3:
|
|
311
|
-
_this4.executeNextRun();
|
|
312
|
-
case 4:
|
|
313
|
-
case "end":
|
|
314
|
-
return _context3.stop();
|
|
315
|
-
}
|
|
316
|
-
}, _callee3);
|
|
317
|
-
})), Math.max(0, delay))
|
|
310
|
+
delay: delay,
|
|
311
|
+
timeoutId: undefined
|
|
318
312
|
};
|
|
313
|
+
delayProcess.timeoutId = setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
314
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
315
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
316
|
+
case 0:
|
|
317
|
+
if (!(_this4.delayProcess !== delayProcess)) {
|
|
318
|
+
_context3.next = 2;
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
return _context3.abrupt("return");
|
|
322
|
+
case 2:
|
|
323
|
+
delayProcess.timeoutId = undefined;
|
|
324
|
+
_context3.next = 5;
|
|
325
|
+
return _this4.run(delay, runId);
|
|
326
|
+
case 5:
|
|
327
|
+
if (_this4.delayProcess === delayProcess) {
|
|
328
|
+
_this4.executeNextRun();
|
|
329
|
+
}
|
|
330
|
+
case 6:
|
|
331
|
+
case "end":
|
|
332
|
+
return _context3.stop();
|
|
333
|
+
}
|
|
334
|
+
}, _callee3);
|
|
335
|
+
})), Math.max(0, delay));
|
|
336
|
+
this.delayProcess = delayProcess;
|
|
319
337
|
}
|
|
320
338
|
}, {
|
|
321
339
|
key: "executeNextRun",
|
|
@@ -341,7 +359,7 @@ var RunScheduler = exports.RunScheduler = /*#__PURE__*/function () {
|
|
|
341
359
|
var _newDelay = Math.max(1, nextValidRun.delay - (_now - nextValidRun.insertTime));
|
|
342
360
|
this.setDelayProcess(nextValidRun.runId, nextValidRun.insertTime, nextValidRun.delay, _now + _newDelay, _newDelay);
|
|
343
361
|
} else {
|
|
344
|
-
this.
|
|
362
|
+
this.clearDelayProcess();
|
|
345
363
|
}
|
|
346
364
|
}
|
|
347
365
|
}, {
|
|
@@ -383,6 +401,52 @@ var RunScheduler = exports.RunScheduler = /*#__PURE__*/function () {
|
|
|
383
401
|
delay: newDelay
|
|
384
402
|
});
|
|
385
403
|
}
|
|
404
|
+
}, {
|
|
405
|
+
key: "getSnapshot",
|
|
406
|
+
value: function getSnapshot() {
|
|
407
|
+
var now = _TUtil.TUtil.now();
|
|
408
|
+
var runs = [];
|
|
409
|
+
var addRun = function addRun(run) {
|
|
410
|
+
if (!run) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
var runTime = _TUtil.TUtil.isDefined(run.runTime) ? run.runTime : run.insertTime + run.delay;
|
|
414
|
+
runs.push({
|
|
415
|
+
runId: run.runId,
|
|
416
|
+
delay: Math.max(0, runTime - now)
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
addRun(this.delayProcess);
|
|
420
|
+
this.nextRuns.forEach(addRun);
|
|
421
|
+
var immediateRuns = runs.filter(function (run) {
|
|
422
|
+
return run.delay === 0;
|
|
423
|
+
});
|
|
424
|
+
var delayedRuns = runs.filter(function (run) {
|
|
425
|
+
return run.delay > 0;
|
|
426
|
+
});
|
|
427
|
+
var result = [];
|
|
428
|
+
if (immediateRuns.length) {
|
|
429
|
+
result.push({
|
|
430
|
+
runId: immediateRuns.map(function (run) {
|
|
431
|
+
return run.runId;
|
|
432
|
+
}).join('-'),
|
|
433
|
+
delay: 0
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
delayedRuns.forEach(function (run) {
|
|
437
|
+
result.push(run);
|
|
438
|
+
});
|
|
439
|
+
return result;
|
|
440
|
+
}
|
|
441
|
+
}, {
|
|
442
|
+
key: "restoreSnapshot",
|
|
443
|
+
value: function restoreSnapshot() {
|
|
444
|
+
var _this5 = this;
|
|
445
|
+
var snapshot = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
446
|
+
snapshot.forEach(function (run) {
|
|
447
|
+
_this5.schedule(run.delay, "restore-".concat(run.runId));
|
|
448
|
+
});
|
|
449
|
+
}
|
|
386
450
|
}]);
|
|
387
451
|
}();
|
|
388
452
|
_defineProperty(RunScheduler, "domSteps", [function () {
|
package/build/TModelManager.js
CHANGED
|
@@ -114,7 +114,9 @@ var TModelManager = exports.TModelManager = /*#__PURE__*/function () {
|
|
|
114
114
|
if (!tmodel.canHaveDom() || !tmodel.isIncluded() || tmodel.canDeleteDom() && !visible && !keepDom) {
|
|
115
115
|
this.addToInvisibleDom(tmodel);
|
|
116
116
|
tmodel.getChildren().forEach(function (tmodel) {
|
|
117
|
-
|
|
117
|
+
if (!tmodel.managesOwnScroll()) {
|
|
118
|
+
_this.addToRecursiveInvisibleDom(tmodel);
|
|
119
|
+
}
|
|
118
120
|
});
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -232,7 +234,9 @@ var TModelManager = exports.TModelManager = /*#__PURE__*/function () {
|
|
|
232
234
|
this.lists.invisibleDom.push(tmodel);
|
|
233
235
|
}
|
|
234
236
|
tmodel.getChildren().forEach(function (tmodel) {
|
|
235
|
-
|
|
237
|
+
if (!tmodel.managesOwnScroll()) {
|
|
238
|
+
_this2.addToRecursiveInvisibleDom(tmodel);
|
|
239
|
+
}
|
|
236
240
|
});
|
|
237
241
|
}
|
|
238
242
|
}
|
|
@@ -260,10 +264,11 @@ var TModelManager = exports.TModelManager = /*#__PURE__*/function () {
|
|
|
260
264
|
}, {
|
|
261
265
|
key: "needsRerender",
|
|
262
266
|
value: function needsRerender(tmodel) {
|
|
263
|
-
|
|
264
|
-
|
|
267
|
+
var html = tmodel.getHtml();
|
|
268
|
+
if (!tmodel.hasDom() || !_TUtil.TUtil.isDefined(html)) {
|
|
269
|
+
return false;
|
|
265
270
|
}
|
|
266
|
-
return
|
|
271
|
+
return tmodel.$dom.innerHTML() !== String(html) || tmodel.$dom.textOnly !== tmodel.isTextOnly();
|
|
267
272
|
}
|
|
268
273
|
}, {
|
|
269
274
|
key: "needsRestyle",
|
package/build/TUtil.js
CHANGED
|
@@ -82,7 +82,7 @@ var TUtil = exports.TUtil = /*#__PURE__*/function () {
|
|
|
82
82
|
}, {
|
|
83
83
|
key: "getVisibilityClipRect",
|
|
84
84
|
value: function getVisibilityClipRect(container) {
|
|
85
|
-
var rect =
|
|
85
|
+
var rect = TUtil.getScreenViewportRect();
|
|
86
86
|
while (container && container !== (0, _App.tRoot)()) {
|
|
87
87
|
if (this.shouldClipByAncestor(container)) {
|
|
88
88
|
var ancestorRect = this.getAncestorViewportRect(container);
|
|
@@ -95,6 +95,17 @@ var TUtil = exports.TUtil = /*#__PURE__*/function () {
|
|
|
95
95
|
}
|
|
96
96
|
return rect;
|
|
97
97
|
}
|
|
98
|
+
}, {
|
|
99
|
+
key: "getScreenViewportRect",
|
|
100
|
+
value: function getScreenViewportRect() {
|
|
101
|
+
return {
|
|
102
|
+
x: 0,
|
|
103
|
+
y: 0,
|
|
104
|
+
r: (0, _App.getScreenWidth)(),
|
|
105
|
+
b: (0, _App.getScreenHeight)(),
|
|
106
|
+
source: "screen"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
98
109
|
}, {
|
|
99
110
|
key: "shouldClipByAncestor",
|
|
100
111
|
value: function shouldClipByAncestor(ancestor) {
|