uicore-ts 1.1.377 → 1.1.378

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.
@@ -18,10 +18,11 @@ type UIGroupingWrapperFrameContext = {
18
18
  configuration: UIGroupingWrapperFrameConfiguration;
19
19
  views: UIView[];
20
20
  framesByView: Map<UIView, UIRectangle>;
21
+ childContexts: UIGroupingWrapperFrameContext[];
21
22
  };
22
23
  type UIGroupingWrapperFrameLayoutPass = {
23
24
  owner: UIView;
24
- groupingContext?: UIGroupingWrapperFrameContext;
25
+ groupingContextStack: UIGroupingWrapperFrameContext[];
25
26
  requests: UIGroupingWrapperFrameContext[];
26
27
  };
27
28
  type UIGroupingWrapperFrameRecord = {
@@ -29,6 +30,7 @@ type UIGroupingWrapperFrameRecord = {
29
30
  wrapperHTMLElement: HTMLDivElement;
30
31
  coordinateSpaceHTMLElement: HTMLDivElement;
31
32
  views: UIView[];
33
+ childRecords: UIGroupingWrapperFrameRecord[];
32
34
  configuredClassNames: string[];
33
35
  configuredAttributeNames: string[];
34
36
  configuredStyleNames: string[];
@@ -176,10 +178,13 @@ export declare class UIRectangle extends UIObject {
176
178
  static _endGroupingWrapperFrameLayoutPass(owner: UIView): void;
177
179
  static _assignFrameToView(frame: UIRectangle, view: UIView): void;
178
180
  static _reconcileGroupingWrapperFrames(layoutPass: UIGroupingWrapperFrameLayoutPass): void;
181
+ static _viewsInGroupingWrapperFrameRecord(record: UIGroupingWrapperFrameRecord): UIView[];
182
+ static _reorderGroupingWrapperFrameElements(containerHTMLElement: HTMLElement, desiredElements: HTMLElement[]): void;
179
183
  static _newGroupingWrapperFrameRecord(): UIGroupingWrapperFrameRecord;
180
- static _configureGroupingWrapperFrameRecord(record: UIGroupingWrapperFrameRecord, request: UIGroupingWrapperFrameContext, owner: UIView): void;
184
+ static _configureGroupingWrapperFrameRecord(record: UIGroupingWrapperFrameRecord, request: UIGroupingWrapperFrameContext, owner: UIView, containerHTMLElement: HTMLElement): void;
181
185
  static _topLevelHTMLElementForView(view: UIView): HTMLElement & import("./UIView").LooseObject;
182
186
  static _detachViewFromGroupingWrapperFrame(view: UIView): void;
187
+ static _removeEmptyGroupingWrapperFrameAncestors(wrapperHTMLElement: Element | null): void;
183
188
  toString(): string;
184
189
  get [Symbol.toStringTag](): string;
185
190
  IF(condition: boolean): UIRectangleConditionalChain<UIRectangle>;
@@ -194,6 +199,12 @@ export declare class UIRectangle extends UIObject {
194
199
  didChange(): void;
195
200
  _rectanglePointDidChange(): void;
196
201
  }
202
+ declare global {
203
+ interface Array<T> {
204
+ /** Returns the smallest rectangle containing every point and rectangle in the array. */
205
+ boundingBox(this: Array<UIPoint | UIRectangle>): UIRectangle;
206
+ }
207
+ }
197
208
  type RectangleChainMethods<TResult> = {
198
209
  [K in keyof UIRectangle as (K extends 'IF' | 'ELSE' | 'ELSE_IF' | 'ENDIF' ? never : K)]: UIRectangle[K] extends (...args: infer Args) => infer R ? R extends UIRectangle | UIRectangle[] ? (...args: Args) => UIRectangleConditionalChain<R, TResult> : never : never;
199
210
  };
@@ -731,28 +731,33 @@ const _UIRectangle = class extends import_UIObject.UIObject {
731
731
  if (!layoutPass) {
732
732
  throw new Error("beginGroupingWrapperFrame() must be called during a UIView layout pass");
733
733
  }
734
- if (layoutPass.groupingContext) {
735
- throw new Error("Nested grouping wrapper frames are not supported");
736
- }
737
- layoutPass.groupingContext = {
734
+ const groupingContext = {
738
735
  configuration,
739
736
  views: [],
740
- framesByView: /* @__PURE__ */ new Map()
737
+ framesByView: /* @__PURE__ */ new Map(),
738
+ childContexts: []
741
739
  };
740
+ const parentContext = layoutPass.groupingContextStack.lastElement;
741
+ if (parentContext) {
742
+ parentContext.childContexts.push(groupingContext);
743
+ } else {
744
+ layoutPass.requests.push(groupingContext);
745
+ }
746
+ layoutPass.groupingContextStack.push(groupingContext);
742
747
  return this;
743
748
  }
744
749
  endGroupingWrapperFrame() {
745
750
  const layoutPass = _UIRectangle._groupingWrapperFrameLayoutPasses.lastElement;
746
- if (!(layoutPass == null ? void 0 : layoutPass.groupingContext)) {
751
+ if (!(layoutPass == null ? void 0 : layoutPass.groupingContextStack.length)) {
747
752
  throw new Error("endGroupingWrapperFrame() requires a matching beginGroupingWrapperFrame()");
748
753
  }
749
- layoutPass.requests.push(layoutPass.groupingContext);
750
- layoutPass.groupingContext = void 0;
754
+ layoutPass.groupingContextStack.pop();
751
755
  return this;
752
756
  }
753
757
  static _beginGroupingWrapperFrameLayoutPass(owner) {
754
758
  _UIRectangle._groupingWrapperFrameLayoutPasses.push({
755
759
  owner,
760
+ groupingContextStack: [],
756
761
  requests: []
757
762
  });
758
763
  }
@@ -761,9 +766,9 @@ const _UIRectangle = class extends import_UIObject.UIObject {
761
766
  if (!layoutPass || layoutPass.owner !== owner) {
762
767
  throw new Error("Unbalanced grouping wrapper frame layout pass");
763
768
  }
764
- if (layoutPass.groupingContext) {
769
+ if (layoutPass.groupingContextStack.length) {
765
770
  console.error("beginGroupingWrapperFrame() was not balanced with endGroupingWrapperFrame()", owner);
766
- layoutPass.requests.push(layoutPass.groupingContext);
771
+ layoutPass.groupingContextStack.length = 0;
767
772
  }
768
773
  if (!import_UIView.UIView.isVirtualLayouting) {
769
774
  _UIRectangle._reconcileGroupingWrapperFrames(layoutPass);
@@ -772,14 +777,15 @@ const _UIRectangle = class extends import_UIObject.UIObject {
772
777
  static _assignFrameToView(frame, view) {
773
778
  var _a;
774
779
  view.frame = frame;
775
- const groupingContext = (_a = _UIRectangle._groupingWrapperFrameLayoutPasses.lastElement) == null ? void 0 : _a.groupingContext;
776
- if (!groupingContext) {
780
+ const groupingContexts = (_a = _UIRectangle._groupingWrapperFrameLayoutPasses.lastElement) == null ? void 0 : _a.groupingContextStack;
781
+ if (!(groupingContexts == null ? void 0 : groupingContexts.length)) {
777
782
  return;
778
783
  }
779
- if (!groupingContext.framesByView.has(view)) {
780
- groupingContext.views.push(view);
784
+ groupingContexts.forEach((groupingContext) => groupingContext.framesByView.set(view, frame.copy()));
785
+ const innermostContext = groupingContexts.lastElement;
786
+ if (!innermostContext.views.contains(view)) {
787
+ innermostContext.views.push(view);
781
788
  }
782
- groupingContext.framesByView.set(view, frame.copy());
783
789
  }
784
790
  static _reconcileGroupingWrapperFrames(layoutPass) {
785
791
  var _a;
@@ -788,10 +794,13 @@ const _UIRectangle = class extends import_UIObject.UIObject {
788
794
  const availablePreviousRecords = previousRecords.copy();
789
795
  const nextRecords = [];
790
796
  const groupedViews = /* @__PURE__ */ new Set();
791
- layoutPass.requests.forEach((request, requestIndex) => {
792
- var _a2;
793
- if (!request.views.length) {
794
- return;
797
+ const configuredIdentifiers = /* @__PURE__ */ new Set();
798
+ const validateContext = (request) => {
799
+ if (request.configuration.identifier) {
800
+ if (configuredIdentifiers.has(request.configuration.identifier)) {
801
+ throw new Error("Grouping wrapper frame identifiers must be unique within one layout owner");
802
+ }
803
+ configuredIdentifiers.add(request.configuration.identifier);
795
804
  }
796
805
  request.views.forEach((view) => {
797
806
  if (view.superview !== owner) {
@@ -802,51 +811,99 @@ const _UIRectangle = class extends import_UIObject.UIObject {
802
811
  }
803
812
  groupedViews.add(view);
804
813
  });
814
+ request.childContexts.forEach(validateContext);
815
+ };
816
+ layoutPass.requests.forEach(validateContext);
817
+ const recordForRequest = (request) => {
805
818
  let record;
806
819
  if (request.configuration.identifier) {
807
820
  record = availablePreviousRecords.find(
808
821
  (candidate) => candidate.identifier === request.configuration.identifier
809
822
  );
823
+ } else {
824
+ record = availablePreviousRecords.find((candidate) => !candidate.identifier);
810
825
  }
811
- record = (_a2 = record != null ? record : availablePreviousRecords[requestIndex]) != null ? _a2 : availablePreviousRecords.firstElement;
812
826
  if (record) {
813
827
  availablePreviousRecords.removeElement(record);
814
828
  } else {
815
829
  record = _UIRectangle._newGroupingWrapperFrameRecord();
816
830
  }
817
- _UIRectangle._configureGroupingWrapperFrameRecord(record, request, owner);
831
+ return record;
832
+ };
833
+ const reconcileContext = (request, containerHTMLElement) => {
834
+ if (!request.framesByView.size) {
835
+ return;
836
+ }
837
+ const record = recordForRequest(request);
838
+ _UIRectangle._configureGroupingWrapperFrameRecord(
839
+ record,
840
+ request,
841
+ owner,
842
+ containerHTMLElement
843
+ );
818
844
  nextRecords.push(record);
819
- });
845
+ record.childRecords = request.childContexts.map(
846
+ (childContext) => reconcileContext(childContext, record.coordinateSpaceHTMLElement)
847
+ ).filter((childRecord) => !!childRecord);
848
+ const elementByView = /* @__PURE__ */ new Map();
849
+ record.views.forEach((view) => elementByView.set(view, view.viewHTMLElement));
850
+ record.childRecords.forEach((childRecord) => {
851
+ _UIRectangle._viewsInGroupingWrapperFrameRecord(childRecord).forEach(
852
+ (view) => elementByView.set(view, childRecord.wrapperHTMLElement)
853
+ );
854
+ });
855
+ _UIRectangle._reorderGroupingWrapperFrameElements(
856
+ record.coordinateSpaceHTMLElement,
857
+ owner.subviews.map((view) => elementByView.get(view)).filter(
858
+ (element) => !!element
859
+ )
860
+ );
861
+ return record;
862
+ };
863
+ const rootRecords = layoutPass.requests.map(
864
+ (request) => reconcileContext(request, owner.viewHTMLElement)
865
+ ).filter((record) => !!record);
820
866
  availablePreviousRecords.forEach((record) => {
821
867
  record.views.forEach((view) => {
822
- var _a2;
823
868
  if (view.viewHTMLElement.parentElement === record.coordinateSpaceHTMLElement) {
824
- (_a2 = record.wrapperHTMLElement.parentElement) == null ? void 0 : _a2.insertBefore(
825
- view.viewHTMLElement,
826
- record.wrapperHTMLElement
827
- );
869
+ owner.viewHTMLElement.appendChild(view.viewHTMLElement);
828
870
  }
829
871
  });
830
872
  record.wrapperHTMLElement.remove();
831
873
  });
832
- const recordByView = /* @__PURE__ */ new Map();
833
- nextRecords.forEach((record) => record.views.forEach((view) => recordByView.set(view, record)));
874
+ const rootRecordByView = /* @__PURE__ */ new Map();
875
+ rootRecords.forEach((record) => {
876
+ _UIRectangle._viewsInGroupingWrapperFrameRecord(record).forEach(
877
+ (view) => rootRecordByView.set(view, record)
878
+ );
879
+ });
834
880
  const desiredTopLevelElements = [];
835
881
  owner.subviews.forEach((view) => {
836
882
  var _a2;
837
- const record = recordByView.get(view);
883
+ const record = rootRecordByView.get(view);
838
884
  const element = (_a2 = record == null ? void 0 : record.wrapperHTMLElement) != null ? _a2 : view.viewHTMLElement;
839
885
  if (!desiredTopLevelElements.contains(element)) {
840
886
  desiredTopLevelElements.push(element);
841
887
  }
842
888
  });
843
- const currentTopLevelElements = Array.from(owner.viewHTMLElement.children).filter(
844
- (element) => desiredTopLevelElements.contains(element)
889
+ _UIRectangle._reorderGroupingWrapperFrameElements(owner.viewHTMLElement, desiredTopLevelElements);
890
+ _UIRectangle._groupingWrapperFrameRecordsByOwner.set(owner, nextRecords);
891
+ }
892
+ static _viewsInGroupingWrapperFrameRecord(record) {
893
+ return record.views.concat(record.childRecords.flatMap(
894
+ (childRecord) => _UIRectangle._viewsInGroupingWrapperFrameRecord(childRecord)
895
+ ));
896
+ }
897
+ static _reorderGroupingWrapperFrameElements(containerHTMLElement, desiredElements) {
898
+ const uniqueDesiredElements = desiredElements.filter(
899
+ (element, index) => desiredElements.indexOf(element) === index
900
+ );
901
+ const currentElements = Array.from(containerHTMLElement.children).filter(
902
+ (element) => uniqueDesiredElements.contains(element)
845
903
  );
846
- if (!currentTopLevelElements.isEqualToArray(desiredTopLevelElements)) {
847
- desiredTopLevelElements.forEach((element) => owner.viewHTMLElement.appendChild(element));
904
+ if (!currentElements.isEqualToArray(uniqueDesiredElements) || uniqueDesiredElements.some((element) => element.parentElement !== containerHTMLElement)) {
905
+ uniqueDesiredElements.forEach((element) => containerHTMLElement.appendChild(element));
848
906
  }
849
- _UIRectangle._groupingWrapperFrameRecordsByOwner.set(owner, nextRecords);
850
907
  }
851
908
  static _newGroupingWrapperFrameRecord() {
852
909
  const wrapperHTMLElement = document.createElement("div");
@@ -860,12 +917,13 @@ const _UIRectangle = class extends import_UIObject.UIObject {
860
917
  wrapperHTMLElement,
861
918
  coordinateSpaceHTMLElement,
862
919
  views: [],
920
+ childRecords: [],
863
921
  configuredClassNames: [],
864
922
  configuredAttributeNames: [],
865
923
  configuredStyleNames: []
866
924
  };
867
925
  }
868
- static _configureGroupingWrapperFrameRecord(record, request, owner) {
926
+ static _configureGroupingWrapperFrameRecord(record, request, owner, containerHTMLElement) {
869
927
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
870
928
  const wrapperHTMLElement = record.wrapperHTMLElement;
871
929
  record.configuredClassNames.forEach((className) => wrapperHTMLElement.classList.remove(className));
@@ -893,7 +951,7 @@ const _UIRectangle = class extends import_UIObject.UIObject {
893
951
  } else {
894
952
  wrapperHTMLElement.removeAttribute("data-uicore-grouping-wrapper-frame-identifier");
895
953
  }
896
- const assignedFrames = request.views.map((view) => request.framesByView.get(view));
954
+ const assignedFrames = Array.from(request.framesByView.values());
897
955
  const framePoints = [];
898
956
  assignedFrames.forEach((frame) => {
899
957
  framePoints.push(frame.min);
@@ -907,8 +965,8 @@ const _UIRectangle = class extends import_UIObject.UIObject {
907
965
  wrapperHTMLElement.style.width = wrapperFrame.width + "px";
908
966
  wrapperHTMLElement.style.height = wrapperFrame.height + "px";
909
967
  wrapperHTMLElement.style.boxSizing = "border-box";
910
- if (wrapperHTMLElement.parentElement !== owner.viewHTMLElement) {
911
- owner.viewHTMLElement.appendChild(wrapperHTMLElement);
968
+ if (wrapperHTMLElement.parentElement !== containerHTMLElement) {
969
+ containerHTMLElement.appendChild(wrapperHTMLElement);
912
970
  }
913
971
  const coordinateSpaceHTMLElement = record.coordinateSpaceHTMLElement;
914
972
  coordinateSpaceHTMLElement.classList.add("UICore_UIGroupingWrapperFrame_CoordinateSpace");
@@ -918,11 +976,6 @@ const _UIRectangle = class extends import_UIObject.UIObject {
918
976
  coordinateSpaceHTMLElement.style.top = -wrapperFrame.y - (wrapperHTMLElement.clientTop || 0) + "px";
919
977
  coordinateSpaceHTMLElement.style.width = owner.bounds.width + "px";
920
978
  coordinateSpaceHTMLElement.style.height = owner.bounds.height + "px";
921
- const currentViewElements = Array.from(coordinateSpaceHTMLElement.children);
922
- const desiredViewElements = request.views.map((view) => view.viewHTMLElement);
923
- if (!currentViewElements.isEqualToArray(desiredViewElements)) {
924
- desiredViewElements.forEach((element) => coordinateSpaceHTMLElement.appendChild(element));
925
- }
926
979
  }
927
980
  static _topLevelHTMLElementForView(view) {
928
981
  var _a;
@@ -933,15 +986,29 @@ const _UIRectangle = class extends import_UIObject.UIObject {
933
986
  return element;
934
987
  }
935
988
  static _detachViewFromGroupingWrapperFrame(view) {
936
- var _a, _b;
989
+ var _a;
937
990
  const superviewHTMLElement = (_a = view.superview) == null ? void 0 : _a.viewHTMLElement;
938
991
  if (!superviewHTMLElement || view.viewHTMLElement.parentElement === superviewHTMLElement) {
939
992
  return;
940
993
  }
941
994
  const wrapperHTMLElement = view.viewHTMLElement.closest("[data-uicore-grouping-wrapper-frame]");
942
995
  superviewHTMLElement.appendChild(view.viewHTMLElement);
943
- if (wrapperHTMLElement && !((_b = wrapperHTMLElement.querySelector("[data-uicore-grouping-wrapper-coordinate-space]")) == null ? void 0 : _b.children.length)) {
996
+ _UIRectangle._removeEmptyGroupingWrapperFrameAncestors(wrapperHTMLElement);
997
+ }
998
+ static _removeEmptyGroupingWrapperFrameAncestors(wrapperHTMLElement) {
999
+ var _a, _b;
1000
+ while (wrapperHTMLElement) {
1001
+ const parentWrapperHTMLElement = (_b = (_a = wrapperHTMLElement.parentElement) == null ? void 0 : _a.closest(
1002
+ "[data-uicore-grouping-wrapper-frame]"
1003
+ )) != null ? _b : null;
1004
+ const coordinateSpaceHTMLElement = wrapperHTMLElement.querySelector(
1005
+ ":scope > [data-uicore-grouping-wrapper-coordinate-space]"
1006
+ );
1007
+ if (coordinateSpaceHTMLElement == null ? void 0 : coordinateSpaceHTMLElement.children.length) {
1008
+ return;
1009
+ }
944
1010
  wrapperHTMLElement.remove();
1011
+ wrapperHTMLElement = parentWrapperHTMLElement;
945
1012
  }
946
1013
  }
947
1014
  toString() {
@@ -1013,6 +1080,16 @@ const _UIRectangle = class extends import_UIObject.UIObject {
1013
1080
  let UIRectangle = _UIRectangle;
1014
1081
  UIRectangle._groupingWrapperFrameLayoutPasses = [];
1015
1082
  UIRectangle._groupingWrapperFrameRecordsByOwner = /* @__PURE__ */ new WeakMap();
1083
+ if (!("boundingBox" in Array.prototype)) {
1084
+ Object.defineProperty(Array.prototype, "boundingBox", {
1085
+ configurable: import_UIObject.YES,
1086
+ enumerable: import_UIObject.NO,
1087
+ writable: import_UIObject.YES,
1088
+ value: function() {
1089
+ return UIRectangle.boundingBoxForRectanglesAndPoints(this);
1090
+ }
1091
+ });
1092
+ }
1016
1093
  class UIRectangleConditionalBlock {
1017
1094
  constructor(initialResult, condition) {
1018
1095
  this._stack = [{