targetj 1.0.73 → 1.0.74

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 CHANGED
@@ -4,36 +4,44 @@ Welcome to TargetJ, a powerful JavaScript UI framework designed to simplify deve
4
4
 
5
5
  TargetJ distinguishes itself by introducing a novel concept known as 'targets', which forms its core. Targets are used as the main building blocks of components instead of direct variables and methods. Each component in TargetJ is a set of targets. Targets are employed across all aspects of the program. They are used in animation, controlling program flow, loading data from external APIs, handling user events, and more.
6
6
 
7
- Targets enhance both variables and methods by giving them lifecycles and the autonomy to run independently, rather than always being controlled externally. They can execute under specific conditions, manage the number and timing of executions, and provide callbacks to oversee their life cycles.
7
+ ### Installation
8
8
 
9
- ## What are targets?
9
+ To install TargetJ, run the following command in your terminal:
10
10
 
11
- Targets provide a unified, autonomous approach for managing passive variables and methods, mimicking the behavior of live cells in living beings. They largely manage themselves autonomously, with various callbacks available to adjust for changes.
11
+ ```bash
12
+ npm install targetj
13
+ ```
12
14
 
13
- For variables, targets enhance functionality by giving them the ability to iterate in steps until they reach the specified value, rather rather than being immediately assigned their values. They can introduce pauses between iterations and offer callbacks to monitor progress, track the progress of other variables, and manage their life cycles accordingly.
15
+ ## What are targets?
16
+
17
+ Targets provide a unified interface for variables and methods, giving them life cycles and the autonomy to operate independently, with various callbacks to adapt to changes, mimicking the behavior of living cells.
14
18
 
15
- Similarly, targets enhance methods by allowing them to manage their own life cycles. They execute under specific conditions, control the number of executions, and offer the same capabilities as those provided to variables.
19
+ For variables, targets enhance functionality by giving them the ability to iterate in steps until they reach the specified value, rather than being immediately assigned their values. They can introduce pauses between iterations and offer callbacks to monitor progress, track the progress of other variables, and manage their life cycles accordingly. Similarly, targets enhance methods by allowing them to manage their own life cycles. They can execute themselves under specific conditions, control the number of executions, and offer the same capabilities as those provided to variables.
16
20
 
17
21
  ## What does a target consist of?
18
22
 
19
23
  Each target consists of the following:
20
- 1. Target Value and Actual Value. The target value represents a variable or the outcome of a method. The actual value reflects the transitional value between the previous target value and the current target value. When the target value differs from the actual value, TargetJ iteratively updates the actual value until it matches the target value. This process is managed by two additional variables: Step, which dictates the number of iterations, and Interval, which specifies the duration (in milliseconds) the system waits before executing the next iteration.
24
+ 1. Target Value and Actual Value. The target value represents a variable or the outcome of a method. The actual value is typically the value used by the rest of the application. When the target value differs from the actual value, TargetJ iteratively updates the actual value until it matches the target value. This process is managed by two additional variables: Step, which dictates the number of iterations, and Interval, which specifies the duration (in milliseconds) the system waits before executing the next iteration.
21
25
 
22
- 2. State: Targets have three states that control their lifecycle: Active, Updating, and Complete. Active: Indicates that the target value needs to be initialized from the variable or that the method needs to be executed to calculate its output. Updating: Indicates that the actual value is being adjusted to reach the target value. Complete: Indicates that the target execution is finished, and the actual value has matched the target value.
26
+ 2. State: Targets have four states that control their lifecycle: Active, Inactive, Updating, and Complete. Active: This is the default state for all targets. It indicates that the target is ready to be executed, and the target value needs to be initialized from the variable it represents or its value() method needs to be executed to calculate its output. Inactive: Indicates that the target is not ready to be executed. Updating: Indicates that the actual value is being adjusted to reach the target value. Complete: Indicates that the target execution is finished, and the actual value has matched the target value.
23
27
 
24
28
  3. Target Methods: All methods are optional. They are used to control the lifecycle of targets or serve as callbacks to reflect changes. The controlling methods are: enabledOn, loop, steps, cycles. The callbacks are: onValueChange, onStepsEnd, onImperativeStep, onImperativeEnd. More details in the method section.
25
29
 
26
30
  ## Brief overview of how it operates
27
31
 
28
- All targets are in the active state by default. They can include an enabledOn function that delays their execution until the specified conditions are met. Targets can also be set to inactive and activated externally when needed. The target task monitors all active targets, and if a target is enabled, it will be executed. The target value is generated either from the result of a method or from a static value defined in the target. For simple targets without steps, cycles, or loops, the actual value is set immediately based on the target value. Once executed, the target’s state becomes complete, and it will not be executed again.
32
+ All targets are in the active state by default and ready to be executed. They can include an enabledOn function that delays their execution until the specified conditions are met. Targets can also be set to inactive and activated externally when needed.
33
+
34
+ The target task monitors all active targets, and if a target is enabled, it will be executed. The target value is generated either from the result of a method or from a static value defined in the target. For simple targets without steps, cycles, or loops, the actual value is set immediately based on the target value. Once executed, the target’s state becomes complete, and it will not be executed again.
29
35
 
30
36
  If the target has loop or cycle methods defined, its value method will be re-executed after a pause specified by the interval. The number of executions will be determined by the cycles or will continue as long as the loop condition returns true. If the target has steps defined, its state changes to updating, and the actual value is updated iteratively until it reaches the target value, according to the number of steps and pauses specified by steps and intervals.
31
37
 
32
- A target can reactivate itself under various conditions, such as when all steps are completed, all imperative targets initiated by that target are completed, or the targets of the component’s children are completed. It can also be reactivated externally, either directly or through an event.
38
+ A target can reactivate itself in the `onStepsEnd` callback once all steps are completed, or in the `onImperativeEnd` callback when all imperative targets initiated by that target are finished, allowing it to re-execute. It can also be reactivated externally, either directly or through an event.
33
39
 
34
40
  ## Target methods
35
41
 
36
- 1. **Value**
42
+ All methods and properties are optional, but they play integral roles in making targets useful for animation, API loading, event handling, and more:
43
+
44
+ 1. **value**
37
45
  If defined, value is the primary target method that will be executed. The target value will be calculated based on the result of value().
38
46
 
39
47
  2. **onEnabled**
@@ -66,10 +74,20 @@ onImperativeStep() This callback tracks the progress of imperative targets defin
66
74
  11. **onImperativeEnd**
67
75
  It is similar to onImperativeStep, but it is called when the imperative target is completed.
68
76
 
77
+ 12. **active**
78
+ This is only property. It indicates that the target is in an inactive state and is ready to be executed.
79
+
80
+ 13. **initialValue**
81
+ This is only property. It defines the initial value of the actual value.
82
+
83
+
69
84
  ### Simple example
70
85
 
71
86
  In the example below, we incrementally increase the value of width, height, and opacity in 30 steps, with a 50-milliseconds pause between each step.
72
87
 
88
+ ![first example](https://targetj.io/img/firstExample.png)
89
+
90
+
73
91
  ```bash
74
92
  import { App, TModel } from 'targetj';
75
93
 
@@ -110,166 +128,350 @@ App(new TModel({
110
128
 
111
129
  Targets in TargetJ can be defined in two ways: declaratively or imperatively.
112
130
 
113
- The declarative approach offers a structured method for defining targets, as seen in the previous example. However, orchestrating multiple targets with varying speeds and timings can be challenging. For instance, tracking the completion of multiple targets to trigger a new set of targets is not easily done using only declarative targets. To address this, TargetJ provides the setTarget function, allowing you to define multiple targets from within a single declarative target. Additionally, the onImperativeStep and onImperativeEnd callbacks, defined in the declarative target, enable you to track each step of the imperative targets or just their completion.
131
+ The declarative approach offers a structured method for defining targets, as seen in the previous example. However, orchestrating multiple targets with varying speeds and timings can be challenging. For instance, tracking the completion of multiple targets to trigger a new set of targets is not easily done using only declarative targets. To address this, TargetJ provides the setTarget function, allowing you to define multiple imperative targets from within a single declarative target. Additionally, the onImperativeStep and onImperativeEnd callbacks, defined in the declarative target, enable you to track each step of the imperative targets or just their completion.
114
132
 
115
133
  By combining both declarative and imperative targets, you gain a powerful toolset for designing complex interactions.
116
134
 
117
- ## Special target names used by TargetJ
118
-
119
- The following are special target names to impact the UI or control properties of TargetJ objects (called TModel):
120
-
121
- 1. x, y, width, height: Set the location and dimensions of the object.
122
- 2. opacity, scale, rotate: Set the opacity, scale, and rotation of the object.
123
- 3. zIndex: Sets the z-order of the object.
124
- 4. html: Sets the content of the object. By default, it will be interpreted as text.
125
- 5. style: An object that sets the style of the object.
126
- 6. css: A string that sets the CSS of the object.
127
- 7. scrollLeft and scrollTop: Used for scrolling the object.
128
- 8. leftMargin, rightMargin, topMargin, bottomMargin: Set the margins between objects.
129
- 9. children: Sets the TModel children of the object.
130
- 10. domHolder and domParent: Set to control the HTML element containment and how HTML is nested.
131
- 11. isVisible: An optional boolean flag to explicitly control the visibility of the object instead of leaving it to TargetJ to calculate.
132
- 12. canHaveDom: A boolean flag that sets if the object can have a DOM element in the page.
133
- 13. canHandleEvents: Sets what events the object can handle
134
- 14. widthFromDom and heightFromDom: Boolean flags that control if the width and height should be calculated from the DOM element.
135
- 15. textOnly: A boolean flag that sets the type of content to be text or HTML.
136
- 16. canBeBracketed: A boolean flag that controls if the object will be optimized and included in the TargetJ task process only when visible.
137
- 17. isInFlow: A boolean flag that determines if the object will be used to calculate the content height and width of its parent.
138
- 18. onResize: An array of targets that will be reset and re-executed after a resize event.
139
- 19. onClickEvent: An array of targets that will be reset and re-executed after a click event.
140
- 20. onTouchEvent: An array of targets that will be reset and re-executed after a touch event.
141
- 21. onScrollEvent: An array of targets that will be reset and re-executed after a scroll event.
142
- 22. onKeyEvent: An array of targets that will be reset and re-executed after a key event.
143
-
144
- ## Features
145
-
146
- As a result of using targets, we can develop web sites or apps with the following features:
147
-
148
- - **No HTML required**: HTML tags are seldom necessary except for images.
149
- - **No HTML nesting**: HTML nesting is seldom required in TargetJ. If it is required, nesting is done at runtime. Elements can be dynamically detached and incorporated into other elements, facilitating the easy reuse of components regardless of their location or attachment. It also opens the door for a new user experiences.
150
- - **Next-level animation**: Users can program objects to move at varying speeds, pause at certain intervals, and repeat sequences based on various conditions. It allows the creation of complicated animations.
151
- - **Control the flow of execution with time**: TargetJ simplifies the execution of various program segments at specific times, making it easy to sequence or parallelize numerous actions.
152
- - **Handle events effortlessly**: In TargetJ, events are triggered synchronously and are designed so that any component can detect when an event occurs. Event handling can be simply implemented as conditions in the enabling functions of \'targets.\' This ensures that managing events is both simple and effective.
153
- - **Easy to learn**: TargetJ simplifies development by employing the single concept of \'targets\' making it easy to learn.
154
- - **Handle 100,000s of items**: TargetJ efficiently manages large collections of objects on a single page. This is done by its data structure and optimization algorithm. It divides a long list into a tree structure, monitoring only the branches that are visible to the user at any given time.
155
- - **AI friendly**: With a unified concept of targets for all development, the ability to add and remove targets at runtime, and the capability to inspect various statuses of running objects, TargetJ is a strong candidate for AI-powered UI development.
156
-
157
- ## Getting Started
135
+ ## Declarative an imperative example
158
136
 
159
- ### Installation
137
+ The following example demonstrates the use of both declarative and imperative approaches. In the animate target, we set two imperative targets to move a square across the screen. When x reaches the end of the screen, onImperativeEnd is triggered, reactivating the target and restarting the animation.
160
138
 
161
- To install TargetJ, run the following command in your terminal:
139
+ ![declarative example](https://targetj.io/img/declarative.png)
162
140
 
163
141
  ```bash
164
- npm install targetj
142
+ import { App, TModel, getScreenWidth, getScreenHeight } from "targetj";
143
+
144
+ App(new TModel('declarative', {
145
+ add() {
146
+ for (var i = 0; i < 10; i++) {
147
+ this.addChild(new TModel("square", {
148
+ width: 50,
149
+ height: 50,
150
+ background: 'brown',
151
+ animate: {
152
+ value() {
153
+ var width = this.getWidth();
154
+ var parentWidth = this.getParentValue('width');
155
+ this.setTarget('x', { list: [ -width, parentWidth + width ] }, Math.floor(30 + parentWidth * Math.random()));
156
+ this.setTarget('y', Math.floor(Math.random() * (this.getParentValue('height') - this.getHeight())), 30);
157
+ },
158
+ onImperativeEnd(key) {
159
+ if (key === 'x') {
160
+ this.activateTarget(this.key);
161
+ }
162
+ }
163
+ }
164
+ }));
165
+ }
166
+ },
167
+ width() { return getScreenWidth(); },
168
+ height() { return getScreenHeight(); }
169
+ }));
165
170
  ```
166
171
 
167
- ## Examples
172
+ ## Loading data example
168
173
 
169
- ### Hello World example
174
+ Calling backend APIs is simplified through the use of targets in TargetJ. It includes a loader that streamlines API integration.
170
175
 
171
- ```bash
172
- import { App, TModel } from 'targetj';
176
+ In the example below, we define a target named 'load' that attempts to fetch a random user. Within the value() function, we initialize the API call. The first parameter specifies an ID that identifies the API call, which can also be used to access cached data.
173
177
 
174
- App(new TModel({ html: 'Hello World'}));
175
- ```
178
+ The target will remain active using the loop function, with value() continuing to return undefined while polling the system every 20ms (as specified in the interval property) until the loader retrieves the API result. When the API result arrives, it triggers onValueChange, which creates a user object based on the retrieved data. Additionally, we define two targets to handle scenarios for both fast and slow connections. The slow target is enabled if polling exceeds 100 times, while the fast target is enabled if the API result is retrieved in less than 600ms. If you restart the example, the result will be fetched from the cache instead of the API.
179
+
180
+ ![api loading example](https://targetj.io/img/apiLoading.png)
176
181
 
177
- ### Simple animation example
178
182
  ```bash
179
- import { App, TModel } from 'targetj';
183
+ import { App, TModel, getLoader, browser } from "targetj";
180
184
 
181
- App(new TModel({
182
- style: { backgroundColor: '#f00' },
183
- width: {
184
- value: 250,
185
- steps: 30,
186
- stepInterval: 50
185
+ App(
186
+ new TModel("apiCall", {
187
+ load: {
188
+ loop() { return !this.val(this.key); },
189
+ interval: 20,
190
+ value: function () {
191
+ var fetchId = "user";
192
+ getLoader().initSingleLoad(fetchId, { url: "https://targetj.io/api/randomUser", data: { id: fetchId } });
193
+ return getLoader().fetchResult(fetchId);
194
+ },
195
+ onValueChange(newValue) {
196
+ var user = newValue.result;
197
+ this.addChild(new TModel("userApi", {
198
+ width: 60,
199
+ height: 30,
200
+ html: user.name,
201
+ background: "#f00",
202
+ }));
203
+ },
187
204
  },
188
- height: {
189
- value: 250,
190
- steps: 30,
191
- stepInterval: 50
205
+ slowLoad: {
206
+ value() {
207
+ console.log("Connection issue: please try again later.");
208
+ },
209
+ enabledOn() {
210
+ return this.getTargetExecutionCount("load") > 100;
211
+ }
192
212
  },
193
- opacity: {
194
- value: 0.15,
195
- steps: 30,
196
- stepInterval: 50
213
+ fastLoad: {
214
+ value() {
215
+ //Loading is fast: We can load additional details about the user.
216
+ console.log(`Loading time was only ${this.val("load").loadingTime}ms`);
217
+ console.log(`Load target execution time was ${browser.now() - this.getTargetCreationTime("load")}ms`);
218
+ console.log(`Load target was executed ${this.getTargetExecutionCount("load")} times`);
219
+ },
220
+ enabledOn() {
221
+ return this.val("load") && this.val("load").loadingTime < 600;
222
+ }
197
223
  }
198
- }));
224
+ })
225
+ );
199
226
  ```
200
227
 
201
- It can also be written in a more compact form using arrays:
228
+ ## Event handling example
229
+
230
+ In the following example, the background color of the pane changes randomly whenever you click on it. The `canHandleEvents` target ensures that the object can handle touch events, such as clicks. However, we’ve set a limit of 10 executions for the background change. After reaching this limit, the component will no longer respond to click events. The `onClickEvent` is a system target that activates all associated targets when a click occurs. The `html` target tracks the number of executions and displays it within the pane.
231
+
232
+ ![event handling example](https://targetj.io/img/eventHandling2.png)
202
233
 
203
234
  ```bash
204
- import { App, TModel } from 'targetj';
235
+ import { App, TModel } from "targetj";
205
236
 
206
- App(new TModel({
207
- style: { backgroundColor: '#f00' },
208
- width: [ 250, 30, 50],
209
- height: [ 250, 30, 50],
210
- opacity: [ 0.15, 30, 50]
211
- }));
237
+ App(
238
+ new TModel("events", {
239
+ canHandleEvents() {
240
+ return this.getTargetExecutionCount("background") < 10 ? "touch" : "";
241
+ },
242
+ width: 120,
243
+ height: 120,
244
+ background: {
245
+ active: false,
246
+ initialValue: "#f00",
247
+ value() {
248
+ return "#" + Math.random().toString(16).slice(-6);
249
+ },
250
+ },
251
+ html() {
252
+ return this.getTargetExecutionCount("background");
253
+ },
254
+ onClickEvent: ["background", "canHandleEvents", "html"],
255
+ })
256
+ );
212
257
  ```
213
258
 
214
- ### More complicated example
259
+ ## Animation API example
260
+
261
+ TargetJ offers efficient and easy-to-control UI animation and manipulation through special targets such as x, y, width, height, scale, rotate, and opacity, which directly impact the UI. A complete list of these targets can be found in the "Special target names" section. For very intensive UI animations, you can leverage the Animation API. An example is provided below.
215
262
 
216
- You can find a running example, which also demonstrates how the code operates, at https://targetj.io/docs/declarative.html
263
+ ![animation api example](https://targetj.io/img/animationApi.png)
217
264
 
218
265
  ```bash
219
- import { App, TModel, getScreenWidth, getScreenHeight } from "targetj";
266
+ import { App, TModel } from "targetj";
220
267
 
221
268
  App(
222
- new TModel({
223
- add() {
224
- for (var i = 0; i < 10; i++) {
225
- this.addChild(
226
- new TModel("square", {
227
- width: 50,
228
- height: 50,
229
- style: { backgroundColor: "#f00" },
230
- rotate: {
231
- cycles: 1000,
232
- steps: 15,
233
- stepInterval: 50,
234
- value(key, cycle) {
235
- return [360, 0][cycle % 2];
236
- },
237
- },
238
- })
239
- );
240
- }
241
- },
269
+ new TModel("TargetJ vs Animation Api", {
270
+ x: 0,
271
+ y: 0,
272
+ width: 150,
273
+ height: 150,
242
274
  animate: {
243
- loop: true,
244
- stepInterval: 1600,
245
275
  value() {
246
- this.getChildren().forEach((child) => {
247
- child.setTargetValue("x", -child.getWidth());
248
- child.setTargetValue("x", getScreenWidth() + child.getWidth(), 30, 50);
249
- child.setTargetValue("y", Math.random() * getScreenHeight(), 30, 50);
276
+ const keyframes = [
277
+ {
278
+ transform: "translate(0, 0) rotate(0deg) scale(1)",
279
+ width: "80px",
280
+ height: "80px",
281
+ background: "orange",
282
+ },
283
+ {
284
+ transform: "translate(50px, 100px) rotate(180deg) scale(1.5)",
285
+ width: "120px",
286
+ height: "120px",
287
+ background: "brown",
288
+ },
289
+ {
290
+ transform: "translate(200px, 0) rotate(360deg) scale(1)",
291
+ width: "100px",
292
+ height: "100px",
293
+ background: "crimson",
294
+ },
295
+ {
296
+ transform: "translate(0, 0) rotate(360deg) scale(1)",
297
+ width: "150px",
298
+ height: "150px",
299
+ background: "purple",
300
+ },
301
+ ];
302
+
303
+ return this.$dom.animate(keyframes, {
304
+ duration: 5000,
305
+ iterations: 1,
306
+ easing: "ease-in-out",
250
307
  });
251
308
  },
252
309
  enabledOn() {
253
- return this.isTargetComplete("add");
310
+ return this.hasDom();
254
311
  },
255
312
  },
256
- width() {
257
- return getScreenWidth();
313
+ trackProgress: {
314
+ loop: true,
315
+ interval: 100,
316
+ value() {
317
+ const currentTime = this.val("animate").currentTime;
318
+ this.setTarget("html", (currentTime / 5000).toFixed(1));
319
+ return currentTime < 5000 ? false : true;
320
+ },
321
+ onValueChange(newValue) {
322
+ if (newValue) {
323
+ this.activateTarget("animate");
324
+ }
325
+ },
326
+ enabledOn() {
327
+ return this.isTargetComplete("animate");
328
+ },
329
+ },
330
+ })
331
+ );
332
+ ```
333
+
334
+ ## Simple Single Page App Example
335
+
336
+ Below is a simple single-page app that demonstrates how to develop a full application using TargetJ.
337
+
338
+ ![Single page app](https://targetj.io/img/singlePageApp2.png)
339
+
340
+ ```bash
341
+ import { App, TModel, getScreenHeight, getScreenWidth, getEvents, getPager } from "targetj";
342
+
343
+ App(
344
+ new TModel("app", {
345
+ start() {
346
+ const urlParts = window.location.href.split("/");
347
+ this.pageName = urlParts[urlParts.length - 1];
258
348
  },
259
- height() {
260
- return getScreenHeight();
349
+ canHandleEvents: "touch",
350
+ width: () => getScreenWidth(),
351
+ height: () => getScreenHeight(),
352
+ children() {
353
+ switch (this.pageName) {
354
+ case "page1":
355
+ return [Toolbar(), Page1()];
356
+ case "page2":
357
+ return [Toolbar(), Page2()];
358
+ default:
359
+ return [Toolbar(), HomePage()];
360
+ }
261
361
  },
362
+ onResize: ["width", "height"]
262
363
  })
263
364
  );
365
+
366
+ const Toolbar = () =>
367
+ new TModel("toolbar", {
368
+ start() {
369
+ ["home", "page1", "page2"].forEach((menu) => {
370
+ this.addChild(
371
+ new TModel("toolItem", {
372
+ canHandleEvents: "touch",
373
+ background: "bisque",
374
+ width: 100,
375
+ height: 50,
376
+ lineHeight: 50,
377
+ outerXEast: 0,
378
+ opacity: {
379
+ loop() { return this.getOpacity() === 1; },
380
+ value () { return getEvents().isTouchHandler(this) ? [1, 20] : [0.5, 20]; }
381
+ },
382
+ activePage: {
383
+ active: false,
384
+ value: () => getPager().openLink(menu),
385
+ },
386
+ onTouchEvent: ["opacity"],
387
+ onClickEvent: ["activePage"],
388
+ html: menu
389
+ })
390
+ );
391
+ });
392
+ },
393
+ height: 50,
394
+ width: () => getScreenWidth(),
395
+ onResize: ["width"],
396
+ });
397
+
398
+ const HomePage = () =>
399
+ new TModel("homePage", {
400
+ background: "yellow",
401
+ width: () => getScreenWidth(),
402
+ height: () => getScreenHeight(),
403
+ html: "home page",
404
+ onResize: ["width", "height"]
405
+ });
406
+
407
+ const Page1 = () =>
408
+ new TModel("page1", {
409
+ background: "blue",
410
+ width: () => getScreenWidth(),
411
+ height: () => getScreenHeight(),
412
+ html: "page 1",
413
+ onResize: ["width", "height"]
414
+ });
415
+
416
+ const Page2 = () =>
417
+ new TModel("page2", {
418
+ background: "green",
419
+ width: () => getScreenWidth(),
420
+ height: () => getScreenHeight(),
421
+ html: "page 2",
422
+ onResize: ["width", "height"]
423
+ });
264
424
  ```
265
425
 
426
+ ## Special target names
427
+
428
+ The following are special target names to impact the UI or control properties of TargetJ objects (called TModel):
429
+
430
+ 1. x, y, width, height: Set the location and dimensions of the object.
431
+ 2. opacity, scale, rotate: Set the opacity, scale, and rotation of the object.
432
+ 3. zIndex: Sets the z-order of the object.
433
+ 4. html: Sets the content of the object. By default, it will be interpreted as text.
434
+ 5. style: An object that sets the style of the object.
435
+ 6. css: A string that sets the CSS of the object.
436
+ 7. scrollLeft and scrollTop: Used for scrolling the object.
437
+ 8. leftMargin, rightMargin, topMargin, bottomMargin: Set the margins between objects.
438
+ 9. children: Sets the TModel children of the object.
439
+ 10. domHolder and domParent: Set to control the HTML element containment and how HTML is nested.
440
+ 11. isVisible: An optional boolean flag to explicitly control the visibility of the object instead of leaving it to TargetJ to calculate.
441
+ 12. canHaveDom: A boolean flag that sets if the object can have a DOM element in the page.
442
+ 13. canHandleEvents: Sets what events the object can handle
443
+ 14. widthFromDom and heightFromDom: Boolean flags that control if the width and height should be calculated from the DOM element.
444
+ 15. textOnly: A boolean flag that sets the type of content to be text or HTML.
445
+ 16. canBeBracketed: A boolean flag that controls if the object will be optimized and included in the TargetJ task process only when visible.
446
+ 17. isInFlow: A boolean flag that determines if the object will be used to calculate the content height and width of its parent.
447
+ 18. onResize: An array of targets that will be activated and executed after a resize event.
448
+ 19. onClickEvent: An array of targets that will be activated and executed after a click event.
449
+ 20. onTouchEvent: An array of targets that will be activated and executed after a touch event.
450
+ 21. onScrollEvent: An array of targets that will be activated and executed after a scroll event.
451
+ 22. onKeyEvent: An array of targets that will be activated and executed after a key event.
452
+ 22. onInvisibleEvent: An array of targets that will be activated and executed after the component becomes invisisble.
453
+
454
+ ## Features
455
+
456
+ As a result of using targets, we can develop web sites or apps with the following features:
457
+
458
+ - **No HTML required**: HTML tags are seldom necessary except for images.
459
+ - **No HTML nesting**: HTML nesting is seldom required in TargetJ. If it is required, nesting is done at runtime. Elements can be dynamically detached and incorporated into other elements, facilitating the easy reuse of components regardless of their location or attachment. It also opens the door for a new user experiences.
460
+ - **Next-level animation**: Users can program objects to move at varying speeds, pause at certain intervals, and repeat sequences based on various conditions. It allows the creation of complicated animations.
461
+ - **Control the flow of execution with time**: TargetJ simplifies the execution of various program segments at specific times, making it easy to sequence or parallelize numerous actions.
462
+ - **Handle events effortlessly**: In TargetJ, events are triggered synchronously and are designed so that any component can detect when an event occurs. Event handling can be simply implemented as conditions in the enabling functions of \'targets.\' This ensures that managing events is both simple and effective.
463
+ - **Easy to learn**: TargetJ simplifies development by employing the single concept of \'targets\' making it easy to learn.
464
+ - **Handle 100,000s of items**: TargetJ efficiently manages large collections of objects on a single page. This is done by its data structure and optimization algorithm. It divides a long list into a tree structure, monitoring only the branches that are visible to the user at any given time.
465
+ - **AI friendly**: With a unified concept of targets for all development, the ability to add and remove targets at runtime, and the capability to inspect various statuses of running objects, TargetJ is a strong candidate for AI-powered UI development.
466
+
467
+
266
468
  ## How to debug in TargetJ
267
469
  1. TargetJ.tapp.stop(): Stops the application.
268
470
  2. TargetJ.tapp.start(): Restarts the application
269
471
  3. TargetJ.tapp.throttle: Slows down the application. This represents the pause in milliseconds before starting another TargetJ task cycle. It is zero by default.
270
472
  4. TargetJ.tapp.debugLevel: Logs information about the TargetJ task cycle and its efficiency. It is zero by default. Set it to 1 to log basic information and 2 to log more detailed information.
271
- 5. Use `t()` to find an object from the browser console using its `oid`: Inspect its targetValues to display the status of its targets.
272
-
473
+ 5. Use `t()` to find an object from the browser console using its `oid`. Inspect all the vital properities using `t(oid).bug`.
474
+
273
475
  ## Documentation
274
476
  Explore the full potential of TargetJ and dive into our interactive documentation at www.targetj.io.
275
477
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "targetj",
3
- "version": "1.0.73",
3
+ "version": "1.0.74",
4
4
  "keywords": [
5
5
  "targetj"
6
6
  ],
@@ -24,6 +24,7 @@
24
24
  "devDependencies": {
25
25
  "webpack": "^5.91.0",
26
26
  "webpack-cli": "^5.1.4",
27
- "wepback": "^1.0.0"
27
+ "wepback": "^1.0.0",
28
+ "eslint-webpack-plugin": "^4.2.0"
28
29
  }
29
30
  }
package/src/$Dom.js CHANGED
@@ -41,7 +41,9 @@ $Dom.prototype.focus = function() {
41
41
  };
42
42
 
43
43
  $Dom.prototype.attr = function(name, value) {
44
- if (!this.element) return;
44
+ if (!this.element) {
45
+ return;
46
+ }
45
47
 
46
48
  if (TUtil.isDefined(value)) {
47
49
  this.element.setAttribute(name, value);
@@ -51,8 +53,10 @@ $Dom.prototype.attr = function(name, value) {
51
53
  };
52
54
 
53
55
  $Dom.prototype.value = function(value) {
54
- if (!this.element) return;
55
-
56
+ if (!this.element) {
57
+ return;
58
+ }
59
+
56
60
  if (TUtil.isDefined(value)) {
57
61
  this.element.value = value;
58
62
  } else {
@@ -61,8 +65,9 @@ $Dom.prototype.value = function(value) {
61
65
  };
62
66
 
63
67
  $Dom.prototype.select = function() {
64
- if (!this.element || typeof this.element.select !== 'function') return;
65
-
68
+ if (!this.element || typeof this.element.select !== 'function') {
69
+ return;
70
+ }
66
71
 
67
72
  this.element.select();
68
73
  };
@@ -138,7 +143,9 @@ $Dom.prototype.parent = function() {
138
143
 
139
144
  $Dom.prototype.detach = function() {
140
145
  $Dom.detach(this.element);
141
- if (this.$domParent && this.$domParent.childrenCount > 0) this.$domParent.childrenCount--;
146
+ if (this.$domParent && this.$domParent.childrenCount > 0) {
147
+ this.$domParent.childrenCount--;
148
+ }
142
149
  };
143
150
 
144
151
  $Dom.prototype.append$Dom = function($dom) {
package/src/Bracket.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { TModel } from "./TModel.js";
2
2
  import { TUtil } from "./TUtil.js";
3
3
  import { tapp } from "./App.js";
4
- import { browser } from "./Browser.js";
5
4
 
6
5
  function Bracket(parent) {
7
6
 
package/src/Browser.js CHANGED
@@ -2,29 +2,12 @@ var browser = {
2
2
  style: undefined,
3
3
  delayProcess: {},
4
4
  setup: function () {
5
-
6
- if (typeof String.prototype.trim !== 'function') {
7
- String.prototype.trim = function () {
8
- return this.replace(/^\s+|\s+$/g, '');
9
- };
10
- }
11
- if (typeof String.prototype.startsWith !== 'function') {
12
- String.prototype.startsWith = function (str) {
13
- return this.indexOf(str) === 0;
14
- };
15
- }
16
-
17
- if (typeof String.prototype.endsWith !== 'function') {
18
- String.prototype.endsWith = function (suffix) {
19
- return this.indexOf(suffix, this.length - suffix.length) !== -1;
20
- };
21
- }
22
-
23
5
  if (typeof String.prototype.hashCode !== 'function') {
24
6
  String.prototype.hashCode = function () {
25
7
  var hash = 0, i, chr, len;
26
- if (this.length === 0)
8
+ if (this.length === 0) {
27
9
  return hash;
10
+ }
28
11
  for (i = 0, len = this.length; i < len; i++) {
29
12
  chr = this.charCodeAt(i);
30
13
  hash = ((hash << 5) - hash) + chr;
@@ -39,69 +22,21 @@ var browser = {
39
22
  return this.map(function(o) { return o.oid; }).join(separator || " ");
40
23
  };
41
24
  }
42
-
43
- if (!Array.spaces) {
44
- Array.spaces = function(count) {
45
- return Array(count).join(' ');
46
- };
47
- }
48
-
49
-
50
-
51
- if (!Array.prototype.find) {
52
- Object.defineProperty(Array.prototype, 'find', {
53
- value: function(predicate) {
54
- if (this === null) {
55
- throw new TypeError('"this" is null or not defined');
56
- }
57
-
58
- var o = Object(this);
59
-
60
- var len = o.length >>> 0;
61
-
62
- if (typeof predicate !== 'function') {
63
- throw new TypeError('predicate must be a function');
64
- }
65
-
66
- var thisArg = arguments[1];
67
-
68
- var k = 0;
69
-
70
- while (k < len) {
71
- var kValue = o[k];
72
- if (predicate.call(thisArg, kValue, k, o)) {
73
- return kValue;
74
- }
75
- k++;
76
- }
77
-
78
- return undefined;
79
- },
80
- configurable: true,
81
- writable: true
82
- });
83
- }
84
-
85
25
 
86
26
  if (!document.getElementsByClassName) {
87
- var indexOf = [].indexOf || function (prop) {
88
- for (var i = 0; i < this.length; i++) {
89
- if (this[i] === prop)
90
- return i;
91
- }
92
- return -1;
93
- };
94
27
  var getElementsByClassName = function (className, context) {
95
- var elems = document.querySelectorAll ? context.querySelectorAll("." + className) : (function () {
96
- var all = context.getElementsByTagName("*"),
97
- elements = [],
98
- i = 0;
99
- for (; i < all.length; i++) {
100
- if (all[i].className && (" " + all[i].className + " ").indexOf(" " + className + " ") > -1 && indexOf.call(elements, all[i]) === -1)
101
- elements.push(all[i]);
28
+ var elems;
29
+ if (document.querySelectorAll) {
30
+ elems = context.querySelectorAll("." + className);
31
+ } else {
32
+ var all = context.getElementsByTagName("*");
33
+ elems = [];
34
+ for (var i = 0; i < all.length; i++) {
35
+ if (all[i].className && (" " + all[i].className + " ").indexOf(" " + className + " ") > -1 && elems.indexOf(all[i]) === -1) {
36
+ elems.push(all[i]);
37
+ }
102
38
  }
103
- return elements;
104
- })();
39
+ }
105
40
  return elems;
106
41
  };
107
42
  document.getElementsByClassName = function (className) {
@@ -112,39 +47,11 @@ var browser = {
112
47
  };
113
48
  }
114
49
 
115
- var lastTime = 0;
116
- var vendors = ['ms', 'moz', 'webkit', 'o'];
117
- for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
118
- window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
119
- window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
120
- window[vendors[x] + 'CancelRequestAnimationFrame'];
121
- }
122
-
123
- if (!window.requestAnimationFrame) {
124
- window.requestAnimationFrame = function (callback, element) {
125
- var currTime = new Date().getTime();
126
- var timeToCall = Math.max(0, 16 - (currTime - lastTime));
127
- var id = window.setTimeout(function () {
128
- callback(currTime + timeToCall);
129
- },
130
- timeToCall);
131
- lastTime = currTime + timeToCall;
132
- return id;
133
- };
134
- }
135
-
136
- if (!window.cancelAnimationFrame) {
137
- window.cancelAnimationFrame = function (id) {
138
- clearTimeout(id);
139
- };
140
- }
141
-
142
50
  this.style = {
143
51
  transform: this.prefixStyle('transform'),
144
52
  transitionTimingFunction: this.prefixStyle('transitionTimingFunction'),
145
53
  transitionDuration: this.prefixStyle('transitionDuration')
146
54
  };
147
-
148
55
  },
149
56
  log: function(condition) {
150
57
  if (condition === true) {
@@ -156,9 +63,7 @@ var browser = {
156
63
  prefixStyle: function (style) {
157
64
  var elementStyle = document.createElement('div').style;
158
65
 
159
- var vendor = '';
160
-
161
- var vendors = ['webkitT', 'MozT', 'msT', 'OT', 't'];
66
+ var vendor = '', vendors = ['webkitT', 'MozT', 'msT', 'OT', 't'];
162
67
 
163
68
  for (var i = 0; i < vendors.length; i++) {
164
69
  var transform = vendors[i] + 'ransform';
@@ -171,12 +76,6 @@ var browser = {
171
76
 
172
77
  return style;
173
78
  },
174
- getParameterByName: function (name) {
175
- name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
176
- var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
177
- results = regex.exec(location.search);
178
- return results === null ? 0 : decodeURIComponent(results[1].replace(/\+/g, " "));
179
- },
180
79
  now: Date.now || function () {
181
80
  return new Date().getTime();
182
81
  },
package/src/ColorUtil.js CHANGED
@@ -148,7 +148,9 @@ ColorUtil.color2Integers = function(color) {
148
148
  color = color ? color + '' : '';
149
149
  color = ColorUtil.colors[color.toLowerCase()] ? ColorUtil.colors[color.toLowerCase()] : color;
150
150
 
151
- if (!color) return;
151
+ if (!color) {
152
+ return;
153
+ }
152
154
 
153
155
  if (color.startsWith('#')) {
154
156
  color = color.slice(1);
@@ -120,7 +120,9 @@ EventListener.prototype.captureEvents = function() {
120
120
  };
121
121
 
122
122
  EventListener.prototype.handleEvent = function (event) {
123
- if (!event) return;
123
+ if (!event) {
124
+ return;
125
+ }
124
126
 
125
127
  var eventName, inputType, eventType, eventOrder;
126
128
 
@@ -167,7 +169,9 @@ EventListener.prototype.handleEvent = function (event) {
167
169
  this.clearTouch();
168
170
 
169
171
  this.touchCount = this.countTouches(event);
170
- if (this.preventDefault(tmodel, eventName)) event.preventDefault();
172
+ if (this.preventDefault(tmodel, eventName)) {
173
+ event.preventDefault();
174
+ }
171
175
 
172
176
  this.start0 = this.getTouch(event);
173
177
  this.start1 = this.getTouch(event, 1);
@@ -184,7 +188,9 @@ EventListener.prototype.handleEvent = function (event) {
184
188
  var touch = this.getTouch(event);
185
189
  this.cursor.x = touch.x;
186
190
  this.cursor.y = touch.y;
187
- if (this.preventDefault(tmodel, eventName)) event.preventDefault();
191
+ if (this.preventDefault(tmodel, eventName)) {
192
+ event.preventDefault();
193
+ }
188
194
  if (this.touchCount > 0) {
189
195
  this.move(event);
190
196
  event.stopPropagation();
@@ -194,7 +200,9 @@ EventListener.prototype.handleEvent = function (event) {
194
200
  case 'mouseup':
195
201
  case 'touchend':
196
202
 
197
- if (this.preventDefault(tmodel, eventName)) event.preventDefault();
203
+ if (this.preventDefault(tmodel, eventName)) {
204
+ event.preventDefault();
205
+ }
198
206
  this.end(event);
199
207
 
200
208
  if (this.start0) {
@@ -219,7 +227,9 @@ EventListener.prototype.handleEvent = function (event) {
219
227
 
220
228
  case 'wheel':
221
229
 
222
- if (this.preventDefault(tmodel, eventName)) event.preventDefault();
230
+ if (this.preventDefault(tmodel, eventName)) {
231
+ event.preventDefault();
232
+ }
223
233
  this.wheel(event);
224
234
  break;
225
235
 
@@ -20,7 +20,9 @@ function LoadingManager() {
20
20
 
21
21
  LoadingManager.prototype.initSingleLoad = function (fetchId, query, forceLoad) {
22
22
 
23
- if (this.isLoading(fetchId) || (this.isLoaded(fetchId) && !forceLoad) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) return;
23
+ if (this.isLoading(fetchId) || (this.isLoaded(fetchId) && !forceLoad) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) {
24
+ return;
25
+ }
24
26
 
25
27
  this.initLoadingMap(fetchId);
26
28
 
@@ -31,7 +33,9 @@ LoadingManager.prototype.initSingleLoad = function (fetchId, query, forceLoad)
31
33
  LoadingManager.prototype.initGroupLoad = function (fetchId, dataId, query, idKey, separator) {
32
34
  var groupId = JSON.stringify({ query: query, idKey: idKey, separator: separator });
33
35
 
34
- if (this.isLoading(fetchId) || this.isLoaded(fetchId) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) return;
36
+ if (this.isLoading(fetchId) || this.isLoaded(fetchId) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) {
37
+ return;
38
+ }
35
39
 
36
40
  this.initLoadingMap(fetchId);
37
41
 
@@ -45,7 +49,9 @@ LoadingManager.prototype.initGroupLoad = function (fetchId, dataId, query, idKey
45
49
 
46
50
  LoadingManager.prototype.initImgLoad = function (fetchId, src) {
47
51
 
48
- if (this.isLoading(fetchId) || this.isLoaded(fetchId) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) return;
52
+ if (this.isLoading(fetchId) || this.isLoaded(fetchId) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) {
53
+ return;
54
+ }
49
55
 
50
56
  this.initLoadingMap(fetchId, 'image');
51
57
 
@@ -110,7 +116,9 @@ LoadingManager.prototype.initLoadingMap = function(fetchId, category) {
110
116
  };
111
117
 
112
118
  LoadingManager.prototype.groupLoad = function () {
113
- if (!this.groupLoadList) return;
119
+ if (!this.groupLoadList) {
120
+ return;
121
+ }
114
122
 
115
123
  var groupIds = Object.keys(this.groupLoadList);
116
124
 
@@ -140,7 +148,9 @@ LoadingManager.prototype.groupLoad = function () {
140
148
  };
141
149
 
142
150
  LoadingManager.prototype.singleLoad = function () {
143
- if (!this.singleLoadList) return;
151
+ if (!this.singleLoadList) {
152
+ return;
153
+ }
144
154
 
145
155
  var keys = Object.keys(this.singleLoadList);
146
156
 
@@ -154,7 +164,9 @@ LoadingManager.prototype.singleLoad = function () {
154
164
  };
155
165
 
156
166
  LoadingManager.prototype.imgLoad = function () {
157
- if (!this.imgLoadList) return;
167
+ if (!this.imgLoadList) {
168
+ return;
169
+ }
158
170
 
159
171
  var keys = Object.keys(this.imgLoadList);
160
172
 
@@ -63,7 +63,9 @@ LocationManager.prototype.calculateContainer = function(container) {
63
63
  while (i < length && tapp.isRunning()) {
64
64
 
65
65
  var child = allChildren[i++];
66
- if (!child) continue;
66
+ if (!child) {
67
+ continue;
68
+ }
67
69
 
68
70
  var outerXEast = undefined, innerXEast = undefined;
69
71
 
@@ -137,7 +139,9 @@ LocationManager.prototype.calculateContainer = function(container) {
137
139
  child.val('contentHeight').forEach(function(key) {
138
140
  var preVal = child.val(key);
139
141
  child.val(key, child.getContentHeight());
140
- if (preVal !== child.val(key)) child.addToStyleTargetList(key);
142
+ if (preVal !== child.val(key)) {
143
+ child.addToStyleTargetList(key);
144
+ }
141
145
  });
142
146
  }
143
147
 
@@ -145,7 +149,9 @@ LocationManager.prototype.calculateContainer = function(container) {
145
149
  child.val('contentWidth').forEach(function(key) {
146
150
  var preVal = child.val(key);
147
151
  child.val(key, child.getContentWidth());
148
- if (preVal !== child.val(key)) child.addToStyleTargetList(key);
152
+ if (preVal !== child.val(key)) {
153
+ child.addToStyleTargetList(key);
154
+ }
149
155
  });
150
156
  }
151
157
 
package/src/Moves.js CHANGED
@@ -1,4 +1,3 @@
1
- import { Easing } from "./Easing.js";
2
1
  import { getScreenWidth } from "./App.js";
3
2
 
4
3
  function Moves() {}
@@ -1,4 +1,3 @@
1
- import { $Dom } from "./$Dom.js";
2
1
  import { TUtil } from "./TUtil.js";
3
2
  import { tapp } from "./App.js";
4
3
 
package/src/SearchUtil.js CHANGED
@@ -92,7 +92,9 @@ SearchUtil.findByType = function (type) {
92
92
 
93
93
  function search(container) {
94
94
 
95
- if (container.type === type) return container;
95
+ if (container.type === type) {
96
+ return container;
97
+ }
96
98
 
97
99
  var children = container.getChildren();
98
100
  var found;
@@ -101,7 +103,9 @@ SearchUtil.findByType = function (type) {
101
103
 
102
104
  tmodel = children[i];
103
105
 
104
- if (!tmodel) continue;
106
+ if (!tmodel) {
107
+ continue;
108
+ }
105
109
 
106
110
  if (tmodel.hasChildren()) {
107
111
  found = search(tmodel);
@@ -128,7 +132,9 @@ SearchUtil.findByTarget = function (target) {
128
132
 
129
133
  function search(container) {
130
134
 
131
- if (container.targets[target]) return container;
135
+ if (container.targets[target]) {
136
+ return container;
137
+ }
132
138
 
133
139
  var children = container.getChildren();
134
140
  var found;
@@ -137,7 +143,9 @@ SearchUtil.findByTarget = function (target) {
137
143
 
138
144
  tmodel = children[i];
139
145
 
140
- if (!tmodel) continue;
146
+ if (!tmodel) {
147
+ continue;
148
+ }
141
149
 
142
150
  if (tmodel.hasChildren()) {
143
151
  found = search(tmodel);
@@ -164,7 +172,9 @@ SearchUtil.find = function (oid) {
164
172
 
165
173
  function search(container) {
166
174
 
167
- if (container.oid === oid) return container;
175
+ if (container.oid === oid) {
176
+ return container;
177
+ }
168
178
 
169
179
  var children = container.getChildren();
170
180
  var found;
@@ -173,7 +183,9 @@ SearchUtil.find = function (oid) {
173
183
 
174
184
  tmodel = children[i];
175
185
 
176
- if (!tmodel) continue;
186
+ if (!tmodel) {
187
+ continue;
188
+ }
177
189
 
178
190
  if (tmodel.hasChildren()) {
179
191
  found = search(tmodel);
package/src/TModel.js CHANGED
@@ -5,8 +5,6 @@ import { TUtil } from "./TUtil.js";
5
5
  import { TargetUtil } from "./TargetUtil.js";
6
6
  import { TargetExecutor } from "./TargetExecutor";
7
7
  import { Viewport } from "./Viewport.js";
8
- import { Easing } from "./Easing.js";
9
- import { $Dom } from "./$Dom.js";
10
8
 
11
9
  function TModel(type, targets) {
12
10
 
@@ -119,7 +117,9 @@ TModel.prototype.getDomHolder = function() {
119
117
  };
120
118
 
121
119
  TModel.prototype.addToStyleTargetList = function(key) {
122
- if (!TargetUtil.styleTargetMap[key]) return;
120
+ if (!TargetUtil.styleTargetMap[key]) {
121
+ return;
122
+ }
123
123
 
124
124
  key = TargetUtil.transformMap[key] ? 'transform' : TargetUtil.dimMap[key] ? 'dim' : key;
125
125
 
@@ -541,7 +541,9 @@ TModel.prototype.resetTargetInitialValue = function(key) {
541
541
  TModel.prototype.updateTargetStatus = function(key) {
542
542
  var targetValue = this.targetValues[key];
543
543
 
544
- if (!targetValue) return;
544
+ if (!targetValue) {
545
+ return;
546
+ }
545
547
 
546
548
  var cycle = this.getTargetCycle(key);
547
549
  var cycles = this.getTargetCycles(key);
@@ -67,8 +67,7 @@ TModelManager.prototype.clear = function() {
67
67
  this.targetMethodMap = {};
68
68
  };
69
69
 
70
- TModelManager.prototype.visibles = function(type, list) {
71
- list = !list ? this.lists.visible : list;
70
+ TModelManager.prototype.visibles = function(type) {
72
71
  return this.lists.visible.filter(function(tmodel) { return tmodel.type === type || !type ; }).map(function(tmodel) { return tmodel.oid; });
73
72
  };
74
73
 
package/src/TUtil.js CHANGED
@@ -132,7 +132,9 @@ TUtil.limit = function (num, low, high) {
132
132
  };
133
133
 
134
134
  TUtil.formatNum = function (num, precision) {
135
- if (!num) return 0;
135
+ if (!num) {
136
+ return 0;
137
+ }
136
138
  var s = num.toString();
137
139
  var n = parseFloat(s);
138
140
  return n.toFixed(precision);
@@ -143,7 +145,9 @@ TUtil.distance = function(x1, y1, x2, y2) {
143
145
  };
144
146
 
145
147
  TUtil.getFullLink = function(link) {
146
- if (!TUtil.isDefined(link)) return;
148
+ if (!TUtil.isDefined(link)) {
149
+ return;
150
+ }
147
151
 
148
152
  if (link.indexOf('http') === 0) {
149
153
  return link;
@@ -1,7 +1,6 @@
1
1
  import { TargetUtil } from "./TargetUtil.js";
2
2
  import { TUtil } from "./TUtil.js";
3
3
  import { Easing } from "./Easing.js";
4
- import { browser } from "./Browser.js";
5
4
 
6
5
  function TargetExecutor() {}
7
6
 
@@ -1,4 +1,3 @@
1
- import { browser } from "./Browser.js";
2
1
  import { TUtil } from "./TUtil.js";
3
2
  import { TargetUtil } from "./TargetUtil.js";
4
3
  import { TargetExecutor } from "./TargetExecutor";
@@ -80,7 +79,9 @@ TargetManager.prototype.setActualValues = function(tmodel) {
80
79
  TargetManager.prototype.setActualValue = function(tmodel, key) {
81
80
  var targetValue = tmodel.targetValues[key];
82
81
 
83
- if (!targetValue) return;
82
+ if (!targetValue) {
83
+ return;
84
+ }
84
85
 
85
86
  if (!tmodel.isTargetEnabled(key)) {
86
87
  tapp.manager.scheduleRun(10, "setActualValue-disabled-" + tmodel.oid + "__" + key);
package/src/TargetUtil.js CHANGED
@@ -3,7 +3,6 @@ import { TModel } from "./TModel.js";
3
3
  import { getManager } from "./App.js";
4
4
  import { TUtil } from "./TUtil.js";
5
5
  import { ColorUtil } from "./ColorUtil.js";
6
- import { Easing } from "./Easing.js";
7
6
 
8
7
  function TargetUtil() {}
9
8
 
@@ -228,7 +227,7 @@ TargetUtil.handleValueChange = function(tmodel, key, newValue, lastValue, step,
228
227
  }
229
228
  };
230
229
 
231
- TargetUtil.morph = function(tmodel, key, fromValue, toValue, step, steps) {
230
+ TargetUtil.morph = function(tmodel, key, fromValue, toValue, step) {
232
231
 
233
232
  var easing = tmodel.getTargetEasing(key);
234
233
  var easingStep = easing ? easing(tmodel.getTargetStepPercent(key, step)) : tmodel.getTargetStepPercent(key, step);
package/src/Viewport.js CHANGED
@@ -1,6 +1,4 @@
1
- import { browser } from "./Browser.js";
2
1
  import { TUtil } from "./TUtil.js";
3
- import { tapp } from "./App.js";
4
2
  import { getScreenWidth, getScreenHeight } from "./App.js";
5
3
 
6
4
  function Viewport(tmodel) {
package/webpack.config.js CHANGED
@@ -1,13 +1,43 @@
1
- const path = require('path');
1
+ const path = require('path');
2
+ const ESLintPlugin = require('eslint-webpack-plugin');
2
3
 
3
4
  module.exports = {
4
- entry: './Exports.js',
5
- output: {
6
- library: {
7
- name: 'TargetJ',
8
- type: 'window'
5
+ entry: './Exports.js',
6
+ output: {
7
+ library: {
8
+ name: 'TargetJ',
9
+ type: 'window'
10
+ },
11
+ path: path.resolve(__dirname, './dist'),
12
+ filename: 'targetj.js'
9
13
  },
10
- path: path.resolve(__dirname, './dist'),
11
- filename: 'targetj.js'
12
- }
13
- };
14
+ plugins: [
15
+ new ESLintPlugin({
16
+ extensions: ['js'],
17
+ exclude: 'node_modules',
18
+ overrideConfig: {
19
+ env: {
20
+ browser: true,
21
+ es2021: true
22
+ },
23
+ extends: [
24
+ 'eslint:recommended'
25
+ ],
26
+ parserOptions: {
27
+ ecmaVersion: 12,
28
+ sourceType: 'module'
29
+ },
30
+ rules: {
31
+ 'curly': 'error',
32
+ 'eqeqeq': 'error',
33
+ 'dot-notation': 'off',
34
+ 'no-console': 'warn',
35
+ 'no-loop-func': 'off'
36
+ }
37
+ }
38
+ })
39
+ ],
40
+ resolve: {
41
+ extensions: ['.js']
42
+ }
43
+ };