@dotcms/client 0.0.1-alpha.1 → 0.0.1-alpha.11
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 +8 -10
- package/jest.config.ts +15 -0
- package/package.json +24 -26
- package/project.json +63 -0
- package/src/index.ts +4 -0
- package/src/lib/client/sdk-js-client.spec.ts +258 -0
- package/src/lib/client/sdk-js-client.ts +297 -0
- package/src/lib/editor/listeners/listeners.spec.ts +58 -0
- package/src/lib/editor/listeners/listeners.ts +195 -0
- package/src/lib/{postMessageToEditor.d.ts → editor/models/client.model.ts} +16 -8
- package/src/lib/editor/models/editor.model.ts +17 -0
- package/src/lib/editor/models/listeners.model.ts +46 -0
- package/src/lib/editor/sdk-editor-vtl.ts +32 -0
- package/src/lib/editor/sdk-editor.spec.ts +92 -0
- package/src/lib/editor/sdk-editor.ts +68 -0
- package/src/lib/editor/utils/editor.utils.spec.ts +164 -0
- package/src/lib/editor/utils/editor.utils.ts +178 -0
- package/tsconfig.json +22 -0
- package/tsconfig.lib.json +10 -0
- package/tsconfig.spec.json +9 -0
- package/src/index.d.ts +0 -2
- package/src/index.js +0 -3
- package/src/index.js.map +0 -1
- package/src/lib/postMessageToEditor.js +0 -37
- package/src/lib/postMessageToEditor.js.map +0 -1
- package/src/lib/sdk-js-client.d.ts +0 -171
- package/src/lib/sdk-js-client.js +0 -150
- package/src/lib/sdk-js-client.js.map +0 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
listenEditorMessages,
|
|
3
|
+
listenHoveredContentlet,
|
|
4
|
+
pingEditor,
|
|
5
|
+
scrollHandler
|
|
6
|
+
} from './listeners/listeners';
|
|
7
|
+
import { postMessageToEditor, CUSTOMER_ACTIONS } from './models/client.model';
|
|
8
|
+
import { initEditor, isInsideEditor, updateNavigation } from './sdk-editor';
|
|
9
|
+
|
|
10
|
+
jest.mock('./models/client.model', () => ({
|
|
11
|
+
postMessageToEditor: jest.fn(),
|
|
12
|
+
CUSTOMER_ACTIONS: {
|
|
13
|
+
NAVIGATION_UPDATE: 'set-url',
|
|
14
|
+
SET_BOUNDS: 'set-bounds',
|
|
15
|
+
SET_CONTENTLET: 'set-contentlet',
|
|
16
|
+
IFRAME_SCROLL: 'scroll',
|
|
17
|
+
PING_EDITOR: 'ping-editor',
|
|
18
|
+
CONTENT_CHANGE: 'content-change',
|
|
19
|
+
NOOP: 'noop'
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
jest.mock('./listeners/listeners', () => ({
|
|
24
|
+
pingEditor: jest.fn(),
|
|
25
|
+
listenEditorMessages: jest.fn(),
|
|
26
|
+
listenHoveredContentlet: jest.fn(),
|
|
27
|
+
scrollHandler: jest.fn(),
|
|
28
|
+
listenContentChange: jest.fn()
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
describe('DotCMSPageEditor', () => {
|
|
32
|
+
describe('is NOT inside editor', () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
const mockWindow = {
|
|
35
|
+
...window,
|
|
36
|
+
parent: window
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const spy = jest.spyOn(global, 'window', 'get');
|
|
40
|
+
spy.mockReturnValueOnce(mockWindow as unknown as Window & typeof globalThis);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
jest.clearAllMocks();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should initialize without any listener', () => {
|
|
48
|
+
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
|
49
|
+
|
|
50
|
+
expect(isInsideEditor()).toBe(false);
|
|
51
|
+
expect(addEventListenerSpy).not.toHaveBeenCalled();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('is inside editor', () => {
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
const mockWindow = {
|
|
58
|
+
...window,
|
|
59
|
+
parent: null
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const spy = jest.spyOn(global, 'window', 'get');
|
|
63
|
+
spy.mockReturnValue(mockWindow as unknown as Window & typeof globalThis);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
afterEach(() => {
|
|
67
|
+
jest.clearAllMocks();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should initialize properly', () => {
|
|
71
|
+
expect(isInsideEditor()).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should update navigation', () => {
|
|
75
|
+
updateNavigation('/');
|
|
76
|
+
expect(postMessageToEditor).toHaveBeenCalledWith({
|
|
77
|
+
action: CUSTOMER_ACTIONS.NAVIGATION_UPDATE,
|
|
78
|
+
payload: {
|
|
79
|
+
url: 'index'
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should init editor calling listeners', () => {
|
|
85
|
+
initEditor();
|
|
86
|
+
expect(pingEditor).toHaveBeenCalled();
|
|
87
|
+
expect(listenEditorMessages).toHaveBeenCalled();
|
|
88
|
+
expect(listenHoveredContentlet).toHaveBeenCalled();
|
|
89
|
+
expect(scrollHandler).toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
listenEditorMessages,
|
|
3
|
+
listenHoveredContentlet,
|
|
4
|
+
pingEditor,
|
|
5
|
+
scrollHandler,
|
|
6
|
+
subscriptions,
|
|
7
|
+
setPageEditorConfig
|
|
8
|
+
} from './listeners/listeners';
|
|
9
|
+
import { CUSTOMER_ACTIONS, postMessageToEditor } from './models/client.model';
|
|
10
|
+
import { DotCMSPageEditorConfig } from './models/editor.model';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* Updates the navigation in the editor.
|
|
15
|
+
* @param {string} pathname - The pathname to update the navigation with.
|
|
16
|
+
* @memberof DotCMSPageEditor
|
|
17
|
+
*/
|
|
18
|
+
export function updateNavigation(pathname: string) {
|
|
19
|
+
postMessageToEditor({
|
|
20
|
+
action: CUSTOMER_ACTIONS.NAVIGATION_UPDATE,
|
|
21
|
+
payload: {
|
|
22
|
+
url: pathname === '/' ? 'index' : pathname?.replace('/', '')
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Checks if the code is running inside an editor.
|
|
29
|
+
* @returns {boolean} Returns true if the code is running inside an editor, otherwise false.
|
|
30
|
+
*/
|
|
31
|
+
export function isInsideEditor() {
|
|
32
|
+
if (window.parent === window) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Initializes the DotCMS page editor.
|
|
41
|
+
*
|
|
42
|
+
* @param conf - Optional configuration for the editor.
|
|
43
|
+
*/
|
|
44
|
+
export function initEditor(config?: DotCMSPageEditorConfig) {
|
|
45
|
+
if (config) {
|
|
46
|
+
setPageEditorConfig(config);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pingEditor();
|
|
50
|
+
listenEditorMessages();
|
|
51
|
+
listenHoveredContentlet();
|
|
52
|
+
scrollHandler();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Destroys the editor by removing event listeners and disconnecting observers.
|
|
57
|
+
*/
|
|
58
|
+
export function destroyEditor() {
|
|
59
|
+
subscriptions.forEach((subscription) => {
|
|
60
|
+
if (subscription.type === 'listener') {
|
|
61
|
+
window.removeEventListener(subscription.event, subscription.callback as EventListener);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (subscription.type === 'observer') {
|
|
65
|
+
subscription.observer.disconnect();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { getContentletsBound } 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
|
+
});
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bound information for a contentlet.
|
|
3
|
+
*
|
|
4
|
+
* @interface ContentletBound
|
|
5
|
+
*/
|
|
6
|
+
interface ContentletBound {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
payload: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Bound information for a container.
|
|
16
|
+
*
|
|
17
|
+
* @interface ContenainerBound
|
|
18
|
+
*/
|
|
19
|
+
interface ContenainerBound {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
payload: {
|
|
25
|
+
container: {
|
|
26
|
+
acceptTypes: string;
|
|
27
|
+
identifier: string;
|
|
28
|
+
maxContentlets: string;
|
|
29
|
+
uuid: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
contentlets: ContentletBound[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Calculates the bounding information for each page element within the given containers.
|
|
37
|
+
*
|
|
38
|
+
* @export
|
|
39
|
+
* @param {HTMLDivElement[]} containers
|
|
40
|
+
* @return {*} An array of objects containing the bounding information for each page element.
|
|
41
|
+
*/
|
|
42
|
+
export function getPageElementBound(containers: HTMLDivElement[]): ContenainerBound[] {
|
|
43
|
+
return containers.map((container) => {
|
|
44
|
+
const containerRect = container.getBoundingClientRect();
|
|
45
|
+
const contentlets = Array.from(
|
|
46
|
+
container.querySelectorAll('[data-dot-object="contentlet"]')
|
|
47
|
+
) as HTMLDivElement[];
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
x: containerRect.x,
|
|
51
|
+
y: containerRect.y,
|
|
52
|
+
width: containerRect.width,
|
|
53
|
+
height: containerRect.height,
|
|
54
|
+
payload: {
|
|
55
|
+
container: getContainerData(container)
|
|
56
|
+
},
|
|
57
|
+
contentlets: getContentletsBound(containerRect, contentlets)
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* An array of objects containing the bounding information for each contentlet inside a container.
|
|
64
|
+
*
|
|
65
|
+
* @export
|
|
66
|
+
* @param {DOMRect} containerRect
|
|
67
|
+
* @param {HTMLDivElement[]} contentlets
|
|
68
|
+
* @return {*}
|
|
69
|
+
*/
|
|
70
|
+
export function getContentletsBound(
|
|
71
|
+
containerRect: DOMRect,
|
|
72
|
+
contentlets: HTMLDivElement[]
|
|
73
|
+
): ContentletBound[] {
|
|
74
|
+
return contentlets.map((contentlet) => {
|
|
75
|
+
const contentletRect = contentlet.getBoundingClientRect();
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
x: 0,
|
|
79
|
+
y: contentletRect.y - containerRect.y,
|
|
80
|
+
width: contentletRect.width,
|
|
81
|
+
height: contentletRect.height,
|
|
82
|
+
payload: JSON.stringify({
|
|
83
|
+
container: contentlet.dataset?.['dotContainer']
|
|
84
|
+
? JSON.parse(contentlet.dataset?.['dotContainer'])
|
|
85
|
+
: getClosestContainerData(contentlet),
|
|
86
|
+
contentlet: {
|
|
87
|
+
identifier: contentlet.dataset?.['dotIdentifier'],
|
|
88
|
+
title: contentlet.dataset?.['dotTitle'],
|
|
89
|
+
inode: contentlet.dataset?.['dotInode'],
|
|
90
|
+
contentType: contentlet.dataset?.['dotType']
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get container data from VTLS.
|
|
99
|
+
*
|
|
100
|
+
* @export
|
|
101
|
+
* @param {HTMLElement} container
|
|
102
|
+
* @return {*}
|
|
103
|
+
*/
|
|
104
|
+
export function getContainerData(container: HTMLElement) {
|
|
105
|
+
return {
|
|
106
|
+
acceptTypes: container.dataset?.['dotAcceptTypes'] || '',
|
|
107
|
+
identifier: container.dataset?.['dotIdentifier'] || '',
|
|
108
|
+
maxContentlets: container.dataset?.['maxContentlets'] || '',
|
|
109
|
+
uuid: container.dataset?.['dotUuid'] || ''
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get the closest container data from the contentlet.
|
|
115
|
+
*
|
|
116
|
+
* @export
|
|
117
|
+
* @param {Element} element
|
|
118
|
+
* @return {*}
|
|
119
|
+
*/
|
|
120
|
+
export function getClosestContainerData(element: Element) {
|
|
121
|
+
// Find the closest ancestor element with data-dot-object="container" attribute
|
|
122
|
+
const container = element.closest('[data-dot-object="container"]') as HTMLElement;
|
|
123
|
+
|
|
124
|
+
// If a container element is found
|
|
125
|
+
if (container) {
|
|
126
|
+
// Return the dataset of the container element
|
|
127
|
+
return getContainerData(container);
|
|
128
|
+
} else {
|
|
129
|
+
// If no container element is found, return null
|
|
130
|
+
console.warn('No container found for the contentlet');
|
|
131
|
+
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Find the closest contentlet element based on HTMLElement.
|
|
138
|
+
*
|
|
139
|
+
* @export
|
|
140
|
+
* @param {(HTMLElement | null)} element
|
|
141
|
+
* @return {*}
|
|
142
|
+
*/
|
|
143
|
+
export function findContentletElement(element: HTMLElement | null): HTMLElement | null {
|
|
144
|
+
if (!element) return null;
|
|
145
|
+
|
|
146
|
+
if (element.dataset && element.dataset?.['dotObject'] === 'contentlet') {
|
|
147
|
+
return element;
|
|
148
|
+
} else {
|
|
149
|
+
return findContentletElement(element?.['parentElement']);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function findVTLElement(element: HTMLElement | null): HTMLElement | null {
|
|
154
|
+
if (!element) return null;
|
|
155
|
+
|
|
156
|
+
if (element.dataset && element.dataset?.['dotObject'] === 'vtl-file') {
|
|
157
|
+
return element;
|
|
158
|
+
} else {
|
|
159
|
+
return findContentletElement(element?.['parentElement']);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function findVTLData(target: HTMLElement) {
|
|
164
|
+
const vltElements = target.querySelectorAll(
|
|
165
|
+
'[data-dot-object="vtl-file"]'
|
|
166
|
+
) as NodeListOf<HTMLElement>;
|
|
167
|
+
|
|
168
|
+
if (!vltElements.length) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return Array.from(vltElements).map((vltElement) => {
|
|
173
|
+
return {
|
|
174
|
+
inode: vltElement.dataset?.['dotInode'],
|
|
175
|
+
name: vltElement.dataset?.['dotUrl']
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"forceConsistentCasingInFileNames": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noImplicitOverride": true,
|
|
8
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
9
|
+
"noImplicitReturns": true,
|
|
10
|
+
"noFallthroughCasesInSwitch": true
|
|
11
|
+
},
|
|
12
|
+
"files": [],
|
|
13
|
+
"include": [],
|
|
14
|
+
"references": [
|
|
15
|
+
{
|
|
16
|
+
"path": "./tsconfig.lib.json"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"path": "./tsconfig.spec.json"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
package/src/index.d.ts
DELETED
package/src/index.js
DELETED
package/src/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/sdk/client/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Actions send to the dotcms editor
|
|
3
|
-
*
|
|
4
|
-
* @export
|
|
5
|
-
* @enum {number}
|
|
6
|
-
*/
|
|
7
|
-
export var CUSTOMER_ACTIONS;
|
|
8
|
-
(function (CUSTOMER_ACTIONS) {
|
|
9
|
-
/**
|
|
10
|
-
* Tell the dotcms editor that page change
|
|
11
|
-
*/
|
|
12
|
-
CUSTOMER_ACTIONS["SET_URL"] = "set-url";
|
|
13
|
-
/**
|
|
14
|
-
* Send the element position of the rows, columnsm containers and contentlets
|
|
15
|
-
*/
|
|
16
|
-
CUSTOMER_ACTIONS["SET_BOUNDS"] = "set-bounds";
|
|
17
|
-
/**
|
|
18
|
-
* Send the information of the hovered contentlet
|
|
19
|
-
*/
|
|
20
|
-
CUSTOMER_ACTIONS["SET_CONTENTLET"] = "set-contentlet";
|
|
21
|
-
/**
|
|
22
|
-
* Tell the editor that the page is being scrolled
|
|
23
|
-
*/
|
|
24
|
-
CUSTOMER_ACTIONS["IFRAME_SCROLL"] = "scroll";
|
|
25
|
-
CUSTOMER_ACTIONS["NOOP"] = "noop";
|
|
26
|
-
})(CUSTOMER_ACTIONS || (CUSTOMER_ACTIONS = {}));
|
|
27
|
-
/**
|
|
28
|
-
* Post message to dotcms page editor
|
|
29
|
-
*
|
|
30
|
-
* @export
|
|
31
|
-
* @template T
|
|
32
|
-
* @param {PostMessageProps<T>} message
|
|
33
|
-
*/
|
|
34
|
-
export function postMessageToEditor(message) {
|
|
35
|
-
window.parent.postMessage(message, '*');
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=postMessageToEditor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"postMessageToEditor.js","sourceRoot":"","sources":["../../../../../../libs/sdk/client/src/lib/postMessageToEditor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAN,IAAY,gBAkBX;AAlBD,WAAY,gBAAgB;IACxB;;OAEG;IACH,uCAAmB,CAAA;IACnB;;OAEG;IACH,6CAAyB,CAAA;IACzB;;OAEG;IACH,qDAAiC,CAAA;IACjC;;OAEG;IACH,4CAAwB,CAAA;IACxB,iCAAa,CAAA;AACjB,CAAC,EAlBW,gBAAgB,KAAhB,gBAAgB,QAkB3B;AAcD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAc,OAA4B;IACzE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC"}
|