@mulsense/xnew 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/xnew.d.ts +63 -46
- package/dist/xnew.js +241 -226
- package/dist/xnew.mjs +241 -226
- package/package.json +1 -1
package/dist/xnew.js
CHANGED
|
@@ -143,11 +143,11 @@
|
|
|
143
143
|
else if (this.options.easing === 'ease-in') {
|
|
144
144
|
p = Math.pow((1.0 - Math.pow((1.0 - p), 0.5)), 2.0);
|
|
145
145
|
}
|
|
146
|
-
else if (this.options.easing === 'ease') {
|
|
147
|
-
p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
p = (
|
|
146
|
+
else if (this.options.easing === 'ease' || this.options.easing === 'ease-in-out') {
|
|
147
|
+
// p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
148
|
+
const bias = (this.options.easing === 'ease') ? 0.7 : 1.0;
|
|
149
|
+
const s = Math.pow(p, bias);
|
|
150
|
+
p = s * s * (3 - 2 * s);
|
|
151
151
|
}
|
|
152
152
|
(_b = (_a = this.options).transition) === null || _b === void 0 ? void 0 : _b.call(_a, p);
|
|
153
153
|
});
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
class
|
|
208
|
+
class Eventor {
|
|
209
209
|
constructor() {
|
|
210
210
|
this.map = new MapMap();
|
|
211
211
|
}
|
|
@@ -525,12 +525,93 @@
|
|
|
525
525
|
// utils
|
|
526
526
|
//----------------------------------------------------------------------------------------------------
|
|
527
527
|
const SYSTEM_EVENTS = ['start', 'update', 'render', 'stop', 'finalize'];
|
|
528
|
+
class UnitPromise {
|
|
529
|
+
constructor(promise, component) {
|
|
530
|
+
this.promise = promise;
|
|
531
|
+
this.component = component;
|
|
532
|
+
}
|
|
533
|
+
then(callback) {
|
|
534
|
+
const snapshot = Unit.snapshot(Unit.currentUnit);
|
|
535
|
+
this.promise = this.promise.then((...args) => Unit.scope(snapshot, callback, ...args));
|
|
536
|
+
return this;
|
|
537
|
+
}
|
|
538
|
+
catch(callback) {
|
|
539
|
+
const snapshot = Unit.snapshot(Unit.currentUnit);
|
|
540
|
+
this.promise = this.promise.catch((...args) => Unit.scope(snapshot, callback, ...args));
|
|
541
|
+
return this;
|
|
542
|
+
}
|
|
543
|
+
finally(callback) {
|
|
544
|
+
const snapshot = Unit.snapshot(Unit.currentUnit);
|
|
545
|
+
this.promise = this.promise.finally(() => Unit.scope(snapshot, callback));
|
|
546
|
+
return this;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
class UnitTimer {
|
|
550
|
+
constructor(options) {
|
|
551
|
+
this.stack = [];
|
|
552
|
+
this.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, { options, snapshot: Unit.snapshot(Unit.currentUnit) });
|
|
553
|
+
}
|
|
554
|
+
clear() {
|
|
555
|
+
this.stack = [];
|
|
556
|
+
this.unit.finalize();
|
|
557
|
+
}
|
|
558
|
+
timeout(timeout, duration = 0) {
|
|
559
|
+
UnitTimer.execute(this, { timeout, duration, iterations: 1 });
|
|
560
|
+
return this;
|
|
561
|
+
}
|
|
562
|
+
iteration(timeout, duration = 0, iterations = -1) {
|
|
563
|
+
UnitTimer.execute(this, { timeout, duration, iterations });
|
|
564
|
+
return this;
|
|
565
|
+
}
|
|
566
|
+
transition(transition, duration = 0, easing) {
|
|
567
|
+
UnitTimer.execute(this, { transition, duration, iterations: 1, easing });
|
|
568
|
+
return this;
|
|
569
|
+
}
|
|
570
|
+
static execute(timer, options) {
|
|
571
|
+
if (timer.unit._.state === 'finalized') {
|
|
572
|
+
timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, { options, snapshot: Unit.snapshot(Unit.currentUnit) });
|
|
573
|
+
}
|
|
574
|
+
else if (timer.stack.length === 0) {
|
|
575
|
+
timer.stack.push({ options, snapshot: Unit.snapshot(Unit.currentUnit) });
|
|
576
|
+
timer.unit.on('finalize', () => UnitTimer.next(timer));
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
timer.stack.push({ options, snapshot: Unit.snapshot(Unit.currentUnit) });
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
static next(timer) {
|
|
583
|
+
if (timer.stack.length > 0) {
|
|
584
|
+
timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, timer.stack.shift());
|
|
585
|
+
timer.unit.on('finalize', () => UnitTimer.next(timer));
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
static Component(unit, { options, snapshot }) {
|
|
589
|
+
let counter = 0;
|
|
590
|
+
const timer = new Timer({
|
|
591
|
+
transition: (p) => {
|
|
592
|
+
if (options.transition)
|
|
593
|
+
Unit.scope(snapshot, options.transition, p);
|
|
594
|
+
},
|
|
595
|
+
timeout: () => {
|
|
596
|
+
if (options.transition)
|
|
597
|
+
Unit.scope(snapshot, options.transition, 1.0);
|
|
598
|
+
if (options.timeout)
|
|
599
|
+
Unit.scope(snapshot, options.timeout);
|
|
600
|
+
if (options.iterations && counter >= options.iterations - 1) {
|
|
601
|
+
unit.finalize();
|
|
602
|
+
}
|
|
603
|
+
counter++;
|
|
604
|
+
}, duration: options.duration, iterations: options.iterations, easing: options.easing
|
|
605
|
+
});
|
|
606
|
+
unit.on('finalize', () => timer.clear());
|
|
607
|
+
}
|
|
608
|
+
}
|
|
528
609
|
//----------------------------------------------------------------------------------------------------
|
|
529
610
|
// unit
|
|
530
611
|
//----------------------------------------------------------------------------------------------------
|
|
531
612
|
class Unit {
|
|
532
|
-
constructor(parent, target, component, props
|
|
533
|
-
var _a
|
|
613
|
+
constructor(parent, target, component, props) {
|
|
614
|
+
var _a;
|
|
534
615
|
let baseElement;
|
|
535
616
|
if (target instanceof HTMLElement || target instanceof SVGElement) {
|
|
536
617
|
baseElement = target;
|
|
@@ -545,15 +626,14 @@
|
|
|
545
626
|
if (typeof component === 'function') {
|
|
546
627
|
baseComponent = component;
|
|
547
628
|
}
|
|
548
|
-
else if (
|
|
549
|
-
baseComponent = (unit) => { unit.element.textContent = component; };
|
|
629
|
+
else if (component !== undefined) {
|
|
630
|
+
baseComponent = (unit) => { unit.element.textContent = component.toString(); };
|
|
550
631
|
}
|
|
551
632
|
else {
|
|
552
633
|
baseComponent = (unit) => { };
|
|
553
634
|
}
|
|
554
635
|
const baseContext = (_a = parent === null || parent === void 0 ? void 0 : parent._.currentContext) !== null && _a !== void 0 ? _a : { stack: null };
|
|
555
|
-
|
|
556
|
-
this._ = { parent, target, baseElement, baseContext, baseComponent, props, config: { protect } };
|
|
636
|
+
this._ = { parent, target, baseElement, baseContext, baseComponent, props };
|
|
557
637
|
parent === null || parent === void 0 ? void 0 : parent._.children.push(this);
|
|
558
638
|
Unit.initialize(this, null);
|
|
559
639
|
}
|
|
@@ -582,7 +662,6 @@
|
|
|
582
662
|
Unit.initialize(this, anchor);
|
|
583
663
|
}
|
|
584
664
|
static initialize(unit, anchor) {
|
|
585
|
-
var _a, _b;
|
|
586
665
|
const backup = Unit.currentUnit;
|
|
587
666
|
Unit.currentUnit = unit;
|
|
588
667
|
unit._ = Object.assign(unit._, {
|
|
@@ -592,15 +671,16 @@
|
|
|
592
671
|
anchor,
|
|
593
672
|
state: 'invoked',
|
|
594
673
|
tostart: true,
|
|
595
|
-
|
|
674
|
+
protected: false,
|
|
675
|
+
ancestors: unit._.parent ? [unit._.parent, ...unit._.parent._.ancestors] : [],
|
|
596
676
|
children: [],
|
|
597
677
|
elements: [],
|
|
598
678
|
promises: [],
|
|
599
|
-
|
|
679
|
+
extends: [],
|
|
600
680
|
listeners: new MapMap(),
|
|
601
681
|
defines: {},
|
|
602
682
|
systems: { start: [], update: [], render: [], stop: [], finalize: [] },
|
|
603
|
-
|
|
683
|
+
eventor: new Eventor(),
|
|
604
684
|
});
|
|
605
685
|
// nest html element
|
|
606
686
|
if (typeof unit._.target === 'string') {
|
|
@@ -618,26 +698,21 @@
|
|
|
618
698
|
unit._.children.forEach((child) => child.finalize());
|
|
619
699
|
unit._.systems.finalize.forEach(({ execute }) => execute());
|
|
620
700
|
unit.off();
|
|
621
|
-
unit._.
|
|
701
|
+
unit._.extends.forEach(({ component }) => Unit.component2units.delete(component, unit));
|
|
622
702
|
if (unit._.elements.length > 0) {
|
|
623
703
|
unit._.baseElement.removeChild(unit._.elements[0]);
|
|
624
704
|
unit._.currentElement = unit._.baseElement;
|
|
625
705
|
}
|
|
626
706
|
// reset defines
|
|
627
707
|
Object.keys(unit._.defines).forEach((key) => {
|
|
628
|
-
|
|
629
|
-
delete unit[key];
|
|
630
|
-
}
|
|
708
|
+
delete unit[key];
|
|
631
709
|
});
|
|
632
710
|
unit._.defines = {};
|
|
633
711
|
unit._.state = 'finalized';
|
|
634
712
|
}
|
|
635
713
|
}
|
|
636
|
-
static nest(unit,
|
|
637
|
-
|
|
638
|
-
throw new Error('This function can not be called after initialized.');
|
|
639
|
-
}
|
|
640
|
-
const match = htmlString.match(/<((\w+)[^>]*?)\/?>/);
|
|
714
|
+
static nest(unit, tag, textContent) {
|
|
715
|
+
const match = tag.match(/<((\w+)[^>]*?)\/?>/);
|
|
641
716
|
if (match !== null) {
|
|
642
717
|
let element;
|
|
643
718
|
if (unit._.anchor !== null) {
|
|
@@ -651,47 +726,53 @@
|
|
|
651
726
|
}
|
|
652
727
|
unit._.currentElement = element;
|
|
653
728
|
if (textContent !== undefined) {
|
|
654
|
-
element.textContent = textContent;
|
|
729
|
+
element.textContent = textContent.toString();
|
|
655
730
|
}
|
|
656
731
|
unit._.elements.push(element);
|
|
657
732
|
return element;
|
|
658
733
|
}
|
|
659
734
|
else {
|
|
660
|
-
throw new Error(`
|
|
735
|
+
throw new Error(`xnew.nest: invalid html string [${tag}]`);
|
|
661
736
|
}
|
|
662
737
|
}
|
|
663
738
|
static extend(unit, component, props) {
|
|
664
739
|
var _a;
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
740
|
+
const find = unit._.extends.find(({ component: c }) => c === component);
|
|
741
|
+
if (find !== undefined) {
|
|
742
|
+
throw new Error(`The component is already extended.`);
|
|
743
|
+
}
|
|
744
|
+
else {
|
|
745
|
+
const backupComponent = unit._.currentComponent;
|
|
746
|
+
unit._.currentComponent = component;
|
|
747
|
+
const defines = (_a = component(unit, props)) !== null && _a !== void 0 ? _a : {};
|
|
748
|
+
unit._.currentComponent = backupComponent;
|
|
749
|
+
Object.keys(defines).forEach((key) => {
|
|
750
|
+
if (unit[key] !== undefined && unit._.defines[key] === undefined) {
|
|
751
|
+
throw new Error(`The property "${key}" already exists.`);
|
|
752
|
+
}
|
|
753
|
+
const descriptor = Object.getOwnPropertyDescriptor(defines, key);
|
|
754
|
+
const wrapper = { configurable: true, enumerable: true };
|
|
755
|
+
const snapshot = Unit.snapshot(unit);
|
|
756
|
+
if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) || (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set)) {
|
|
757
|
+
if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get)
|
|
758
|
+
wrapper.get = (...args) => Unit.scope(snapshot, descriptor.get, ...args);
|
|
759
|
+
if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set)
|
|
760
|
+
wrapper.set = (...args) => Unit.scope(snapshot, descriptor.set, ...args);
|
|
761
|
+
}
|
|
762
|
+
else if (typeof (descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) === 'function') {
|
|
763
|
+
wrapper.value = (...args) => Unit.scope(snapshot, descriptor.value, ...args);
|
|
764
|
+
}
|
|
765
|
+
else if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) !== undefined) {
|
|
766
|
+
wrapper.get = () => defines[key];
|
|
767
|
+
wrapper.set = (value) => defines[key] = value;
|
|
768
|
+
}
|
|
769
|
+
Object.defineProperty(unit._.defines, key, wrapper);
|
|
770
|
+
Object.defineProperty(unit, key, wrapper);
|
|
771
|
+
});
|
|
772
|
+
Unit.component2units.add(component, unit);
|
|
773
|
+
unit._.extends.push({ component, defines });
|
|
774
|
+
return defines;
|
|
775
|
+
}
|
|
695
776
|
}
|
|
696
777
|
static start(unit) {
|
|
697
778
|
if (unit._.tostart === false)
|
|
@@ -735,10 +816,6 @@
|
|
|
735
816
|
});
|
|
736
817
|
Unit.rootUnit.on('finalize', () => ticker.clear());
|
|
737
818
|
}
|
|
738
|
-
static wrap(unit, listener) {
|
|
739
|
-
const snapshot = Unit.snapshot(unit);
|
|
740
|
-
return (...args) => Unit.scope(snapshot, listener, ...args);
|
|
741
|
-
}
|
|
742
819
|
static scope(snapshot, func, ...args) {
|
|
743
820
|
if (snapshot.unit._.state === 'finalized') {
|
|
744
821
|
return;
|
|
@@ -789,15 +866,16 @@
|
|
|
789
866
|
types.forEach((type) => Unit.off(this, type, listener));
|
|
790
867
|
}
|
|
791
868
|
static on(unit, type, listener, options) {
|
|
869
|
+
const snapshot = Unit.snapshot(Unit.currentUnit);
|
|
870
|
+
const execute = (...args) => Unit.scope(snapshot, listener, ...args);
|
|
792
871
|
if (SYSTEM_EVENTS.includes(type)) {
|
|
793
|
-
unit._.systems[type].push({ listener, execute
|
|
872
|
+
unit._.systems[type].push({ listener, execute });
|
|
794
873
|
}
|
|
795
874
|
if (unit._.listeners.has(type, listener) === false) {
|
|
796
|
-
const execute = Unit.wrap(Unit.currentUnit, listener);
|
|
797
875
|
unit._.listeners.set(type, listener, { element: unit.element, component: unit._.currentComponent, execute });
|
|
798
876
|
Unit.type2units.add(type, unit);
|
|
799
877
|
if (/^[A-Za-z]/.test(type)) {
|
|
800
|
-
unit._.
|
|
878
|
+
unit._.eventor.add(unit.element, type, execute, options);
|
|
801
879
|
}
|
|
802
880
|
}
|
|
803
881
|
}
|
|
@@ -811,7 +889,7 @@
|
|
|
811
889
|
return;
|
|
812
890
|
unit._.listeners.delete(type, listener);
|
|
813
891
|
if (/^[A-Za-z]/.test(type)) {
|
|
814
|
-
unit._.
|
|
892
|
+
unit._.eventor.remove(type, item.execute);
|
|
815
893
|
}
|
|
816
894
|
});
|
|
817
895
|
if (unit._.listeners.has(type) === false) {
|
|
@@ -824,7 +902,7 @@
|
|
|
824
902
|
if (type[0] === '+') {
|
|
825
903
|
(_a = Unit.type2units.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
|
|
826
904
|
var _a;
|
|
827
|
-
const find = [unit, ...unit._.ancestors].find(u => u._.
|
|
905
|
+
const find = [unit, ...unit._.ancestors].find(u => u._.protected === true);
|
|
828
906
|
if (find === undefined || current._.ancestors.includes(find) === true || current === find) {
|
|
829
907
|
(_a = unit._.listeners.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((item) => item.execute(...args));
|
|
830
908
|
}
|
|
@@ -841,92 +919,10 @@
|
|
|
841
919
|
// event
|
|
842
920
|
//----------------------------------------------------------------------------------------------------
|
|
843
921
|
Unit.type2units = new MapSet();
|
|
844
|
-
//----------------------------------------------------------------------------------------------------
|
|
845
|
-
// unit promise
|
|
846
|
-
//----------------------------------------------------------------------------------------------------
|
|
847
|
-
class UnitPromise {
|
|
848
|
-
constructor(promise, component) {
|
|
849
|
-
this.promise = promise;
|
|
850
|
-
this.component = component;
|
|
851
|
-
}
|
|
852
|
-
then(callback) {
|
|
853
|
-
this.promise = this.promise.then(Unit.wrap(Unit.currentUnit, callback));
|
|
854
|
-
return this;
|
|
855
|
-
}
|
|
856
|
-
catch(callback) {
|
|
857
|
-
this.promise = this.promise.catch(Unit.wrap(Unit.currentUnit, callback));
|
|
858
|
-
return this;
|
|
859
|
-
}
|
|
860
|
-
finally(callback) {
|
|
861
|
-
this.promise = this.promise.finally(Unit.wrap(Unit.currentUnit, callback));
|
|
862
|
-
return this;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
//----------------------------------------------------------------------------------------------------
|
|
866
|
-
// unit timer
|
|
867
|
-
//----------------------------------------------------------------------------------------------------
|
|
868
|
-
class UnitTimer {
|
|
869
|
-
constructor(options) {
|
|
870
|
-
this.stack = [];
|
|
871
|
-
this.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
872
|
-
}
|
|
873
|
-
clear() {
|
|
874
|
-
this.stack = [];
|
|
875
|
-
this.unit.finalize();
|
|
876
|
-
}
|
|
877
|
-
timeout(timeout, duration = 0) {
|
|
878
|
-
UnitTimer.execute(this, { timeout, duration, iterations: 1 });
|
|
879
|
-
return this;
|
|
880
|
-
}
|
|
881
|
-
iteration(timeout, duration = 0, iterations = -1) {
|
|
882
|
-
UnitTimer.execute(this, { timeout, duration, iterations });
|
|
883
|
-
return this;
|
|
884
|
-
}
|
|
885
|
-
transition(transition, duration = 0, easing) {
|
|
886
|
-
UnitTimer.execute(this, { transition, duration, iterations: 1, easing });
|
|
887
|
-
return this;
|
|
888
|
-
}
|
|
889
|
-
static execute(timer, options) {
|
|
890
|
-
if (timer.unit._.state === 'finalized') {
|
|
891
|
-
timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
892
|
-
}
|
|
893
|
-
else if (timer.stack.length === 0) {
|
|
894
|
-
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
895
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
896
|
-
}
|
|
897
|
-
else {
|
|
898
|
-
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
static next(timer) {
|
|
902
|
-
if (timer.stack.length > 0) {
|
|
903
|
-
timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, timer.stack.shift());
|
|
904
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
static Component(unit, options) {
|
|
908
|
-
let counter = 0;
|
|
909
|
-
const timer = new Timer({
|
|
910
|
-
transition: (p) => {
|
|
911
|
-
if (options.transition)
|
|
912
|
-
Unit.scope(options.snapshot, options.transition, p);
|
|
913
|
-
},
|
|
914
|
-
timeout: () => {
|
|
915
|
-
if (options.transition)
|
|
916
|
-
Unit.scope(options.snapshot, options.transition, 1.0);
|
|
917
|
-
if (options.timeout)
|
|
918
|
-
Unit.scope(options.snapshot, options.timeout);
|
|
919
|
-
if (options.iterations && counter >= options.iterations - 1) {
|
|
920
|
-
unit.finalize();
|
|
921
|
-
}
|
|
922
|
-
counter++;
|
|
923
|
-
}, duration: options.duration, iterations: options.iterations, easing: options.easing
|
|
924
|
-
});
|
|
925
|
-
unit.on('finalize', () => timer.clear());
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
922
|
|
|
929
|
-
function
|
|
923
|
+
const xnew$1 = Object.assign(function (...args) {
|
|
924
|
+
if (Unit.rootUnit === undefined)
|
|
925
|
+
Unit.reset();
|
|
930
926
|
let target;
|
|
931
927
|
if (args[0] instanceof HTMLElement || args[0] instanceof SVGElement) {
|
|
932
928
|
target = args.shift(); // an existing html element
|
|
@@ -939,29 +935,26 @@
|
|
|
939
935
|
}
|
|
940
936
|
const component = args.shift();
|
|
941
937
|
const props = args.shift();
|
|
942
|
-
return
|
|
943
|
-
}
|
|
944
|
-
const xnew$1 = Object.assign(function (...args) {
|
|
945
|
-
if (Unit.rootUnit === undefined)
|
|
946
|
-
Unit.reset();
|
|
947
|
-
const { target, component, props } = parseArguments(...args);
|
|
948
|
-
return new Unit(Unit.currentUnit, target, component, props, { protect: false });
|
|
938
|
+
return new Unit(Unit.currentUnit, target, component, props);
|
|
949
939
|
}, {
|
|
950
940
|
/**
|
|
951
941
|
* Creates a nested HTML/SVG element within the current component
|
|
952
|
-
* @param
|
|
942
|
+
* @param tag - HTML or SVG tag name (e.g., '<div>', '<span>', '<svg>')
|
|
953
943
|
* @returns The created HTML/SVG element
|
|
954
944
|
* @throws Error if called after component initialization
|
|
955
945
|
* @example
|
|
956
946
|
* const div = xnew.nest('<div>')
|
|
957
947
|
* div.textContent = 'Hello'
|
|
958
948
|
*/
|
|
959
|
-
nest(
|
|
949
|
+
nest(tag, textContent) {
|
|
960
950
|
try {
|
|
961
|
-
|
|
951
|
+
if (Unit.currentUnit._.state !== 'invoked') {
|
|
952
|
+
throw new Error('xnew.nest can not be called after initialized.');
|
|
953
|
+
}
|
|
954
|
+
return Unit.nest(Unit.currentUnit, tag, textContent);
|
|
962
955
|
}
|
|
963
956
|
catch (error) {
|
|
964
|
-
console.error('xnew.nest(
|
|
957
|
+
console.error('xnew.nest(tag: string): ', error);
|
|
965
958
|
throw error;
|
|
966
959
|
}
|
|
967
960
|
},
|
|
@@ -969,13 +962,16 @@
|
|
|
969
962
|
* Extends the current component with another component's functionality
|
|
970
963
|
* @param component - Component function to extend with
|
|
971
964
|
* @param props - Optional properties to pass to the extended component
|
|
972
|
-
* @returns
|
|
965
|
+
* @returns defines returned by the extended component
|
|
973
966
|
* @throws Error if called after component initialization
|
|
974
967
|
* @example
|
|
975
968
|
* const api = xnew.extend(BaseComponent, { data: {} })
|
|
976
969
|
*/
|
|
977
970
|
extend(component, props) {
|
|
978
971
|
try {
|
|
972
|
+
if (Unit.currentUnit._.state !== 'invoked') {
|
|
973
|
+
throw new Error('xnew.extend can not be called after initialized.');
|
|
974
|
+
}
|
|
979
975
|
return Unit.extend(Unit.currentUnit, component, props);
|
|
980
976
|
}
|
|
981
977
|
catch (error) {
|
|
@@ -1110,6 +1106,15 @@
|
|
|
1110
1106
|
throw error;
|
|
1111
1107
|
}
|
|
1112
1108
|
},
|
|
1109
|
+
/**
|
|
1110
|
+
* Emits a custom event to components
|
|
1111
|
+
* @param type - Event type to emit (prefix with '+' for global events, '-' for local events)
|
|
1112
|
+
* @param args - Additional arguments to pass to event listeners
|
|
1113
|
+
* @returns void
|
|
1114
|
+
* @example
|
|
1115
|
+
* xnew.emit('+globalevent', { data: 123 }); // Global event
|
|
1116
|
+
* xnew.emit('-localevent', { data: 123 }); // Local event
|
|
1117
|
+
*/
|
|
1113
1118
|
emit(type, ...args) {
|
|
1114
1119
|
try {
|
|
1115
1120
|
return Unit.emit(type, ...args);
|
|
@@ -1159,100 +1164,111 @@
|
|
|
1159
1164
|
transition(transition, duration = 0, easing = 'linear') {
|
|
1160
1165
|
return new UnitTimer({ transition, duration, easing, iterations: 1 });
|
|
1161
1166
|
},
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
+
/**
|
|
1168
|
+
* Call this method within a component function to enable protection.
|
|
1169
|
+
* Protected components will not respond to global events emitted via xnew.emit,
|
|
1170
|
+
* and will be excluded from xnew.find searches.
|
|
1171
|
+
* @example
|
|
1172
|
+
* function MyComponent(unit) {
|
|
1173
|
+
* xnew.protect();
|
|
1174
|
+
* // Component logic here
|
|
1175
|
+
* }
|
|
1176
|
+
*/
|
|
1177
|
+
protect() {
|
|
1178
|
+
Unit.currentUnit._.protected = true;
|
|
1167
1179
|
},
|
|
1168
1180
|
});
|
|
1169
1181
|
|
|
1170
|
-
function
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
xnew$1.timeout(() => xnew$1.emit('-transition', { state
|
|
1182
|
+
function OpenAndClose(unit, { state: initialState = 0.0 } = {}) {
|
|
1183
|
+
let state = Math.max(0.0, Math.min(1.0, initialState));
|
|
1184
|
+
let direction = state === 1.0 ? +1 : (state === 0.0 ? -1 : null);
|
|
1185
|
+
let timer = xnew$1.timeout(() => xnew$1.emit('-transition', { state }));
|
|
1174
1186
|
return {
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
unit.close();
|
|
1187
|
+
toggle(duration = 200, easing = 'ease') {
|
|
1188
|
+
if (direction === null || direction < 0) {
|
|
1189
|
+
unit.open(duration, easing);
|
|
1179
1190
|
}
|
|
1180
|
-
else
|
|
1181
|
-
unit.
|
|
1191
|
+
else {
|
|
1192
|
+
unit.close(duration, easing);
|
|
1182
1193
|
}
|
|
1183
1194
|
},
|
|
1184
|
-
open() {
|
|
1185
|
-
if (
|
|
1186
|
-
|
|
1195
|
+
open(duration = 200, easing = 'ease') {
|
|
1196
|
+
if (direction === null || direction < 0) {
|
|
1197
|
+
direction = +1;
|
|
1198
|
+
const d = 1 - state;
|
|
1199
|
+
timer === null || timer === void 0 ? void 0 : timer.clear();
|
|
1200
|
+
timer = xnew$1.transition((x) => {
|
|
1201
|
+
const y = x < 1.0 ? (1 - x) * d : 0.0;
|
|
1202
|
+
state = 1.0 - y;
|
|
1203
|
+
xnew$1.emit('-transition', { state, type: '-transition' });
|
|
1204
|
+
}, duration * d, easing)
|
|
1205
|
+
.timeout(() => {
|
|
1206
|
+
xnew$1.emit('-opened', { state, type: '-opened' });
|
|
1207
|
+
});
|
|
1187
1208
|
}
|
|
1188
1209
|
},
|
|
1189
|
-
close() {
|
|
1190
|
-
if (
|
|
1191
|
-
|
|
1210
|
+
close(duration = 200, easing = 'ease') {
|
|
1211
|
+
if (direction === null || direction > 0) {
|
|
1212
|
+
direction = -1;
|
|
1213
|
+
const d = state;
|
|
1214
|
+
timer === null || timer === void 0 ? void 0 : timer.clear();
|
|
1215
|
+
timer = xnew$1.transition((x) => {
|
|
1216
|
+
const y = x < 1.0 ? (1 - x) * d : 0.0;
|
|
1217
|
+
state = y;
|
|
1218
|
+
xnew$1.emit('-transition', { state, type: '-transition' });
|
|
1219
|
+
}, duration * d, easing)
|
|
1220
|
+
.timeout(() => {
|
|
1221
|
+
xnew$1.emit('-closed', { state, type: '-closed' });
|
|
1222
|
+
});
|
|
1192
1223
|
}
|
|
1193
|
-
}
|
|
1224
|
+
},
|
|
1194
1225
|
};
|
|
1195
1226
|
}
|
|
1196
1227
|
|
|
1197
|
-
function Screen(unit, { width
|
|
1198
|
-
const size = { width, height };
|
|
1199
|
-
const
|
|
1200
|
-
|
|
1228
|
+
function Screen(unit, { width, height, fit = 'contain' } = {}) {
|
|
1229
|
+
const size = { width: width !== null && width !== void 0 ? width : 800, height: height !== null && height !== void 0 ? height : 600 };
|
|
1230
|
+
const outer = xnew$1.nest('<div style="position: relative; width: 100%; height: 100%; overflow: hidden;">');
|
|
1231
|
+
xnew$1().on('resize', resize);
|
|
1201
1232
|
const absolute = xnew$1.nest('<div style="position: absolute; margin: auto; container-type: size; overflow: hidden;">');
|
|
1202
|
-
const canvas = xnew$1(`<canvas width="${width}" height="${height}" style="width: 100%; height: 100%; vertical-align: bottom; user-select: none; user-drag: none; pointer-events: auto;">`);
|
|
1233
|
+
const canvas = xnew$1(`<canvas width="${size.width}" height="${size.height}" style="width: 100%; height: 100%; vertical-align: bottom; user-select: none; user-drag: none; pointer-events: auto;">`);
|
|
1203
1234
|
resize();
|
|
1204
1235
|
function resize() {
|
|
1205
|
-
const aspect = size.width / size.height;
|
|
1206
1236
|
const style = { width: '100%', height: '100%', top: 0, left: 0, bottom: 0, right: 0 };
|
|
1207
1237
|
if (fit === 'contain') {
|
|
1208
|
-
|
|
1209
|
-
|
|
1238
|
+
const aspect = size.width / size.height;
|
|
1239
|
+
if (outer.clientWidth < outer.clientHeight * aspect) {
|
|
1240
|
+
style.height = Math.floor(outer.clientWidth / aspect) + 'px';
|
|
1210
1241
|
}
|
|
1211
1242
|
else {
|
|
1212
|
-
style.width = Math.floor(
|
|
1243
|
+
style.width = Math.floor(outer.clientHeight * aspect) + 'px';
|
|
1213
1244
|
}
|
|
1214
1245
|
}
|
|
1215
1246
|
else if (fit === 'cover') {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
style.
|
|
1247
|
+
const aspect = size.width / size.height;
|
|
1248
|
+
if (outer.clientWidth < outer.clientHeight * aspect) {
|
|
1249
|
+
style.width = Math.floor(outer.clientHeight * aspect) + 'px';
|
|
1250
|
+
style.left = Math.floor((outer.clientWidth - outer.clientHeight * aspect) / 2) + 'px';
|
|
1219
1251
|
style.right = 'auto';
|
|
1220
1252
|
}
|
|
1221
1253
|
else {
|
|
1222
|
-
style.height = Math.floor(
|
|
1223
|
-
style.top = Math.floor((
|
|
1254
|
+
style.height = Math.floor(outer.clientWidth / aspect) + 'px';
|
|
1255
|
+
style.top = Math.floor((outer.clientHeight - outer.clientWidth / aspect) / 2) + 'px';
|
|
1224
1256
|
style.bottom = 'auto';
|
|
1225
1257
|
}
|
|
1226
1258
|
}
|
|
1227
|
-
else
|
|
1259
|
+
else if (fit === 'resize') {
|
|
1260
|
+
size.width = outer.clientWidth > 0 ? outer.clientWidth : size.width;
|
|
1261
|
+
size.height = outer.clientHeight > 0 ? outer.clientHeight : size.height;
|
|
1262
|
+
console.log(size);
|
|
1263
|
+
canvas.element.setAttribute('width', size.width + 'px');
|
|
1264
|
+
canvas.element.setAttribute('height', size.height + 'px');
|
|
1265
|
+
}
|
|
1228
1266
|
Object.assign(absolute.style, style);
|
|
1229
1267
|
}
|
|
1230
1268
|
return {
|
|
1231
1269
|
get canvas() {
|
|
1232
1270
|
return canvas.element;
|
|
1233
1271
|
},
|
|
1234
|
-
resize(width, height) {
|
|
1235
|
-
size.width = width;
|
|
1236
|
-
size.height = height;
|
|
1237
|
-
canvas.element.setAttribute('width', width + 'px');
|
|
1238
|
-
canvas.element.setAttribute('height', height + 'px');
|
|
1239
|
-
resize();
|
|
1240
|
-
},
|
|
1241
|
-
};
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
function Modal(unit, { duration = 200, easing = 'ease' } = {}) {
|
|
1245
|
-
xnew$1.context('xnew.modalframe', unit);
|
|
1246
|
-
xnew$1.nest('<div style="position: fixed; inset: 0; z-index: 1000;">');
|
|
1247
|
-
unit.on('click', ({ event }) => unit.close());
|
|
1248
|
-
unit.on('-transition', ({ state }) => unit.state = state);
|
|
1249
|
-
xnew$1.transition((x) => xnew$1.emit('-transition', { state: x }), duration, easing);
|
|
1250
|
-
return {
|
|
1251
|
-
state: 0.0,
|
|
1252
|
-
close() {
|
|
1253
|
-
xnew$1.transition((x) => xnew$1.emit('-transition', { state: 1.0 - x }), duration, easing)
|
|
1254
|
-
.timeout(() => unit.finalize());
|
|
1255
|
-
}
|
|
1256
1272
|
};
|
|
1257
1273
|
}
|
|
1258
1274
|
|
|
@@ -1307,7 +1323,7 @@
|
|
|
1307
1323
|
xnew$1.emit('-up', { type: '-up', vector });
|
|
1308
1324
|
});
|
|
1309
1325
|
}
|
|
1310
|
-
function
|
|
1326
|
+
function DPad(unit, { diagonal = true, stroke = 'currentColor', strokeOpacity = 0.8, strokeWidth = 2, strokeLinejoin = 'round', fill = '#FFF', fillOpacity = 0.8 } = {}) {
|
|
1311
1327
|
const outer = xnew$1.nest(`<div style="position: relative; width: 100%; height: 100%;">`);
|
|
1312
1328
|
let newsize = Math.min(outer.clientWidth, outer.clientHeight);
|
|
1313
1329
|
const inner = xnew$1.nest(`<div style="position: absolute; width: ${newsize}px; height: ${newsize}px; margin: auto; inset: 0; cursor: pointer; pointer-select: none; pointer-events: auto; overflow: hidden;">`);
|
|
@@ -1600,10 +1616,9 @@
|
|
|
1600
1616
|
|
|
1601
1617
|
const basics = {
|
|
1602
1618
|
Screen,
|
|
1603
|
-
|
|
1604
|
-
Accordion,
|
|
1619
|
+
OpenAndClose,
|
|
1605
1620
|
AnalogStick,
|
|
1606
|
-
|
|
1621
|
+
DPad,
|
|
1607
1622
|
};
|
|
1608
1623
|
const audio = {
|
|
1609
1624
|
load(path) {
|