targetj 1.0.168 → 1.0.169

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
@@ -200,7 +200,7 @@ Or in HTML:
200
200
 
201
201
  ## The Core of TargetJS
202
202
 
203
- TargetJS utilizes literal JavaScript objects for target definitions, providing a compact and readable format. The core principles are:
203
+ TargetJS utilizes literal JavaScript objects or HTML elements for target definitions, providing a compact and readable format. The core principles are:
204
204
 
205
205
  - Provide an internal wrapper (called "targets") for both properties and methods of the literal object.
206
206
  - Execute targets sequentially, in the order they are written leveraging ES2015's guaranteed property order.
@@ -438,6 +438,38 @@ App({
438
438
  height: getScreenHeight
439
439
  });
440
440
  ```
441
+ Or in HTML:
442
+
443
+ ```html
444
+ <div
445
+ tg-width="function() { return TargetJS.getScreenWidth(); }"
446
+ tg-height="function() { return TargetJS.getScreenHeight(); }"
447
+ tg-children="{ cycles: 9, interval: 500 }">
448
+ <div
449
+ tg-width="50"
450
+ tg-height="50"
451
+ tg-background="brown",
452
+ tg-left2right="function() {
453
+ const width = this.getWidth();
454
+ const parentWidth = this.getParentValue('width');
455
+ this.setTarget('x', { list: [ -width, parentWidth + width ] }, 400);
456
+ this.setTarget('y', Math.floor(Math.random() * (this.getParentValue('height') - this.getHeight())), 30);
457
+ }"
458
+ tg-_right2left$$="function() {
459
+ const width = this.getWidth();
460
+ const parentWidth = this.getParentValue('width');
461
+ this.setTarget('x', { list: [ parentWidth + width, -width ] }, 400);
462
+ }"
463
+ tg-_onesecond$$="function() {
464
+ this.setTarget('1second', 1, 1, 1000);
465
+ }"
466
+ tg-_repeat$$="function() {
467
+ this.activateTarget('left2right');
468
+ }"
469
+ >
470
+ </div>
471
+ </div>
472
+ ```
441
473
 
442
474
  ### Infinite Loading and Scrolling Example
443
475
 
@@ -496,6 +528,51 @@ App({
496
528
  });
497
529
  ```
498
530
 
531
+ Or in HTML:
532
+
533
+ ```HTML
534
+ <div
535
+ tg-domHolder="true"
536
+ tg-preventDefault="true"
537
+ tg-containerOverflowMode="always"
538
+ tg-width="return TargetJS.getScreenWidth();"
539
+ tg-height="return TargetJS.getScreenHeight();"
540
+ tg-children="function() {
541
+ const childrenCount = this.getChildren().length;
542
+ return Array.from({ length: 20 }, (_, i) => ({
543
+ width: [{ list: [100, 250] }, 15],
544
+ background: [{ list: ['#FCE961', '#B388FF'] }, 15, 15],
545
+ height: 48,
546
+ color: '#C2FC61',
547
+ textAlign: 'center',
548
+ lineHeight: 48,
549
+ bottomMargin: 2,
550
+ x: function() { return this.getCenterX(); },
551
+ validateVisibilityInParent: true,
552
+ html: childrenCount + i
553
+ }));
554
+ }"
555
+ tg-_load$="function() {
556
+ this.prevTargetValue.forEach(data =>
557
+ TargetJS.fetch(this, 'https://targetjs.io/api/randomUser', { id: data.oid })
558
+ );
559
+ }"
560
+ tg-_populate$$="function() {
561
+ this.prevTargetValue.forEach((data) =>
562
+ this.getChildByOid(data.id).setTarget('html', data.name)
563
+ );
564
+ }"
565
+ tg-onScroll="function() {
566
+ this.setTarget('scrollTop', Math.max(0, this.getScrollTop() + TargetJS.getEvents().deltaY()));
567
+ }"
568
+ tg-onVisibleChildrenChange="function() {
569
+ if (TargetJS.getEvents().dir() === 'down' && this.visibleChildren.length * 50 < this.getHeight()) {
570
+ this.activateTarget('children');
571
+ }
572
+ }"
573
+ ></div>
574
+ ```
575
+
499
576
  ## Simple SPA Example
500
577
 
501
578
  Below is a simple single-page application that demonstrates how to build a fully-featured app using TargetJS. Each page is represented by a textarea. You’ll notice that when you type something, switch to another page, and then return to the same page, your input remains preserved. This also applies to the page's scroll position—when you return, the page will open at the same scroll position where you left it, rather than defaulting to the top.
@@ -508,86 +585,169 @@ You can now assemble your app by incorporating code segments from the examples o
508
585
  import { App, getScreenHeight, getScreenWidth, getEvents, getPager } from "targetj";
509
586
 
510
587
  App({
511
- width() { return getScreenWidth(); },
512
- height() { return getScreenHeight(); },
513
- menubar() {
514
- return {
515
- children() {
516
- return ["home", "page1", "page2"].map(menu => ({
517
- canHandleEvents: "touch",
518
- background: "#fce961",
519
- width: 100,
520
- height: 50,
521
- lineHeight: 50,
522
- itemOverflowMode: 'never',
523
- opacity: 0.5,
524
- cursor: "pointer",
525
- html: menu,
526
- onEnter() {
527
- this.setTarget("opacity", 1, 20);
528
- },
529
- onLeave() {
530
- this.setTarget("opacity", 0.5, 20);
531
- },
532
- onClick() {
533
- this.setTarget("opacity", 0.5);
534
- getPager().openLink(menu);
535
- }
536
- }));
537
- },
588
+ domHolder: true,
589
+ width() { return getScreenWidth(); },
590
+ height() { return getScreenHeight(); },
591
+ menubar() {
592
+ return {
593
+ children() {
594
+ return ['home', 'page1', 'page2'].map(menu => {
595
+ return {
596
+ background: '#fce961',
597
+ width: 100,
538
598
  height: 50,
539
- width() { return getScreenWidth(); },
540
- onResize: ["width"]
541
- };
542
- },
543
- page() {
544
- return {
545
- width() { return getScreenWidth(); },
546
- height() { return getScreenHeight() - 50; },
547
- baseElement: 'textarea',
548
- keepEventDefault: [ 'touchstart', 'touchend', 'mousedown', 'mouseup' ],
549
- boxSizing: 'border-box',
550
- html: "main page",
551
- onKey() { this.setTarget('html', this.$dom.value()); },
552
- onResize: [ "width", "height" ]
553
- };
554
- },
555
- mainPage() {
556
- return {
557
- ...this.val('page'),
558
- background: "#e6f6fb",
559
- html: 'main page'
560
- };
561
- },
562
- page1() {
563
- return {
564
- ...this.val('page'),
565
- background: "#C2FC61",
566
- html: 'page1'
567
- };
568
- },
569
- page2() {
570
- return {
571
- ...this.val('page'),
572
- background: "#B388FF",
573
- html: 'page2'
574
- };
575
- },
576
- children() {
577
- const pageName = window.location.pathname.split("/").pop();
578
- switch (pageName) {
579
- case "page1":
580
- return [ this.val('menubar'), this.val('page1')];
581
- case "page2":
582
- return [ this.val('menubar'), this.val('page2')];
583
- default:
584
- return [ this.val('menubar'), this.val('mainPage') ];
585
- }
586
- },
587
- onResize: ["width", "height"]
599
+ lineHeight: 50,
600
+ itemOverflowMode: 'never',
601
+ opacity: 0.5,
602
+ cursor: 'pointer',
603
+ html: menu,
604
+ onEnter: function() {
605
+ this.setTarget('opacity', 1, 20);
606
+ },
607
+ onLeave: function() {
608
+ this.setTarget('opacity', 0.5, 20);
609
+ },
610
+ onClick: function() {
611
+ this.setTarget('opacity', 0.5);
612
+ getPager().updateBrowserUrl(menu);
613
+ this.activateAncestorTarget('updateChildren');
614
+ }
615
+ };
616
+ });
617
+ },
618
+ height: 50,
619
+ width: function() { return getScreenWidth(); },
620
+ onResize: ['width']
621
+ };
622
+ },
623
+ page() {
624
+ return {
625
+ width: function() { return getScreenWidth(); },
626
+ height: function() { return getScreenHeight() - 50; },
627
+ baseElement: 'textarea',
628
+ keepEventDefault: ['touchstart', 'touchend', 'mousedown', 'mouseup'],
629
+ boxSizing: 'border-box',
630
+ html: 'main page',
631
+ onKey() {
632
+ this.setTarget('html', this.$dom.value());
633
+ }
634
+ };
635
+ },
636
+ mainpage() {
637
+ return Object.assign({}, this.val('page'), {
638
+ background: '#e6f6fb',
639
+ html: 'main page'
640
+ });
641
+ },
642
+ page1() {
643
+ return Object.assign({}, this.val('page'), {
644
+ background: '#C2FC61',
645
+ html: 'page1'
646
+ });
647
+ },
648
+ page2() {
649
+ return Object.assign({}, this.val('page'), {
650
+ background: '#B388FF',
651
+ html: 'page2'
652
+ });
653
+ },
654
+ updateChildren() {
655
+ const pageName = window.location.pathname.split('/').pop();
656
+
657
+ if (this.hasChildren()) {
658
+ this.removeChild(this.getLastChild());
659
+ } else {
660
+ this.addChild(this.val('menubar'));
661
+ }
662
+ this.addChild(this.val(pageName) || this.val('mainpage'));
663
+ }
588
664
  });
589
665
  ```
590
666
 
667
+ Or in HTML:
668
+
669
+ ```HTML
670
+ <div
671
+ tg-domHolder="true"
672
+ tg-width="return TargetJS.getScreenWidth();"
673
+ tg-height="return TargetJS.getScreenHeight();"
674
+ tg-menubar="function() {
675
+ return {
676
+ children: function() {
677
+ return ['home', 'page1', 'page2'].map(function(menu) {
678
+ return {
679
+ background: '#fce961',
680
+ width: 100,
681
+ height: 50,
682
+ lineHeight: 50,
683
+ itemOverflowMode: 'never',
684
+ opacity: 0.5,
685
+ cursor: 'pointer',
686
+ html: menu,
687
+ onEnter: function() {
688
+ this.setTarget('opacity', 1, 20);
689
+ },
690
+ onLeave: function() {
691
+ this.setTarget('opacity', 0.5, 20);
692
+ },
693
+ onClick: function() {
694
+ this.setTarget('opacity', 0.5);
695
+ TargetJS.getPager().updateBrowserUrl(menu);
696
+ this.activateAncestorTarget('update-children');
697
+ }
698
+ };
699
+ });
700
+ },
701
+ height: 50,
702
+ width: function() { return TargetJS.getScreenWidth(); },
703
+ onResize: ['width']
704
+ };
705
+ }"
706
+ tg-page="
707
+ return {
708
+ width: function() { return TargetJS.getScreenWidth(); },
709
+ height: function() { return TargetJS.getScreenHeight() - 50; },
710
+ baseElement: 'textarea',
711
+ keepEventDefault: ['touchstart', 'touchend', 'mousedown', 'mouseup'],
712
+ boxSizing: 'border-box',
713
+ html: 'main page',
714
+ onKey: function() {
715
+ this.setTarget('html', this.$dom.value());
716
+ },
717
+ onResize: ['width', 'height']
718
+ };"
719
+ tg-mainpage="function() {
720
+ return Object.assign({}, this.val('page'), {
721
+ background: '#e6f6fb',
722
+ html: 'main page'
723
+ });
724
+ }"
725
+ tg-page1="function() {
726
+ return Object.assign({}, this.val('page'), {
727
+ background: '#C2FC61',
728
+ html: 'page1'
729
+ });
730
+ }"
731
+ tg-page2="function() {
732
+ return Object.assign({}, this.val('page'), {
733
+ background: '#B388FF',
734
+ html: 'page2'
735
+ });
736
+ }"
737
+ tg-test="function() { console.log('test'); }"
738
+ tg-update-children="function() {
739
+ const pageName = window.location.pathname.split('/').pop();
740
+
741
+ if (this.hasChildren()) {
742
+ this.removeChild(this.getLastChild());
743
+ } else {
744
+ this.addChild(this.val('menubar'));
745
+ }
746
+ this.addChild(this.val(pageName) || this.val('mainpage'));
747
+ }"
748
+ ></div>
749
+ ```
750
+
591
751
  ## Using TargetJS as a Library Example
592
752
 
593
753
  Here is an example that creates 1000 rows. The first argument, 'rows,' is used to find an element with the ID 'rows.' If no such element exists, it will be created at the top of the page. The OnDomEvent target activates the targets defined in its value when the DOM is found or created, eliminating the need for conditions to verify the DOM's availability before executing the target.
package/build/App.js CHANGED
@@ -73,6 +73,9 @@ var AppFn = function AppFn() {
73
73
  tmodel.val('height', _$Dom.$Dom.getScreenHeight());
74
74
  if (my.tRoot) {
75
75
  my.tRoot.getChildren().forEach(function (t) {
76
+ if (t.val('sourceDom')) {
77
+ return;
78
+ }
76
79
  var child = new _TModel.TModel(t.type, t.targets);
77
80
  tmodel.addChild(child);
78
81
  });
@@ -10,6 +10,7 @@ var _TUtil = require("./TUtil.js");
10
10
  var _TModelUtil = require("./TModelUtil.js");
11
11
  var _TargetUtil = require("./TargetUtil.js");
12
12
  var _TargetData = require("./TargetData.js");
13
+ var _SearchUtil = require("./SearchUtil.js");
13
14
  var _$Dom = require("./$Dom.js");
14
15
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
15
16
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -276,7 +277,7 @@ var BaseModel = exports.BaseModel = /*#__PURE__*/function () {
276
277
  });
277
278
  } else if (domExists && !_TUtil.TUtil.isDefined(this.targets['reuseDomDefinition'])) {
278
279
  this.targets['reuseDomDefinition'] = true;
279
- if (!_TUtil.TUtil.isDefined('excludeXYCalc')) {
280
+ if (!_TUtil.TUtil.isDefined(this.targets['excludeXYCalc'])) {
280
281
  this.targets['excludeXYCalc'] = true;
281
282
  }
282
283
  if (!_TUtil.TUtil.isDefined(this.targets['x'])) {
@@ -959,6 +960,12 @@ var BaseModel = exports.BaseModel = /*#__PURE__*/function () {
959
960
  }
960
961
  return this;
961
962
  }
963
+ }, {
964
+ key: "activateAncestorTarget",
965
+ value: function activateAncestorTarget(key) {
966
+ var _SearchUtil$findParen;
967
+ (_SearchUtil$findParen = _SearchUtil.SearchUtil.findParentByTarget(this, key)) === null || _SearchUtil$findParen === void 0 || _SearchUtil$findParen.activateTarget(key);
968
+ }
962
969
  }, {
963
970
  key: "manageChildTargetExecution",
964
971
  value: function manageChildTargetExecution(child, shouldCalculateChildTargets) {
@@ -134,17 +134,16 @@ var PageManager = exports.PageManager = /*#__PURE__*/function () {
134
134
  }
135
135
  }, {
136
136
  key: "updateBrowserUrl",
137
- value: function updateBrowserUrl(link) {
138
- var currentState = window.history.state;
139
- if (!currentState.browserUrl) {
140
- _App.tApp.tRoot.$dom = _$Dom.$Dom.query('#tgjs-root') ? new _$Dom.$Dom('#tgjs-root') : new _$Dom.$Dom('body');
141
- this.pageCache[document.URL] = {
142
- link: document.URL,
143
- html: _App.tApp.tRoot.$dom.innerHTML(),
144
- oids: _objectSpread({}, _App.App.oids),
145
- visibleList: _toConsumableArray(_App.tApp.manager.lists.visible),
146
- tRoot: _App.tApp.tRoot
147
- };
137
+ value: function updateBrowserUrl(link, updateHistory) {
138
+ _App.tApp.tRoot.$dom = _$Dom.$Dom.query('#tgjs-root') ? new _$Dom.$Dom('#tgjs-root') : new _$Dom.$Dom('body');
139
+ this.pageCache[document.URL] = {
140
+ link: document.URL,
141
+ html: _App.tApp.tRoot.$dom.innerHTML(),
142
+ oids: _objectSpread({}, _App.App.oids),
143
+ visibleList: _toConsumableArray(_App.tApp.manager.lists.visible),
144
+ tRoot: _App.tApp.tRoot
145
+ };
146
+ if (updateHistory) {
148
147
  history.pushState({
149
148
  browserUrl: link
150
149
  }, "", link);
package/build/TModel.js CHANGED
@@ -136,6 +136,9 @@ var TModel = exports.TModel = /*#__PURE__*/function (_BaseModel) {
136
136
  }, {
137
137
  key: "removeChild",
138
138
  value: function removeChild(child) {
139
+ if (!child) {
140
+ return;
141
+ }
139
142
  this.deletedChildren.push(child);
140
143
  this.removeFromUpdatingChildren(child);
141
144
  this.childrenUpdateFlag = true;
package/build/TUtil.js CHANGED
@@ -201,6 +201,7 @@ var TUtil = exports.TUtil = /*#__PURE__*/function () {
201
201
  };
202
202
  } else {
203
203
  _value.isVisible = true;
204
+ _value.sourceDom = true;
204
205
  (0, _App.tRoot)().addChild(_value);
205
206
  }
206
207
  }
@@ -561,7 +561,15 @@ _defineProperty(TargetData, "attributesToTargets", {
561
561
  textdecoration: 'textDecoration',
562
562
  boxshadow: 'boxShadow',
563
563
  fontweight: 'fontWeight',
564
- willchange: 'willChange'
564
+ willchange: 'willChange',
565
+ domholder: 'domHolder',
566
+ shouldcalculatechildtargets: 'shouldCalculateChildTargets',
567
+ coretargets: 'coreTargets',
568
+ domparent: 'domParent',
569
+ containeroverflowmode: 'containerOverflowMode',
570
+ itemoverflowmode: 'itemOverflowMode',
571
+ onvisiblechildrenchange: 'onVisibleChildrenChange',
572
+ onchildrenchange: 'onChildrenChange'
565
573
  });
566
574
  _defineProperty(TargetData, "targetToEventsMapping", {
567
575
  onStart: ['touchStart', 'mouseStart'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "targetj",
3
- "version": "1.0.168",
3
+ "version": "1.0.169",
4
4
  "description": "TargetJS is a JavaScript framework designed for creating animated and efficient web user interfaces.",
5
5
  "keywords": ["targetjs"],
6
6
  "main": "Export.js",