@contrail/documents 2.1.0-alpha.5e3a42c → 2.1.0-alpha.a738b01
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/CHANGELOG.md +0 -19
- package/lib/containers/document-container-index.d.ts +4 -7
- package/lib/containers/document-container-index.js +6 -22
- package/lib/containers/document-container.d.ts +0 -1
- package/lib/containers/document-container.js +0 -5
- package/lib/containers/document-container.service.d.ts +7 -1
- package/lib/containers/document-container.service.js +11 -10
- package/lib/util/dynamic-text/dynamic-text-util.d.ts +1 -2
- package/lib/util/dynamic-text/dynamic-text-util.js +22 -27
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -20,25 +20,6 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
20
20
|
- `SECTION_ELEMENT_TYPE`, `FRAME_ELEMENT_TYPE` and `SHAPE_ELEMENT_TYPES` in
|
|
21
21
|
`document-element-constants`, so the rule above has one definition rather than one per app.
|
|
22
22
|
|
|
23
|
-
### Changed (breaking)
|
|
24
|
-
|
|
25
|
-
- `isContainerBinding()` becomes `DynamicTextUtil.takesValueFromContainer()`. Same rule, named for
|
|
26
|
-
what it decides: whether the binding's value comes from the container rather than a type property.
|
|
27
|
-
|
|
28
|
-
### Fixed
|
|
29
|
-
|
|
30
|
-
- A dynamic text is now anchored at its position rather than its centre when deciding which
|
|
31
|
-
container it belongs to, and `DynamicTextUtil.isDynamicText` is the shared test for one. Its size
|
|
32
|
-
comes from the value it resolves to, and that value depends on the container, so letting its width
|
|
33
|
-
feed membership meant its own text could choose its container: near an edge the two answers
|
|
34
|
-
disagreed indefinitely, flipping between a value and "Move to a frame" on every read. Everything
|
|
35
|
-
else still resolves on its centre.
|
|
36
|
-
- `min` and `max` rendered an infinity sign when every member value was empty. The early return
|
|
37
|
-
checked the list length before the empty values were filtered out, so `Math.min` of nothing
|
|
38
|
-
reached the formatter. Both now fall through to `n/a`.
|
|
39
|
-
- `DynamicTextUtil.calculateSize` threw on an element that reached it without a `size`, which on
|
|
40
|
-
the server failed the read for the whole document. It now measures from a zero size instead.
|
|
41
|
-
|
|
42
23
|
### Changed
|
|
43
24
|
|
|
44
25
|
- `DocumentElementFactory.getBoundingClientRect` multiplies the measured size by the element's
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PositionDefinition } from '../types';
|
|
2
2
|
import { ContainerElementType } from './container-kind';
|
|
3
3
|
import { DocumentContainer } from './document-container';
|
|
4
4
|
export declare class DocumentContainerIndex {
|
|
5
5
|
private readonly data;
|
|
6
6
|
constructor(data: {
|
|
7
|
-
documentElementsById: Map<string, DocumentElement>;
|
|
8
7
|
containersById: Map<string, DocumentContainer>;
|
|
9
8
|
containerPathsByDocumentElementId: Map<string, Map<string, string[]>>;
|
|
10
9
|
memberIdsByContainerId: Map<string, string[]>;
|
|
@@ -12,13 +11,11 @@ export declare class DocumentContainerIndex {
|
|
|
12
11
|
});
|
|
13
12
|
getContainer(containerId: string): DocumentContainer | null;
|
|
14
13
|
containersOf(documentElementId: string, elementType: ContainerElementType): DocumentContainer[];
|
|
15
|
-
containerIdsOf(documentElementId: string, elementType: ContainerElementType):
|
|
14
|
+
containerIdsOf(documentElementId: string, elementType: ContainerElementType): string[];
|
|
16
15
|
innermostContainerIdOf(documentElementId: string, elementType: ContainerElementType): string | null;
|
|
17
|
-
memberIdsOf(containerId: string):
|
|
18
|
-
|
|
19
|
-
containerPathAtPoint(point: PositionDefinition, elementType: ContainerElementType): readonly string[];
|
|
16
|
+
memberIdsOf(containerId: string): string[];
|
|
17
|
+
containerPathAtPoint(point: PositionDefinition, elementType: ContainerElementType): string[];
|
|
20
18
|
maxDepth(elementType: ContainerElementType): number;
|
|
21
19
|
private containersOfType;
|
|
22
|
-
private resolveAll;
|
|
23
20
|
private containerPath;
|
|
24
21
|
}
|
|
@@ -11,7 +11,9 @@ class DocumentContainerIndex {
|
|
|
11
11
|
return (_a = this.data.containersById.get(containerId)) !== null && _a !== void 0 ? _a : null;
|
|
12
12
|
}
|
|
13
13
|
containersOf(documentElementId, elementType) {
|
|
14
|
-
return this.
|
|
14
|
+
return this.containerIdsOf(documentElementId, elementType)
|
|
15
|
+
.map((containerId) => this.data.containersById.get(containerId))
|
|
16
|
+
.filter(Boolean);
|
|
15
17
|
}
|
|
16
18
|
containerIdsOf(documentElementId, elementType) {
|
|
17
19
|
return this.containerPath(documentElementId, elementType);
|
|
@@ -24,16 +26,6 @@ class DocumentContainerIndex {
|
|
|
24
26
|
var _a;
|
|
25
27
|
return (_a = this.data.memberIdsByContainerId.get(containerId)) !== null && _a !== void 0 ? _a : [];
|
|
26
28
|
}
|
|
27
|
-
memberDocumentElementsOf(containerId) {
|
|
28
|
-
const members = [];
|
|
29
|
-
for (const memberId of this.memberIdsOf(containerId)) {
|
|
30
|
-
const member = this.data.documentElementsById.get(memberId);
|
|
31
|
-
if (member) {
|
|
32
|
-
members.push(member);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return members;
|
|
36
|
-
}
|
|
37
29
|
containerPathAtPoint(point, elementType) {
|
|
38
30
|
const covering = this.containersOfType(elementType).filter((container) => (0, document_container_1.containsPoint)(container.box, point));
|
|
39
31
|
return (0, document_container_1.topmostPerDepth)(covering).map((container) => container.id);
|
|
@@ -43,17 +35,9 @@ class DocumentContainerIndex {
|
|
|
43
35
|
}
|
|
44
36
|
containersOfType(elementType) {
|
|
45
37
|
var _a;
|
|
46
|
-
return
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const containers = [];
|
|
50
|
-
for (const containerId of containerIds) {
|
|
51
|
-
const container = this.data.containersById.get(containerId);
|
|
52
|
-
if (container) {
|
|
53
|
-
containers.push(container);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return containers;
|
|
38
|
+
return ((_a = this.data.containerIdsByElementType.get(elementType)) !== null && _a !== void 0 ? _a : [])
|
|
39
|
+
.map((containerId) => this.data.containersById.get(containerId))
|
|
40
|
+
.filter(Boolean);
|
|
57
41
|
}
|
|
58
42
|
containerPath(documentElementId, elementType) {
|
|
59
43
|
var _a, _b;
|
|
@@ -16,7 +16,6 @@ export interface MeasuredDocumentElement {
|
|
|
16
16
|
}
|
|
17
17
|
export declare function toCoordinateBox(x: number, y: number, width: number, height: number): CoordinateBox;
|
|
18
18
|
export declare function centerOf(box: CoordinateBox): PositionDefinition;
|
|
19
|
-
export declare function anchorOf(documentElement: DocumentElement, box: CoordinateBox): PositionDefinition;
|
|
20
19
|
export declare function containsPoint(box: CoordinateBox, point: PositionDefinition): boolean;
|
|
21
20
|
export declare function encloses(outer: CoordinateBox, inner: CoordinateBox): boolean;
|
|
22
21
|
export declare function isWiderAndTallerThan(box: CoordinateBox, other: CoordinateBox): boolean;
|
|
@@ -2,21 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toCoordinateBox = toCoordinateBox;
|
|
4
4
|
exports.centerOf = centerOf;
|
|
5
|
-
exports.anchorOf = anchorOf;
|
|
6
5
|
exports.containsPoint = containsPoint;
|
|
7
6
|
exports.encloses = encloses;
|
|
8
7
|
exports.isWiderAndTallerThan = isWiderAndTallerThan;
|
|
9
8
|
exports.topmostPerDepth = topmostPerDepth;
|
|
10
|
-
const dynamic_text_util_1 = require("../util/dynamic-text/dynamic-text-util");
|
|
11
9
|
function toCoordinateBox(x, y, width, height) {
|
|
12
10
|
return { x, y, width, height, left: x, right: x + width, top: y, bottom: y + height };
|
|
13
11
|
}
|
|
14
12
|
function centerOf(box) {
|
|
15
13
|
return { x: box.left + box.width / 2, y: box.top + box.height / 2 };
|
|
16
14
|
}
|
|
17
|
-
function anchorOf(documentElement, box) {
|
|
18
|
-
return dynamic_text_util_1.DynamicTextUtil.isDynamicText(documentElement) ? { x: box.left, y: box.top } : centerOf(box);
|
|
19
|
-
}
|
|
20
15
|
function containsPoint(box, point) {
|
|
21
16
|
return point.x >= box.left && point.x <= box.right && point.y >= box.top && point.y <= box.bottom;
|
|
22
17
|
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { DocumentElement } from '../types';
|
|
2
2
|
import { ContainerKind } from './container-kind';
|
|
3
3
|
import { DocumentContainerIndex } from './document-container-index';
|
|
4
|
+
export type MeasureDocumentElement = (documentElement: DocumentElement, startElement?: DocumentElement, endElement?: DocumentElement) => {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
} | null;
|
|
4
10
|
export declare class DocumentContainerService {
|
|
5
|
-
static buildIndex(documentElements: readonly DocumentElement[], kinds?: ContainerKind[]): DocumentContainerIndex;
|
|
11
|
+
static buildIndex(documentElements: readonly DocumentElement[], kinds?: ContainerKind[], measure?: MeasureDocumentElement): DocumentContainerIndex;
|
|
6
12
|
static isContainer(documentElement: DocumentElement, kinds?: ContainerKind[]): boolean;
|
|
7
13
|
private static measureDocumentElements;
|
|
8
14
|
private static measure;
|
|
@@ -7,8 +7,8 @@ const container_kind_1 = require("./container-kind");
|
|
|
7
7
|
const document_container_index_1 = require("./document-container-index");
|
|
8
8
|
const document_container_1 = require("./document-container");
|
|
9
9
|
class DocumentContainerService {
|
|
10
|
-
static buildIndex(documentElements, kinds = container_kind_1.CONTAINER_KINDS) {
|
|
11
|
-
const measuredDocumentElements = this.measureDocumentElements(documentElements !== null && documentElements !== void 0 ? documentElements : []);
|
|
10
|
+
static buildIndex(documentElements, kinds = container_kind_1.CONTAINER_KINDS, measure) {
|
|
11
|
+
const measuredDocumentElements = this.measureDocumentElements(documentElements !== null && documentElements !== void 0 ? documentElements : [], measure);
|
|
12
12
|
const nestingByElementType = new Map(kinds.map((kind) => [kind.elementType, this.buildNesting(measuredDocumentElements, kind)]));
|
|
13
13
|
const containersById = new Map();
|
|
14
14
|
const containerIdsByElementType = new Map();
|
|
@@ -37,7 +37,6 @@ class DocumentContainerService {
|
|
|
37
37
|
containerPathsByDocumentElementId.set(documentElementId, pathsByElementType);
|
|
38
38
|
}
|
|
39
39
|
return new document_container_index_1.DocumentContainerIndex({
|
|
40
|
-
documentElementsById: new Map(measuredDocumentElements.map((measured) => [measured.documentElement.id, measured.documentElement])),
|
|
41
40
|
containersById,
|
|
42
41
|
containerPathsByDocumentElementId,
|
|
43
42
|
memberIdsByContainerId,
|
|
@@ -47,15 +46,15 @@ class DocumentContainerService {
|
|
|
47
46
|
static isContainer(documentElement, kinds = container_kind_1.CONTAINER_KINDS) {
|
|
48
47
|
return kinds.some((kind) => kind.elementType === (documentElement === null || documentElement === void 0 ? void 0 : documentElement.type));
|
|
49
48
|
}
|
|
50
|
-
static measureDocumentElements(documentElements) {
|
|
49
|
+
static measureDocumentElements(documentElements, measure) {
|
|
51
50
|
const documentElementsById = new Map(documentElements.map((documentElement) => [documentElement.id, documentElement]));
|
|
52
51
|
return documentElements.map((documentElement, drawOrder) => ({
|
|
53
52
|
documentElement,
|
|
54
53
|
drawOrder,
|
|
55
|
-
box: this.measure(documentElement, documentElementsById),
|
|
54
|
+
box: this.measure(documentElement, documentElementsById, measure),
|
|
56
55
|
}));
|
|
57
56
|
}
|
|
58
|
-
static measure(documentElement, documentElementsById) {
|
|
57
|
+
static measure(documentElement, documentElementsById, measure) {
|
|
59
58
|
var _a, _b;
|
|
60
59
|
if (!(documentElement === null || documentElement === void 0 ? void 0 : documentElement.position)) {
|
|
61
60
|
return null;
|
|
@@ -63,8 +62,10 @@ class DocumentContainerService {
|
|
|
63
62
|
try {
|
|
64
63
|
const start = ((_a = documentElement.start) === null || _a === void 0 ? void 0 : _a.id) ? documentElementsById.get(documentElement.start.id) : undefined;
|
|
65
64
|
const end = ((_b = documentElement.end) === null || _b === void 0 ? void 0 : _b.id) ? documentElementsById.get(documentElement.end.id) : undefined;
|
|
66
|
-
const
|
|
67
|
-
|
|
65
|
+
const rect = measure
|
|
66
|
+
? measure(documentElement, start, end)
|
|
67
|
+
: document_element_factory_1.DocumentElementFactory.getBoundingClientRect(documentElement, start, end);
|
|
68
|
+
return rect ? (0, document_container_1.toCoordinateBox)(rect.x, rect.y, rect.width, rect.height) : null;
|
|
68
69
|
}
|
|
69
70
|
catch (_c) {
|
|
70
71
|
return null;
|
|
@@ -125,14 +126,14 @@ class DocumentContainerService {
|
|
|
125
126
|
return (0, document_container_1.topmostPerDepth)(containers).map((container) => container.id);
|
|
126
127
|
}
|
|
127
128
|
static candidateContainers(measured, containers) {
|
|
128
|
-
const
|
|
129
|
+
const center = (0, document_container_1.centerOf)(measured.box);
|
|
129
130
|
const isShape = document_element_constants_1.SHAPE_ELEMENT_TYPES.includes(measured.documentElement.type);
|
|
130
131
|
return containers.filter((container) => {
|
|
131
132
|
var _a;
|
|
132
133
|
if (container.id === measured.documentElement.id || measured.drawOrder <= container.drawOrder) {
|
|
133
134
|
return false;
|
|
134
135
|
}
|
|
135
|
-
if (!(0, document_container_1.containsPoint)(container.box,
|
|
136
|
+
if (!(0, document_container_1.containsPoint)(container.box, center)) {
|
|
136
137
|
return false;
|
|
137
138
|
}
|
|
138
139
|
if (isShape && (0, document_container_1.isWiderAndTallerThan)(measured.box, container.box)) {
|
|
@@ -48,9 +48,8 @@ export declare const HARD_CODED_TEXT: {
|
|
|
48
48
|
'section.itemOptionCount': string;
|
|
49
49
|
'section.colorCount': string;
|
|
50
50
|
};
|
|
51
|
+
export declare function isContainerBinding(bindingProperty: string | null | undefined): boolean;
|
|
51
52
|
export declare class DynamicTextUtil {
|
|
52
|
-
static isDynamicText(documentElement: DocumentElement): boolean;
|
|
53
|
-
static takesValueFromContainer(bindingProperty: string | null | undefined): boolean;
|
|
54
53
|
static getDynamicTextValue(dynamicTextElement: DocumentElement, property: TypeProperty, propertyLevel: PropertyLevel, container: DynamicTextContainer | null, componentModels: any[], ownerReferenceModel?: any): string;
|
|
55
54
|
static calculateSize(dynamicTextElement: DocumentElement, entityType: any, text: string): import("../..").SizeDefinition;
|
|
56
55
|
static getTextFromFrameMemberValues(displayFunction: string, property: any, memberValues: any[]): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DynamicTextUtil = exports.HARD_CODED_TEXT = exports.CLICK_TO_CONFIGURE = exports.MOVE_TO_SECTION_TEXT = exports.MOVE_TO_FRAME_TEXT = exports.DynamicTextDisplayFunction = exports.DYNAMIC_TEXT_DATA_SOURCE = void 0;
|
|
4
|
+
exports.isContainerBinding = isContainerBinding;
|
|
4
5
|
const types_1 = require("@contrail/types");
|
|
5
6
|
const util_1 = require("@contrail/util");
|
|
6
7
|
const document_util_1 = require("@contrail/document-util");
|
|
@@ -50,19 +51,14 @@ exports.HARD_CODED_TEXT = {
|
|
|
50
51
|
};
|
|
51
52
|
const CONTAINER_PROPERTY_SLUGS = ['name', 'count', 'itemFamilyCount', 'itemOptionCount', 'colorCount'];
|
|
52
53
|
const CONTAINER_SOURCES = [DYNAMIC_TEXT_DATA_SOURCE.FRAME, DYNAMIC_TEXT_DATA_SOURCE.SECTION];
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return
|
|
56
|
-
!!documentElement.propertyBindings &&
|
|
57
|
-
!!documentElement.propertyBindingsMetaData);
|
|
58
|
-
}
|
|
59
|
-
static takesValueFromContainer(bindingProperty) {
|
|
60
|
-
if (!bindingProperty) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
const [entityType, propertySlug] = bindingProperty.split('.');
|
|
64
|
-
return CONTAINER_SOURCES.includes(entityType) && CONTAINER_PROPERTY_SLUGS.includes(propertySlug);
|
|
54
|
+
function isContainerBinding(bindingProperty) {
|
|
55
|
+
if (!bindingProperty) {
|
|
56
|
+
return false;
|
|
65
57
|
}
|
|
58
|
+
const [entityType, propertySlug] = bindingProperty.split('.');
|
|
59
|
+
return CONTAINER_SOURCES.includes(entityType) && CONTAINER_PROPERTY_SLUGS.includes(propertySlug);
|
|
60
|
+
}
|
|
61
|
+
class DynamicTextUtil {
|
|
66
62
|
static getDynamicTextValue(dynamicTextElement, property, propertyLevel, container, componentModels, ownerReferenceModel = null) {
|
|
67
63
|
var _a, _b, _c, _d;
|
|
68
64
|
if (!dynamicTextElement.propertyBindings || !dynamicTextElement.propertyBindings.text) {
|
|
@@ -154,12 +150,12 @@ class DynamicTextUtil {
|
|
|
154
150
|
return text;
|
|
155
151
|
}
|
|
156
152
|
static calculateSize(dynamicTextElement, entityType, text) {
|
|
157
|
-
var _a, _b, _c, _d
|
|
158
|
-
let size =
|
|
159
|
-
const fontFamily = (
|
|
160
|
-
const fontSize = (
|
|
161
|
-
? (
|
|
162
|
-
: document_util_1.DocumentStyleUtil.getFirstFontSize(dynamicTextElement === null || dynamicTextElement === void 0 ? void 0 : dynamicTextElement.text, true))) !== null &&
|
|
153
|
+
var _a, _b, _c, _d;
|
|
154
|
+
let size = dynamicTextElement.size;
|
|
155
|
+
const fontFamily = (_a = document_util_1.DocumentStyleUtil.getFirstFontFamily(dynamicTextElement === null || dynamicTextElement === void 0 ? void 0 : dynamicTextElement.text)) !== null && _a !== void 0 ? _a : document_util_1.DEFAULT_TEXT_FONT_FAMILY;
|
|
156
|
+
const fontSize = (_d = (dynamicTextElement.isTextTool
|
|
157
|
+
? (_c = (_b = dynamicTextElement.style) === null || _b === void 0 ? void 0 : _b.font) === null || _c === void 0 ? void 0 : _c.size
|
|
158
|
+
: document_util_1.DocumentStyleUtil.getFirstFontSize(dynamicTextElement === null || dynamicTextElement === void 0 ? void 0 : dynamicTextElement.text, true))) !== null && _d !== void 0 ? _d : document_util_1.DEFAULT_TEXT_FONT_SIZE;
|
|
163
159
|
const fontSizePx = document_util_1.DocumentStyleUtil.toPx(fontSize, 4);
|
|
164
160
|
const padding = dynamicTextElement.isTextTool ? document_util_1.TEXT_TOOL_PADDING : document_util_1.TEXT_BOX_PADDING;
|
|
165
161
|
const bold = document_util_1.DocumentStyleUtil.isBold(dynamicTextElement === null || dynamicTextElement === void 0 ? void 0 : dynamicTextElement.text, fontFamily);
|
|
@@ -173,7 +169,7 @@ class DynamicTextUtil {
|
|
|
173
169
|
italic,
|
|
174
170
|
};
|
|
175
171
|
if (!dynamicTextElement.isTextTool) {
|
|
176
|
-
measureTextSettings.width = size.width - padding * 2;
|
|
172
|
+
measureTextSettings.width = dynamicTextElement.size.width - padding * 2;
|
|
177
173
|
}
|
|
178
174
|
try {
|
|
179
175
|
const dimensions = document_util_1.DocumentTextUtil.measureText(text, measureTextSettings);
|
|
@@ -216,14 +212,13 @@ class DynamicTextUtil {
|
|
|
216
212
|
else if (displayFunction === DynamicTextDisplayFunction.LAST) {
|
|
217
213
|
text = formatter.formatValueForProperty(memberValues[memberValues.length - 1], property);
|
|
218
214
|
}
|
|
219
|
-
else if (displayFunction === DynamicTextDisplayFunction.MIN
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
text = formatter.formatValueForProperty(extreme, property);
|
|
215
|
+
else if (displayFunction === DynamicTextDisplayFunction.MIN) {
|
|
216
|
+
memberValues = memberValues.filter((e) => e !== null && e !== undefined);
|
|
217
|
+
text = formatter.formatValueForProperty(Math.min(...memberValues), property);
|
|
218
|
+
}
|
|
219
|
+
else if (displayFunction === DynamicTextDisplayFunction.MAX) {
|
|
220
|
+
memberValues = memberValues.filter((e) => e !== null && e !== undefined);
|
|
221
|
+
text = formatter.formatValueForProperty(Math.max(...memberValues), property);
|
|
227
222
|
}
|
|
228
223
|
return text;
|
|
229
224
|
}
|