@ngutil/aria 0.0.56 → 0.0.57

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.
@@ -562,6 +562,314 @@ function direction(prev, curr) {
562
562
  // const w = svc.watch(document.createElement("div"), DragAndDrop)
563
563
  function noop() { }
564
564
 
565
+ const COMPILE_CACHE = {};
566
+ function compile(selector) {
567
+ return (COMPILE_CACHE[selector] ??= _compile(parse(selector)));
568
+ }
569
+ class Cursor {
570
+ get ch() {
571
+ return this.data[this.position];
572
+ }
573
+ constructor(data) {
574
+ this.data = data;
575
+ this.position = 0;
576
+ }
577
+ inc(value = 1) {
578
+ this.position += value;
579
+ return this;
580
+ }
581
+ eatWs() {
582
+ let end = this.position;
583
+ while (end < this.data.length && /[ \r\n\t]/.test(this.data[end])) {
584
+ end++;
585
+ }
586
+ this.position = end;
587
+ return this;
588
+ }
589
+ is(ch) {
590
+ if (ch.length === 1) {
591
+ return this.ch === ch;
592
+ }
593
+ const begin = this.position;
594
+ const end = begin + ch.length;
595
+ return this.data.substring(begin, end) === ch;
596
+ }
597
+ eof() {
598
+ return this.position >= this.data.length;
599
+ }
600
+ set(position) {
601
+ this.position = position;
602
+ return this;
603
+ }
604
+ }
605
+ /**
606
+ * expression:
607
+ * - "*": any
608
+ * - "name without dot": top level: eg. "busy" or "disabled", this is equal to "busy.*"
609
+ * - "name with dot": nested: eg. "busy.self" or "busy.loading"
610
+ * - negate: "!busy", "!busy.*", "!busy.save"
611
+ * - OR: "busy.* || !disabled.*"
612
+ * - AND: "busy.* && !disabled.*"
613
+ * - GROUP: "(busy || disabled) && !readonly"
614
+ * - Shorted of multiple source of same base: "busy{load,save}", if one of load or save is true, the result is true
615
+ */
616
+ function parse(selector) {
617
+ const cursor = new Cursor(selector);
618
+ const res = expression(cursor.eatWs());
619
+ if (res == null) {
620
+ throw new Error(`invalid selector: ${selector}`);
621
+ }
622
+ if (!cursor.eof()) {
623
+ throw new Error(`unexpected charcter: ${selector[res.end]} at ${res.end}`);
624
+ }
625
+ return res;
626
+ }
627
+ function expression(cursor, skip) {
628
+ return binary(cursor) || leftExpr(cursor);
629
+ }
630
+ function leftExpr(cursor) {
631
+ const begin = cursor.position;
632
+ const left = unary(cursor) || group(cursor) || load(cursor);
633
+ if (left != null) {
634
+ return left;
635
+ }
636
+ cursor.set(begin);
637
+ return null;
638
+ }
639
+ function group(cursor) {
640
+ const begin = cursor.position;
641
+ if (cursor.is("(")) {
642
+ const expr = expression(cursor.inc().eatWs());
643
+ if (cursor.eatWs().is(")")) {
644
+ cursor.inc();
645
+ return binary(cursor.eatWs(), expr) || expr;
646
+ }
647
+ }
648
+ cursor.set(begin);
649
+ return null;
650
+ }
651
+ function binary(cursor, left = null) {
652
+ const begin = cursor.position;
653
+ left = left ?? leftExpr(cursor);
654
+ if (left != null) {
655
+ cursor.eatWs();
656
+ const result = and(left, cursor) || or(left, cursor);
657
+ if (result != null) {
658
+ return result;
659
+ }
660
+ }
661
+ cursor.set(begin);
662
+ return null;
663
+ }
664
+ function and(left, cursor) {
665
+ if (cursor.is("&&")) {
666
+ cursor.inc(2);
667
+ const right = expression(cursor.eatWs());
668
+ if (right == null) {
669
+ return null;
670
+ }
671
+ return { type: 5 /* TokenType.And */, left, right, begin: left.begin, end: cursor.position };
672
+ }
673
+ return null;
674
+ }
675
+ function or(left, cursor) {
676
+ if (cursor.is("||")) {
677
+ cursor.inc(2);
678
+ const right = expression(cursor.eatWs());
679
+ if (right == null) {
680
+ return null;
681
+ }
682
+ return { type: 4 /* TokenType.Or */, left, right, begin: left.begin, end: cursor.position };
683
+ }
684
+ return null;
685
+ }
686
+ function unary(cursor) {
687
+ const begin = cursor.position;
688
+ if (cursor.is("!")) {
689
+ const expr = leftExpr(cursor.inc().eatWs());
690
+ if (expr != null) {
691
+ return { type: 3 /* TokenType.Negate */, value: expr, begin, end: cursor.position };
692
+ }
693
+ }
694
+ cursor.set(begin);
695
+ return null;
696
+ }
697
+ function load(cursor) {
698
+ cursor.eatWs();
699
+ const _any = any(cursor);
700
+ if (_any != null) {
701
+ return _any;
702
+ }
703
+ const base = name(cursor);
704
+ if (base == null) {
705
+ return null;
706
+ }
707
+ cursor.eatWs();
708
+ const sub = loadSingle(cursor) || loadMulti(cursor);
709
+ if (sub == null) {
710
+ return base;
711
+ }
712
+ else if (Array.isArray(sub)) {
713
+ return {
714
+ type: 8 /* TokenType.MultiSubscript */,
715
+ base,
716
+ subscripts: sub,
717
+ begin: base.begin,
718
+ end: sub[sub.length - 1].end
719
+ };
720
+ }
721
+ else {
722
+ return { type: 7 /* TokenType.Subscript */, base, subscript: sub, begin: base.begin, end: sub.end };
723
+ }
724
+ }
725
+ function loadSingle(cursor) {
726
+ const begin = cursor.position;
727
+ if (cursor.is(".")) {
728
+ cursor.inc().eatWs();
729
+ const prop = any(cursor) || name(cursor);
730
+ if (prop != null) {
731
+ return prop;
732
+ }
733
+ }
734
+ cursor.set(begin);
735
+ return null;
736
+ }
737
+ function loadMulti(cursor) {
738
+ const begin = cursor.position;
739
+ if (cursor.is("{")) {
740
+ const names = [];
741
+ let entry = null;
742
+ cursor.inc().eatWs();
743
+ while ((entry = name(cursor))) {
744
+ names.push(entry);
745
+ cursor.eatWs();
746
+ if (cursor.is(",")) {
747
+ cursor.inc();
748
+ }
749
+ cursor.eatWs();
750
+ if (cursor.is("}")) {
751
+ if (names.length === 0) {
752
+ throw new Error("expected name");
753
+ }
754
+ cursor.inc();
755
+ return names;
756
+ }
757
+ }
758
+ }
759
+ cursor.set(begin);
760
+ return null;
761
+ }
762
+ function name(cursor) {
763
+ const begin = cursor.position;
764
+ while (!cursor.eof() && isNameCh(cursor.ch)) {
765
+ cursor.inc();
766
+ }
767
+ if (cursor.position > begin) {
768
+ return { type: 2 /* TokenType.Name */, begin, end: cursor.position, value: cursor.data.slice(begin, cursor.position) };
769
+ }
770
+ cursor.set(begin);
771
+ return null;
772
+ }
773
+ function isNameCh(ch) {
774
+ return /[^.,{}()!\s&|]/.test(ch);
775
+ }
776
+ function any(cursor) {
777
+ if (cursor.is("*")) {
778
+ const begin = cursor.position;
779
+ cursor.inc();
780
+ return { type: 1 /* TokenType.Any */, begin, end: cursor.position };
781
+ }
782
+ return null;
783
+ }
784
+ function _compile(ast, parent) {
785
+ switch (ast.type) {
786
+ case 1 /* TokenType.Any */:
787
+ return compileAny(ast, parent);
788
+ case 7 /* TokenType.Subscript */:
789
+ return compileSubscript(ast, parent);
790
+ case 8 /* TokenType.MultiSubscript */:
791
+ return compileMultiSubscript(ast, parent);
792
+ case 2 /* TokenType.Name */:
793
+ return compileName(ast, parent);
794
+ case 3 /* TokenType.Negate */:
795
+ return compileNot(_compile(ast.value, parent));
796
+ case 4 /* TokenType.Or */:
797
+ return compileOr(_compile(ast.left, parent), _compile(ast.right, parent));
798
+ case 5 /* TokenType.And */:
799
+ return compileAnd(_compile(ast.left, parent), _compile(ast.right, parent));
800
+ }
801
+ return () => false;
802
+ }
803
+ function compileAny(ast, parent) {
804
+ if (parent) {
805
+ return v => {
806
+ if (v[parent] == null) {
807
+ return false;
808
+ }
809
+ return Object.values(v[parent]).some(v => v === true);
810
+ };
811
+ }
812
+ else {
813
+ return v => {
814
+ for (const entry of Object.values(v)) {
815
+ if (Object.values(entry).some(v => v === true)) {
816
+ return true;
817
+ }
818
+ }
819
+ return false;
820
+ };
821
+ }
822
+ }
823
+ function compileSubscript(ast, parent) {
824
+ parent ??= ast.base.value;
825
+ if (ast.subscript.type === 1 /* TokenType.Any */) {
826
+ return compileAny(ast.subscript, parent);
827
+ }
828
+ if (ast.subscript.type === 2 /* TokenType.Name */) {
829
+ return compileName(ast.subscript, parent);
830
+ }
831
+ return () => false;
832
+ }
833
+ function compileMultiSubscript(ast, parent) {
834
+ parent ??= ast.base.value;
835
+ const values = ast.subscripts.map(v => compileSubscript({ type: 7 /* TokenType.Subscript */, base: ast.base, subscript: v, begin: v.begin, end: v.end }, parent));
836
+ if (values.length === 1) {
837
+ return values[0];
838
+ }
839
+ else {
840
+ let result = values[0];
841
+ for (let i = 1; i < values.length; i++) {
842
+ result = compileOr(result, values[i]);
843
+ }
844
+ return result;
845
+ }
846
+ }
847
+ function compileName(ast, parent) {
848
+ if (parent) {
849
+ return v => {
850
+ if (v[parent] == null) {
851
+ return false;
852
+ }
853
+ return !!v[parent][ast.value];
854
+ };
855
+ }
856
+ else {
857
+ return v => {
858
+ const many = v[ast.value];
859
+ return many != null && Object.values(many).some(v => v === true);
860
+ };
861
+ }
862
+ }
863
+ function compileNot(compiled) {
864
+ return v => !compiled(v);
865
+ }
866
+ function compileOr(left, right) {
867
+ return v => left(v) || right(v);
868
+ }
869
+ function compileAnd(left, right) {
870
+ return v => left(v) && right(v);
871
+ }
872
+
565
873
  var _a;
566
874
  class UiState {
567
875
  constructor() {
@@ -616,27 +924,14 @@ class UiState {
616
924
  if (entry[source] !== value) {
617
925
  this.#self.set({ ...current, [name]: { ...entry, [source]: value } });
618
926
  }
619
- const root = this.root;
620
- if (source !== "self" && root !== this) {
621
- root.set(name, value, source);
622
- }
927
+ // TODO: maybe some option to propagate to root
928
+ // const root = this.root
929
+ // if (source !== "self" && root !== this) {
930
+ // root.set(name, value, source)
931
+ // }
623
932
  }
624
- is(name, selector = "*") {
625
- if (selector === "*") {
626
- const current = this.value();
627
- return current[name] ?? false;
628
- }
629
- else if (selector.includes(",")) {
630
- const merged = this.merged();
631
- return selector
632
- .split(/\s*,\s*/)
633
- .map(v => merged[name]?.[v] ?? false)
634
- .some(v => v);
635
- }
636
- else {
637
- const merged = this.merged();
638
- return merged[name]?.[selector] ?? false;
639
- }
933
+ is(selector = "*") {
934
+ return compile(selector)(this.merged());
640
935
  }
641
936
  intercept(name, source) {
642
937
  return (src) => this.wrap(src, name, source);
@@ -665,7 +960,7 @@ class AbstractUiState {
665
960
  this.yes = computed(() => {
666
961
  const when = this.when();
667
962
  if (when !== NOTSET) {
668
- return this.state.is(this.name, `${when},self`);
963
+ return this.state.is(`${this.name}.self || (${when})`);
669
964
  }
670
965
  return this.state.is(this.name);
671
966
  });
@@ -675,7 +970,6 @@ class AbstractUiState {
675
970
  if (input !== NOTSET) {
676
971
  this.state.set(name, !!coerceBoolAttr(input));
677
972
  }
678
- this.yes();
679
973
  }, { allowSignalWrites: true });
680
974
  }
681
975
  set(value, source) {