@dotcms/client 0.0.1-alpha.37 → 0.0.1-alpha.39
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/.eslintrc.json +18 -0
- package/README.md +4 -4
- package/jest.config.ts +15 -0
- package/package.json +3 -15
- package/project.json +72 -0
- package/src/index.ts +30 -0
- package/src/lib/client/content/builders/collection/collection.spec.ts +515 -0
- package/src/lib/client/content/builders/collection/collection.ts +416 -0
- package/src/lib/client/content/content-api.ts +139 -0
- package/src/lib/client/content/shared/const.ts +15 -0
- package/src/lib/client/content/shared/types.ts +155 -0
- package/src/lib/client/content/shared/utils.ts +28 -0
- package/src/lib/client/models/index.ts +19 -0
- package/src/lib/client/models/types.ts +14 -0
- package/src/lib/client/sdk-js-client.spec.ts +483 -0
- package/src/lib/client/sdk-js-client.ts +442 -0
- package/src/lib/editor/listeners/listeners.spec.ts +119 -0
- package/src/lib/editor/listeners/listeners.ts +223 -0
- package/src/lib/editor/models/{client.model.d.ts → client.model.ts} +19 -16
- package/src/lib/editor/models/{editor.model.d.ts → editor.model.ts} +9 -5
- package/src/lib/editor/models/{listeners.model.d.ts → listeners.model.ts} +9 -6
- package/src/lib/editor/sdk-editor-vtl.ts +31 -0
- package/src/lib/editor/sdk-editor.spec.ts +116 -0
- package/src/lib/editor/sdk-editor.ts +105 -0
- package/src/lib/editor/utils/editor.utils.spec.ts +206 -0
- package/src/lib/editor/utils/editor.utils.ts +258 -0
- package/src/lib/query-builder/lucene-syntax/{Equals.d.ts → Equals.ts} +83 -18
- package/src/lib/query-builder/lucene-syntax/Field.ts +40 -0
- package/src/lib/query-builder/lucene-syntax/{NotOperand.d.ts → NotOperand.ts} +18 -6
- package/src/lib/query-builder/lucene-syntax/{Operand.d.ts → Operand.ts} +21 -7
- package/src/lib/query-builder/sdk-query-builder.spec.ts +159 -0
- package/src/lib/query-builder/sdk-query-builder.ts +87 -0
- package/src/lib/query-builder/utils/index.ts +179 -0
- package/src/lib/utils/graphql/transforms.spec.ts +150 -0
- package/src/lib/utils/graphql/transforms.ts +99 -0
- package/src/lib/utils/page/common-utils.spec.ts +37 -0
- package/src/lib/utils/page/common-utils.ts +64 -0
- package/tsconfig.json +22 -0
- package/tsconfig.lib.json +13 -0
- package/tsconfig.spec.json +9 -0
- package/index.cjs.d.ts +0 -1
- package/index.cjs.default.js +0 -1
- package/index.cjs.js +0 -1490
- package/index.cjs.mjs +0 -2
- package/index.esm.d.ts +0 -1
- package/index.esm.js +0 -1481
- package/src/index.d.ts +0 -6
- package/src/lib/client/content/builders/collection/collection.d.ts +0 -148
- package/src/lib/client/content/content-api.d.ts +0 -78
- package/src/lib/client/content/shared/const.d.ts +0 -3
- package/src/lib/client/content/shared/types.d.ts +0 -62
- package/src/lib/client/content/shared/utils.d.ts +0 -12
- package/src/lib/client/models/index.d.ts +0 -1
- package/src/lib/client/models/types.d.ts +0 -5
- package/src/lib/client/sdk-js-client.d.ts +0 -193
- package/src/lib/editor/listeners/listeners.d.ts +0 -46
- package/src/lib/editor/sdk-editor-vtl.d.ts +0 -6
- package/src/lib/editor/sdk-editor.d.ts +0 -29
- package/src/lib/editor/utils/editor.utils.d.ts +0 -83
- package/src/lib/query-builder/lucene-syntax/Field.d.ts +0 -23
- package/src/lib/query-builder/sdk-query-builder.d.ts +0 -42
- package/src/lib/query-builder/utils/index.d.ts +0 -91
- package/src/lib/utils/graphql/transforms.d.ts +0 -11
- package/src/lib/utils/page/common-utils.d.ts +0 -11
- /package/src/lib/query-builder/lucene-syntax/{index.d.ts → index.ts} +0 -0
- /package/src/lib/utils/{index.d.ts → index.ts} +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { getContentletsBound, scrollIsInBottom } from './editor.utils';
|
|
2
|
+
|
|
3
|
+
describe('getContentletsBound', () => {
|
|
4
|
+
const createContentlet = ({
|
|
5
|
+
x,
|
|
6
|
+
y,
|
|
7
|
+
width,
|
|
8
|
+
height,
|
|
9
|
+
dataset
|
|
10
|
+
}: {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
dataset: { [key: string]: string };
|
|
16
|
+
}): HTMLDivElement => {
|
|
17
|
+
const contentlet = document.createElement('div');
|
|
18
|
+
const mockGetBoundingClientRect = jest.fn(() => ({
|
|
19
|
+
x,
|
|
20
|
+
y,
|
|
21
|
+
width,
|
|
22
|
+
height
|
|
23
|
+
})) as unknown as () => DOMRect;
|
|
24
|
+
contentlet.getBoundingClientRect = mockGetBoundingClientRect;
|
|
25
|
+
Object.keys(dataset).forEach((key) => {
|
|
26
|
+
contentlet.setAttribute(`data-${key}`, dataset[key]);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return contentlet;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const containerRect = {
|
|
33
|
+
x: 0,
|
|
34
|
+
y: 0,
|
|
35
|
+
width: 100,
|
|
36
|
+
height: 100,
|
|
37
|
+
top: 0,
|
|
38
|
+
right: 100,
|
|
39
|
+
bottom: 100,
|
|
40
|
+
left: 0
|
|
41
|
+
} as DOMRect;
|
|
42
|
+
|
|
43
|
+
const contentlets: HTMLDivElement[] = [
|
|
44
|
+
createContentlet({
|
|
45
|
+
x: 10,
|
|
46
|
+
y: 20,
|
|
47
|
+
width: 30,
|
|
48
|
+
height: 40,
|
|
49
|
+
dataset: {
|
|
50
|
+
'dot-container': JSON.stringify({ uuid: 'container1' }),
|
|
51
|
+
'dot-identifier': 'contentlet1',
|
|
52
|
+
'dot-title': 'Contentlet 1',
|
|
53
|
+
'dot-inode': 'inode1',
|
|
54
|
+
'dot-type': 'type1'
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
createContentlet({
|
|
58
|
+
x: 50,
|
|
59
|
+
y: 60,
|
|
60
|
+
width: 70,
|
|
61
|
+
height: 80,
|
|
62
|
+
dataset: {
|
|
63
|
+
'dot-container': JSON.stringify({ uuid: 'container1' }),
|
|
64
|
+
'dot-identifier': 'contentlet2',
|
|
65
|
+
'dot-title': 'Contentlet 2',
|
|
66
|
+
'dot-inode': 'inode2',
|
|
67
|
+
'dot-type': 'type2'
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
it('should return an array of contentlets bound from contentlet with data atrribute dotContainer ', () => {
|
|
73
|
+
const result = getContentletsBound(containerRect, contentlets);
|
|
74
|
+
|
|
75
|
+
expect(result).toEqual([
|
|
76
|
+
{
|
|
77
|
+
x: 0,
|
|
78
|
+
y: 20,
|
|
79
|
+
width: 30,
|
|
80
|
+
height: 40,
|
|
81
|
+
payload: JSON.stringify({
|
|
82
|
+
container: { uuid: 'container1' },
|
|
83
|
+
contentlet: {
|
|
84
|
+
identifier: 'contentlet1',
|
|
85
|
+
title: 'Contentlet 1',
|
|
86
|
+
inode: 'inode1',
|
|
87
|
+
contentType: 'type1'
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
x: 0,
|
|
93
|
+
y: 60,
|
|
94
|
+
width: 70,
|
|
95
|
+
height: 80,
|
|
96
|
+
payload: JSON.stringify({
|
|
97
|
+
container: { uuid: 'container1' },
|
|
98
|
+
contentlet: {
|
|
99
|
+
identifier: 'contentlet2',
|
|
100
|
+
title: 'Contentlet 2',
|
|
101
|
+
inode: 'inode2',
|
|
102
|
+
contentType: 'type2'
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
]);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should return an empty array if contentlets is empty', () => {
|
|
110
|
+
const result = getContentletsBound(containerRect, []);
|
|
111
|
+
|
|
112
|
+
expect(result).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should return an array of contentlets with correct properties when dotContainer is not present in dataset', () => {
|
|
116
|
+
const contentletsWithMissingContainer: HTMLDivElement[] = [
|
|
117
|
+
createContentlet({
|
|
118
|
+
x: 10,
|
|
119
|
+
y: 20,
|
|
120
|
+
width: 30,
|
|
121
|
+
height: 40,
|
|
122
|
+
dataset: {
|
|
123
|
+
'dot-identifier': 'contentlet1',
|
|
124
|
+
'dot-title': 'Contentlet 1',
|
|
125
|
+
'dot-inode': 'inode1',
|
|
126
|
+
'dot-type': 'type1'
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
const container = document.createElement('div');
|
|
132
|
+
|
|
133
|
+
container.appendChild(contentletsWithMissingContainer[0]);
|
|
134
|
+
container.setAttribute('data-dot-object', 'container');
|
|
135
|
+
container.setAttribute('data-dot-accept-types', '[Blogs]');
|
|
136
|
+
container.setAttribute('data-dot-identifier', '1');
|
|
137
|
+
container.setAttribute('data-max-contentlets', '1');
|
|
138
|
+
container.setAttribute('data-dot-uuid', '1');
|
|
139
|
+
const result = getContentletsBound(containerRect, contentletsWithMissingContainer);
|
|
140
|
+
|
|
141
|
+
expect(result).toEqual([
|
|
142
|
+
{
|
|
143
|
+
x: 0,
|
|
144
|
+
y: 20,
|
|
145
|
+
width: 30,
|
|
146
|
+
height: 40,
|
|
147
|
+
payload: JSON.stringify({
|
|
148
|
+
container: {
|
|
149
|
+
acceptTypes: '[Blogs]',
|
|
150
|
+
identifier: '1',
|
|
151
|
+
maxContentlets: '1',
|
|
152
|
+
uuid: '1'
|
|
153
|
+
},
|
|
154
|
+
contentlet: {
|
|
155
|
+
identifier: 'contentlet1',
|
|
156
|
+
title: 'Contentlet 1',
|
|
157
|
+
inode: 'inode1',
|
|
158
|
+
contentType: 'type1'
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
]);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe('scrollIsInBottom', () => {
|
|
167
|
+
it('should return true when scroll position + viewport height equals document height', () => {
|
|
168
|
+
Object.defineProperty(window, 'innerHeight', {
|
|
169
|
+
writable: true,
|
|
170
|
+
configurable: true,
|
|
171
|
+
value: 500
|
|
172
|
+
});
|
|
173
|
+
Object.defineProperty(window, 'scrollY', {
|
|
174
|
+
writable: true,
|
|
175
|
+
configurable: true,
|
|
176
|
+
value: 500
|
|
177
|
+
});
|
|
178
|
+
Object.defineProperty(document.documentElement, 'scrollHeight', {
|
|
179
|
+
writable: true,
|
|
180
|
+
configurable: true,
|
|
181
|
+
value: 1000
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
expect(scrollIsInBottom()).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should return false when scroll position + viewport height is less than document height', () => {
|
|
188
|
+
Object.defineProperty(window, 'innerHeight', {
|
|
189
|
+
writable: true,
|
|
190
|
+
configurable: true,
|
|
191
|
+
value: 500
|
|
192
|
+
});
|
|
193
|
+
Object.defineProperty(window, 'scrollY', {
|
|
194
|
+
writable: true,
|
|
195
|
+
configurable: true,
|
|
196
|
+
value: 400
|
|
197
|
+
});
|
|
198
|
+
Object.defineProperty(document.documentElement, 'scrollHeight', {
|
|
199
|
+
writable: true,
|
|
200
|
+
configurable: true,
|
|
201
|
+
value: 1000
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
expect(scrollIsInBottom()).toBe(false);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bound information for a contentlet.
|
|
3
|
+
*
|
|
4
|
+
* @interface ContentletBound
|
|
5
|
+
* @property {number} x - The x-coordinate of the contentlet.
|
|
6
|
+
* @property {number} y - The y-coordinate of the contentlet.
|
|
7
|
+
* @property {number} width - The width of the contentlet.
|
|
8
|
+
* @property {number} height - The height of the contentlet.
|
|
9
|
+
* @property {string} payload - The payload data of the contentlet in JSON format.
|
|
10
|
+
*/
|
|
11
|
+
interface ContentletBound {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
payload: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Bound information for a container.
|
|
21
|
+
*
|
|
22
|
+
* @interface ContainerBound
|
|
23
|
+
* @property {number} x - The x-coordinate of the container.
|
|
24
|
+
* @property {number} y - The y-coordinate of the container.
|
|
25
|
+
* @property {number} width - The width of the container.
|
|
26
|
+
* @property {number} height - The height of the container.
|
|
27
|
+
* @property {string} payload - The payload data of the container in JSON format.
|
|
28
|
+
* @property {ContentletBound[]} contentlets - An array of contentlets within the container.
|
|
29
|
+
*/
|
|
30
|
+
interface ContainerBound {
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
payload: string;
|
|
36
|
+
contentlets: ContentletBound[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Calculates the bounding information for each page element within the given containers.
|
|
41
|
+
*
|
|
42
|
+
* @export
|
|
43
|
+
* @param {HTMLDivElement[]} containers - An array of HTMLDivElement representing the containers.
|
|
44
|
+
* @return {ContainerBound[]} An array of objects containing the bounding information for each page element.
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const containers = document.querySelectorAll('.container');
|
|
48
|
+
* const bounds = getPageElementBound(containers);
|
|
49
|
+
* console.log(bounds);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function getPageElementBound(containers: HTMLDivElement[]): ContainerBound[] {
|
|
53
|
+
return containers.map((container) => {
|
|
54
|
+
const containerRect = container.getBoundingClientRect();
|
|
55
|
+
const contentlets = Array.from(
|
|
56
|
+
container.querySelectorAll('[data-dot-object="contentlet"]')
|
|
57
|
+
) as HTMLDivElement[];
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
x: containerRect.x,
|
|
61
|
+
y: containerRect.y,
|
|
62
|
+
width: containerRect.width,
|
|
63
|
+
height: containerRect.height,
|
|
64
|
+
payload: JSON.stringify({
|
|
65
|
+
container: getContainerData(container)
|
|
66
|
+
}),
|
|
67
|
+
contentlets: getContentletsBound(containerRect, contentlets)
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Calculates the bounding information for each contentlet inside a container.
|
|
74
|
+
*
|
|
75
|
+
* @export
|
|
76
|
+
* @param {DOMRect} containerRect - The bounding rectangle of the container.
|
|
77
|
+
* @param {HTMLDivElement[]} contentlets - An array of HTMLDivElement representing the contentlets.
|
|
78
|
+
* @return {ContentletBound[]} An array of objects containing the bounding information for each contentlet.
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const containerRect = container.getBoundingClientRect();
|
|
82
|
+
* const contentlets = container.querySelectorAll('.contentlet');
|
|
83
|
+
* const bounds = getContentletsBound(containerRect, contentlets);
|
|
84
|
+
* console.log(bounds); // Element bounds within the container
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export function getContentletsBound(
|
|
88
|
+
containerRect: DOMRect,
|
|
89
|
+
contentlets: HTMLDivElement[]
|
|
90
|
+
): ContentletBound[] {
|
|
91
|
+
return contentlets.map((contentlet) => {
|
|
92
|
+
const contentletRect = contentlet.getBoundingClientRect();
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
x: 0,
|
|
96
|
+
y: contentletRect.y - containerRect.y,
|
|
97
|
+
width: contentletRect.width,
|
|
98
|
+
height: contentletRect.height,
|
|
99
|
+
payload: JSON.stringify({
|
|
100
|
+
container: contentlet.dataset?.['dotContainer']
|
|
101
|
+
? JSON.parse(contentlet.dataset?.['dotContainer'])
|
|
102
|
+
: getClosestContainerData(contentlet),
|
|
103
|
+
contentlet: {
|
|
104
|
+
identifier: contentlet.dataset?.['dotIdentifier'],
|
|
105
|
+
title: contentlet.dataset?.['dotTitle'],
|
|
106
|
+
inode: contentlet.dataset?.['dotInode'],
|
|
107
|
+
contentType: contentlet.dataset?.['dotType']
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Get container data from VTLS.
|
|
116
|
+
*
|
|
117
|
+
* @export
|
|
118
|
+
* @param {HTMLElement} container - The container element.
|
|
119
|
+
* @return {object} An object containing the container data.
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* const container = document.querySelector('.container');
|
|
123
|
+
* const data = getContainerData(container);
|
|
124
|
+
* console.log(data);
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export function getContainerData(container: HTMLElement) {
|
|
128
|
+
return {
|
|
129
|
+
acceptTypes: container.dataset?.['dotAcceptTypes'] || '',
|
|
130
|
+
identifier: container.dataset?.['dotIdentifier'] || '',
|
|
131
|
+
maxContentlets: container.dataset?.['maxContentlets'] || '',
|
|
132
|
+
uuid: container.dataset?.['dotUuid'] || ''
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get the closest container data from the contentlet.
|
|
138
|
+
*
|
|
139
|
+
* @export
|
|
140
|
+
* @param {Element} element - The contentlet element.
|
|
141
|
+
* @return {object | null} An object containing the closest container data or null if no container is found.
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const contentlet = document.querySelector('.contentlet');
|
|
145
|
+
* const data = getClosestContainerData(contentlet);
|
|
146
|
+
* console.log(data);
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
export function getClosestContainerData(element: Element) {
|
|
150
|
+
// Find the closest ancestor element with data-dot-object="container" attribute
|
|
151
|
+
const container = element.closest('[data-dot-object="container"]') as HTMLElement;
|
|
152
|
+
|
|
153
|
+
// If a container element is found
|
|
154
|
+
if (container) {
|
|
155
|
+
// Return the dataset of the container element
|
|
156
|
+
return getContainerData(container);
|
|
157
|
+
} else {
|
|
158
|
+
// If no container element is found, return null
|
|
159
|
+
console.warn('No container found for the contentlet');
|
|
160
|
+
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Find the closest contentlet element based on HTMLElement.
|
|
167
|
+
*
|
|
168
|
+
* @export
|
|
169
|
+
* @param {HTMLElement | null} element - The starting element.
|
|
170
|
+
* @return {HTMLElement | null} The closest contentlet element or null if not found.
|
|
171
|
+
* @example
|
|
172
|
+
* const element = document.querySelector('.some-element');
|
|
173
|
+
* const contentlet = findDotElement(element);
|
|
174
|
+
* console.log(contentlet);
|
|
175
|
+
*/
|
|
176
|
+
export function findDotElement(element: HTMLElement | null): HTMLElement | null {
|
|
177
|
+
if (!element) return null;
|
|
178
|
+
|
|
179
|
+
if (
|
|
180
|
+
element?.dataset?.['dotObject'] === 'contentlet' ||
|
|
181
|
+
(element?.dataset?.['dotObject'] === 'container' && element.children.length === 0)
|
|
182
|
+
) {
|
|
183
|
+
return element;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return findDotElement(element?.['parentElement']);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Find the closest VTL file element based on HTMLElement.
|
|
191
|
+
*
|
|
192
|
+
* @export
|
|
193
|
+
* @param {HTMLElement | null} element - The starting element.
|
|
194
|
+
* @return {HTMLElement | null} The closest VTL file element or null if not found.
|
|
195
|
+
* @example
|
|
196
|
+
* const element = document.querySelector('.some-element');
|
|
197
|
+
* const vtlFile = findDotVTLElement(element);
|
|
198
|
+
* console.log(vtlFile);
|
|
199
|
+
*/
|
|
200
|
+
export function findDotVTLElement(element: HTMLElement | null): HTMLElement | null {
|
|
201
|
+
if (!element) return null;
|
|
202
|
+
|
|
203
|
+
if (element.dataset && element.dataset?.['dotObject'] === 'vtl-file') {
|
|
204
|
+
return element;
|
|
205
|
+
} else {
|
|
206
|
+
return findDotElement(element?.['parentElement']);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Find VTL data within a target element.
|
|
212
|
+
*
|
|
213
|
+
* @export
|
|
214
|
+
* @param {HTMLElement} target - The target element to search within.
|
|
215
|
+
* @return {Array<{ inode: string, name: string }> | null} An array of objects containing VTL data or null if none found.
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* const target = document.querySelector('.target-element');
|
|
219
|
+
* const vtlData = findVTLData(target);
|
|
220
|
+
* console.log(vtlData);
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export function findVTLData(target: HTMLElement) {
|
|
224
|
+
const vltElements = target.querySelectorAll(
|
|
225
|
+
'[data-dot-object="vtl-file"]'
|
|
226
|
+
) as NodeListOf<HTMLElement>;
|
|
227
|
+
|
|
228
|
+
if (!vltElements.length) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return Array.from(vltElements).map((vltElement) => {
|
|
233
|
+
return {
|
|
234
|
+
inode: vltElement.dataset?.['dotInode'],
|
|
235
|
+
name: vltElement.dataset?.['dotUrl']
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Check if the scroll position is at the bottom of the page.
|
|
242
|
+
*
|
|
243
|
+
* @export
|
|
244
|
+
* @return {boolean} True if the scroll position is at the bottom, otherwise false.
|
|
245
|
+
* @example
|
|
246
|
+
* ```ts
|
|
247
|
+
* if (scrollIsInBottom()) {
|
|
248
|
+
* console.log('Scrolled to the bottom');
|
|
249
|
+
* }
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
export function scrollIsInBottom() {
|
|
253
|
+
const documentHeight = document.documentElement.scrollHeight;
|
|
254
|
+
const viewportHeight = window.innerHeight;
|
|
255
|
+
const scrollY = window.scrollY;
|
|
256
|
+
|
|
257
|
+
return scrollY + viewportHeight >= documentHeight;
|
|
258
|
+
}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { Field } from './Field';
|
|
2
2
|
import { NotOperand } from './NotOperand';
|
|
3
3
|
import { Operand } from './Operand';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
OPERAND,
|
|
7
|
+
buildExcludeField,
|
|
8
|
+
buildField,
|
|
9
|
+
buildNotOperand,
|
|
10
|
+
buildOperand,
|
|
11
|
+
buildRawEquals,
|
|
12
|
+
sanitizeQuery
|
|
13
|
+
} from '../utils';
|
|
14
|
+
|
|
4
15
|
/**
|
|
5
16
|
* 'Equal' Is a Typescript class that provides the ability to use terms in the lucene query string.
|
|
6
17
|
* A term is a value used to search for a specific value in a document. It can be a word or a phrase.
|
|
@@ -10,74 +21,128 @@ import { Operand } from './Operand';
|
|
|
10
21
|
* @export
|
|
11
22
|
* @class Equal
|
|
12
23
|
*/
|
|
13
|
-
export
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
constructor(query: string)
|
|
24
|
+
export class Equals {
|
|
25
|
+
#query = '';
|
|
26
|
+
|
|
27
|
+
constructor(private query: string) {
|
|
28
|
+
this.#query = this.query;
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
/**
|
|
18
32
|
* This method appends to the query a term that should be excluded in the search.
|
|
19
33
|
*
|
|
20
|
-
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const equals = new Equals("+myField: myValue");
|
|
37
|
+
* equals.excludeField("myField2").equals("myValue2"); // Current query: "+myField: myValue -myField2: myValue2"
|
|
38
|
+
* ```
|
|
21
39
|
*
|
|
22
40
|
* @param {string} field - The field that should be excluded in the search.
|
|
23
41
|
* @return {*} {Field} - An instance of a Lucene Field. A field is a key used to search for a specific value in a document.
|
|
24
42
|
* @memberof Equal
|
|
25
43
|
*/
|
|
26
|
-
excludeField(field: string): Field
|
|
44
|
+
excludeField(field: string): Field {
|
|
45
|
+
return buildExcludeField(this.#query, field);
|
|
46
|
+
}
|
|
47
|
+
|
|
27
48
|
/**
|
|
28
49
|
* This method appends to the query a field that should be included in the search.
|
|
29
50
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const equals = new Equals("+myField: myValue");
|
|
54
|
+
* equals.field("myField2").equals("myValue2"); // Current query: "+myField: myValue +myField2: myValue2"
|
|
55
|
+
*```
|
|
32
56
|
* @param {string} field - The field that should be included in the search.
|
|
33
57
|
* @return {*} {Field} - An instance of a Lucene Field. A field is a key used to search for a specific value in a document.
|
|
34
58
|
* @memberof Equal
|
|
35
59
|
*/
|
|
36
|
-
field(field: string): Field
|
|
60
|
+
field(field: string): Field {
|
|
61
|
+
return buildField(this.#query, field);
|
|
62
|
+
}
|
|
63
|
+
|
|
37
64
|
/**
|
|
38
65
|
* This method appends to the query an operand to use logic operators in the query.
|
|
39
66
|
*
|
|
40
|
-
*
|
|
67
|
+
* @example
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const equals = new Equals("+myField: myValue");
|
|
71
|
+
* equals.or().field("myField2").equals("myValue2"); // Current query: "+myField: myValue OR +myField2: myValue2"
|
|
72
|
+
* ```
|
|
41
73
|
*
|
|
42
74
|
* @return {*} {Operand} - An instance of a Lucene Operand. An operand is a logical operator used to combine terms or phrases in a query.
|
|
43
75
|
* @memberof Equal
|
|
44
76
|
*/
|
|
45
|
-
or(): Operand
|
|
77
|
+
or(): Operand {
|
|
78
|
+
return buildOperand(this.#query, OPERAND.OR);
|
|
79
|
+
}
|
|
80
|
+
|
|
46
81
|
/**
|
|
47
82
|
* This method appends to the query an operand to use logic operators in the query.
|
|
48
83
|
*
|
|
49
|
-
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const equals = new Equals("+myField: myValue");
|
|
87
|
+
* equals.and().field("myField2").equals("myValue2"); // Current query: "+myField: myValue AND +myField2: myValue2"
|
|
88
|
+
* ```
|
|
50
89
|
*
|
|
51
90
|
* @return {*} {Operand} - An instance of a Lucene Operand. An operand is a logical operator used to combine terms or phrases in a query.
|
|
52
91
|
* @memberof Equal
|
|
53
92
|
*/
|
|
54
|
-
and(): Operand
|
|
93
|
+
and(): Operand {
|
|
94
|
+
return buildOperand(this.#query, OPERAND.AND);
|
|
95
|
+
}
|
|
96
|
+
|
|
55
97
|
/**
|
|
56
98
|
* This method appends to the query an operand to use logic operators in the query.
|
|
57
99
|
*
|
|
58
|
-
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* const equals = new Equals("+myField: myValue");
|
|
103
|
+
* equals.not().field("myField").equals("myValue2"); // Current query: "+myField: myValue NOT +myField: myValue2"
|
|
104
|
+
* ```
|
|
59
105
|
*
|
|
60
106
|
* @return {*} {NotOperand} - An instance of a Lucene Not Operand. A not operand is a logical operator used to exclude terms or phrases in a query.
|
|
61
107
|
* @memberof Equal
|
|
62
108
|
*/
|
|
63
|
-
not(): NotOperand
|
|
109
|
+
not(): NotOperand {
|
|
110
|
+
return buildNotOperand(this.#query);
|
|
111
|
+
}
|
|
112
|
+
|
|
64
113
|
/**
|
|
65
114
|
* This method allows to pass a raw query string to the query builder.
|
|
66
115
|
* This raw query should end in a Lucene Equal.
|
|
67
116
|
* This method is useful when you want to append a complex query or an already written query to the query builder.
|
|
68
117
|
*
|
|
69
|
-
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* // This builds the follow raw query "+myField: value AND (someOtherValue OR anotherValue)"
|
|
121
|
+
* const equals = new Equals("+myField: value");
|
|
122
|
+
* equals.raw("+myField2: value2"); // Current query: "+myField: value +myField2: anotherValue"
|
|
123
|
+
* ```
|
|
70
124
|
*
|
|
71
125
|
* @param {string} query - A raw query string.
|
|
72
126
|
* @return {*} {Equal} - An instance of a Lucene Equal. A term is a value used to search for a specific value in a document.
|
|
73
127
|
* @memberof QueryBuilder
|
|
74
128
|
*/
|
|
75
|
-
raw(query: string): Equals
|
|
129
|
+
raw(query: string): Equals {
|
|
130
|
+
return buildRawEquals(this.#query, query);
|
|
131
|
+
}
|
|
132
|
+
|
|
76
133
|
/**
|
|
77
134
|
* This method returns the final query string.
|
|
78
135
|
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* const equals = new Equals("+myField: myValue");
|
|
139
|
+
* equals.field("myField2").equals("myValue2").build(); // Returns "+myField: myValue +myField2: myValue2"
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
79
142
|
* @return {*} {string} - The final query string.
|
|
80
143
|
* @memberof Equal
|
|
81
144
|
*/
|
|
82
|
-
build(): string
|
|
145
|
+
build(): string {
|
|
146
|
+
return sanitizeQuery(this.#query);
|
|
147
|
+
}
|
|
83
148
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Equals } from './Equals';
|
|
2
|
+
|
|
3
|
+
import { buildEquals } from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `Field` class is used to build a query with a specific field.
|
|
7
|
+
* A Lucene Field is a key used to search for a specific value in a document.
|
|
8
|
+
*
|
|
9
|
+
* @export
|
|
10
|
+
* @class Field
|
|
11
|
+
*/
|
|
12
|
+
export class Field {
|
|
13
|
+
#query = '';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates an instance of the `Field` class.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} query - The initial query string.
|
|
19
|
+
*/
|
|
20
|
+
constructor(private query: string) {
|
|
21
|
+
this.#query = this.query;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Appends a term to the query that should be included in the search.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const field = new Field("+myField");
|
|
30
|
+
* field.equals("myValue");
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @param {string} term - The term that should be included in the search.
|
|
34
|
+
* @return {Equals} - An instance of `Equals`.
|
|
35
|
+
* @memberof Field
|
|
36
|
+
*/
|
|
37
|
+
equals(term: string): Equals {
|
|
38
|
+
return buildEquals(this.#query, term);
|
|
39
|
+
}
|
|
40
|
+
}
|