@servicetitan/dte-unlayer 0.152.0 → 0.154.0
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/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +25 -10
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loadScript.d.ts.map +1 -1
- package/dist/loadScript.js +8 -1
- package/dist/loadScript.js.map +1 -1
- package/dist/log.d.ts +3 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +21 -0
- package/dist/log.js.map +1 -0
- package/dist/merge-tags.d.ts +15 -2
- package/dist/merge-tags.d.ts.map +1 -1
- package/dist/merge-tags.js +40 -22
- package/dist/merge-tags.js.map +1 -1
- package/dist/shared/instance-id.d.ts +13 -0
- package/dist/shared/instance-id.d.ts.map +1 -0
- package/dist/shared/instance-id.js +22 -0
- package/dist/shared/instance-id.js.map +1 -0
- package/dist/store.d.ts +19 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +109 -11
- package/dist/store.js.map +1 -1
- package/dist/tools.d.ts +12 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +47 -0
- package/dist/tools.js.map +1 -1
- package/dist/unlayer-interface.d.ts +11 -1
- package/dist/unlayer-interface.d.ts.map +1 -1
- package/dist/unlayer-interface.js.map +1 -1
- package/dist/unlayer.d.ts.map +1 -1
- package/dist/unlayer.js +90 -73
- package/dist/unlayer.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/load-script.test.ts +41 -0
- package/src/__tests__/log.test.ts +44 -0
- package/src/__tests__/merge-tags.test.ts +133 -18
- package/src/__tests__/store.merge-tags.test.ts +186 -0
- package/src/editor.tsx +20 -9
- package/src/index.ts +7 -1
- package/src/loadScript.ts +9 -1
- package/src/log.ts +24 -0
- package/src/merge-tags.ts +59 -25
- package/src/shared/instance-id.ts +23 -0
- package/src/store.ts +128 -10
- package/src/tools.ts +51 -0
- package/src/unlayer-interface.tsx +11 -1
- package/src/unlayer.tsx +81 -61
package/src/store.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { loadScript } from './loadScript';
|
|
2
|
+
import { logUnlayerError } from './log';
|
|
3
|
+
import { toUnlayerMergeTags, type UnlayerMergeTagsConfig } from './merge-tags';
|
|
2
4
|
import { defaultImageValidation } from './shared/configs';
|
|
3
5
|
import type { UnlayerEditorTwin, UnlayerEventConfig, UnlayerEventRegister } from './shared/const';
|
|
4
6
|
import { unlayerSupportedFonts } from './shared/fonts';
|
|
@@ -10,16 +12,22 @@ import {
|
|
|
10
12
|
} from './shared/forms';
|
|
11
13
|
import { schemaBuildMap, schemaIsDate } from './shared/schema';
|
|
12
14
|
import { unlayerToolsParseTwinKey } from './shared/tools';
|
|
13
|
-
import { unlayerToolsIterate } from './tools';
|
|
15
|
+
import { unlayerToolsDedupeInstanceIds, unlayerToolsIterate } from './tools';
|
|
14
16
|
import {
|
|
15
17
|
createUnlayerEditor,
|
|
16
18
|
DesignUpdatedEventType,
|
|
17
19
|
EventDesignUpdated,
|
|
18
20
|
Unlayer,
|
|
19
21
|
} from './unlayer';
|
|
20
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
CreateUnlayerEditorProps,
|
|
24
|
+
UnlayerDesignFormat,
|
|
25
|
+
UnlayerEditorMergeTagInfo,
|
|
26
|
+
UnlayerRef,
|
|
27
|
+
} from './unlayer-interface';
|
|
21
28
|
|
|
22
29
|
const defaultScriptUrl = 'https://editor.unlayer.com/embed.js?2';
|
|
30
|
+
const UNLAYER_TOOLS_READY_TIMEOUT_MS = 30000;
|
|
23
31
|
|
|
24
32
|
const normalizeFontToken = (font: string) =>
|
|
25
33
|
font.replace(/["']/g, '').split(',')[0].trim().toLowerCase();
|
|
@@ -184,8 +192,14 @@ export class UnlayerStore {
|
|
|
184
192
|
private isInit = false;
|
|
185
193
|
private iframe?: HTMLIFrameElement;
|
|
186
194
|
private hasDesign = false;
|
|
195
|
+
private hasCoreLoaded = false;
|
|
196
|
+
private hasToolsRegistered = false;
|
|
197
|
+
private toolsReadyWatchdogId?: number;
|
|
187
198
|
private formFieldsByFormId: Record<number, FormFieldInfo[]> = {};
|
|
188
199
|
private formFieldSamples: Record<string, unknown> = {};
|
|
200
|
+
private isEditorReady = false;
|
|
201
|
+
private isMergeTagsApplied = false;
|
|
202
|
+
private mergeTagsConfig?: UnlayerMergeTagsConfig;
|
|
189
203
|
|
|
190
204
|
private onMessageCB?: (type: string, data: any) => void;
|
|
191
205
|
private onChangeCB?: (info: UnlayerDesignChangeInfo) => void;
|
|
@@ -231,6 +245,9 @@ export class UnlayerStore {
|
|
|
231
245
|
sendCalcFieldLabels: labels => {
|
|
232
246
|
this.sendCalcFieldLabels(labels);
|
|
233
247
|
},
|
|
248
|
+
setMergeTags: tags => {
|
|
249
|
+
this.setMergeTags(tags);
|
|
250
|
+
},
|
|
234
251
|
};
|
|
235
252
|
}
|
|
236
253
|
|
|
@@ -241,22 +258,44 @@ export class UnlayerStore {
|
|
|
241
258
|
|
|
242
259
|
this.isInit = true;
|
|
243
260
|
|
|
244
|
-
|
|
261
|
+
try {
|
|
262
|
+
setTimeout(() => window.addEventListener('message', this.onPostMessage));
|
|
263
|
+
|
|
264
|
+
await loadScript(defaultScriptUrl);
|
|
265
|
+
|
|
266
|
+
if (!(window as any).unlayer) {
|
|
267
|
+
throw new Error('Unlayer embed script loaded but window.unlayer is missing');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
this.editor = createUnlayerEditor(container, this.props);
|
|
271
|
+
// The host may already have pushed a newer set through `setMergeTags`; keep it.
|
|
272
|
+
this.mergeTagsConfig ??= toUnlayerMergeTags(this.props.mergeTags);
|
|
273
|
+
this.editor.addEventListener('editor:ready', this.onEditorReady);
|
|
274
|
+
this.editor.addEventListener('design:loaded', this.onDesignLoaded);
|
|
275
|
+
this.editor.addEventListener('design:updated', this.onDesignUpdated);
|
|
276
|
+
this.editor.registerCallback('image', this.uploadImage);
|
|
245
277
|
|
|
246
|
-
|
|
278
|
+
this.iframe = container.querySelector(`iframe`) ?? undefined;
|
|
247
279
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.editor.registerCallback('image', this.uploadImage);
|
|
280
|
+
if (!this.iframe) {
|
|
281
|
+
logUnlayerError('Unlayer iframe was not created after createEditor');
|
|
282
|
+
}
|
|
252
283
|
|
|
253
|
-
|
|
284
|
+
this.startToolsReadyWatchdog();
|
|
285
|
+
} catch (error: unknown) {
|
|
286
|
+
this.isInit = false;
|
|
287
|
+
this.clearToolsReadyWatchdog();
|
|
288
|
+
logUnlayerError('Failed to initialize Unlayer editor', error);
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
254
291
|
};
|
|
255
292
|
|
|
256
293
|
destroy = () => {
|
|
294
|
+
this.clearToolsReadyWatchdog();
|
|
257
295
|
window.removeEventListener('message', this.onPostMessage);
|
|
258
296
|
|
|
259
297
|
if (this.editor) {
|
|
298
|
+
this.editor.removeEventListener('editor:ready', this.onEditorReady);
|
|
260
299
|
this.editor.removeEventListener('design:loaded', this.onDesignLoaded);
|
|
261
300
|
this.editor.removeEventListener('design:updated', this.onDesignUpdated);
|
|
262
301
|
this.editor.unregisterCallback('image', this.uploadImage);
|
|
@@ -332,7 +371,46 @@ export class UnlayerStore {
|
|
|
332
371
|
this.sendMessage('--calc-field-labels', { labels });
|
|
333
372
|
};
|
|
334
373
|
|
|
374
|
+
/**
|
|
375
|
+
* Replaces the editor's merge tag menu. Nested groups passed to `createEditor` stop DTE
|
|
376
|
+
* custom tools from registering, so init only carries the flat shape and the grouped
|
|
377
|
+
* config is applied here once the editor is ready. A call before that (including the
|
|
378
|
+
* initial props) is parked; a later call replaces it. A failed apply is retried on the
|
|
379
|
+
* next `design:loaded`.
|
|
380
|
+
*/
|
|
381
|
+
setMergeTags = (tags: UnlayerEditorMergeTagInfo[] | undefined) => {
|
|
382
|
+
this.mergeTagsConfig = toUnlayerMergeTags(tags);
|
|
383
|
+
this.isMergeTagsApplied = false;
|
|
384
|
+
this.applyMergeTags();
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
private applyMergeTags = () => {
|
|
388
|
+
if (
|
|
389
|
+
!this.editor ||
|
|
390
|
+
!this.isEditorReady ||
|
|
391
|
+
this.isMergeTagsApplied ||
|
|
392
|
+
!this.mergeTagsConfig
|
|
393
|
+
) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
try {
|
|
398
|
+
this.editor.setMergeTags(this.mergeTagsConfig);
|
|
399
|
+
this.isMergeTagsApplied = true;
|
|
400
|
+
} catch (error: unknown) {
|
|
401
|
+
logUnlayerError('Failed to apply merge tags', error);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
private onEditorReady = () => {
|
|
406
|
+
this.isEditorReady = true;
|
|
407
|
+
this.applyMergeTags();
|
|
408
|
+
};
|
|
409
|
+
|
|
335
410
|
private onDesignLoaded = () => {
|
|
411
|
+
// A loaded design means the editor is up even if `editor:ready` never reached us.
|
|
412
|
+
this.onEditorReady();
|
|
413
|
+
|
|
336
414
|
if (!this.hasDesign) {
|
|
337
415
|
this.hasDesign = true;
|
|
338
416
|
this.editor?.setBodyValues({
|
|
@@ -368,6 +446,11 @@ export class UnlayerStore {
|
|
|
368
446
|
}
|
|
369
447
|
});
|
|
370
448
|
|
|
449
|
+
// Duplicated contents/rows carry the original's instance GUIDs; give copies new ones.
|
|
450
|
+
if (unlayerToolsDedupeInstanceIds(data.design, event.item?.values?._meta?.htmlID)) {
|
|
451
|
+
hasChanges = true;
|
|
452
|
+
}
|
|
453
|
+
|
|
371
454
|
if (hasChanges) {
|
|
372
455
|
this.setDesign(data.design);
|
|
373
456
|
}
|
|
@@ -392,8 +475,11 @@ export class UnlayerStore {
|
|
|
392
475
|
}
|
|
393
476
|
|
|
394
477
|
if (type === '--ready' || type === '--registered') {
|
|
478
|
+
this.hasToolsRegistered = true;
|
|
479
|
+
this.clearToolsReadyWatchdog();
|
|
395
480
|
this.onReadyCB?.();
|
|
396
481
|
} else if (type === '--core-loaded') {
|
|
482
|
+
this.hasCoreLoaded = true;
|
|
397
483
|
const configData: UnlayerEventConfig = {
|
|
398
484
|
dummyData: this.props.dummyData,
|
|
399
485
|
schema: this.props.schema,
|
|
@@ -588,6 +674,7 @@ export class UnlayerStore {
|
|
|
588
674
|
});
|
|
589
675
|
|
|
590
676
|
if (!res.isValid) {
|
|
677
|
+
logUnlayerError(`Image validation failed: ${res.title}`, res.description);
|
|
591
678
|
this.onErrorCB?.(res.title, res.description);
|
|
592
679
|
return;
|
|
593
680
|
}
|
|
@@ -597,7 +684,8 @@ export class UnlayerStore {
|
|
|
597
684
|
try {
|
|
598
685
|
const { url } = await this.onImageCB(file);
|
|
599
686
|
done({ progress: 100, url });
|
|
600
|
-
} catch {
|
|
687
|
+
} catch (error: unknown) {
|
|
688
|
+
logUnlayerError('Image upload failed', error);
|
|
601
689
|
this.onErrorCB?.(
|
|
602
690
|
'Image upload failed',
|
|
603
691
|
'Something went wrong while uploading the image. Please try again or select another image.',
|
|
@@ -606,6 +694,36 @@ export class UnlayerStore {
|
|
|
606
694
|
}
|
|
607
695
|
};
|
|
608
696
|
|
|
697
|
+
private startToolsReadyWatchdog = () => {
|
|
698
|
+
this.clearToolsReadyWatchdog();
|
|
699
|
+
this.toolsReadyWatchdogId = window.setTimeout(() => {
|
|
700
|
+
if (this.hasToolsRegistered) {
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
logUnlayerError(
|
|
705
|
+
'Unlayer custom tools did not finish loading. customJS may not have run, or tool registration stalled.',
|
|
706
|
+
{
|
|
707
|
+
hasCoreLoaded: this.hasCoreLoaded,
|
|
708
|
+
hasToolsRegistered: this.hasToolsRegistered,
|
|
709
|
+
},
|
|
710
|
+
);
|
|
711
|
+
this.onErrorCB?.(
|
|
712
|
+
'Editor failed to load custom tools',
|
|
713
|
+
'Unlayer custom tools did not finish loading. Check the browser console for [dte-unlayer] details.',
|
|
714
|
+
);
|
|
715
|
+
}, UNLAYER_TOOLS_READY_TIMEOUT_MS);
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
private clearToolsReadyWatchdog = () => {
|
|
719
|
+
if (this.toolsReadyWatchdogId === undefined) {
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
window.clearTimeout(this.toolsReadyWatchdogId);
|
|
724
|
+
this.toolsReadyWatchdogId = undefined;
|
|
725
|
+
};
|
|
726
|
+
|
|
609
727
|
private validateImage = async (
|
|
610
728
|
file: File,
|
|
611
729
|
imageValidation: { maxFileSize: number; maxWidth: number; maxHeight: number },
|
package/src/tools.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { constGenericsEditor, UnlayerToolMetaData } from './shared/const';
|
|
2
2
|
import { editIconSvg } from './shared/edit-icon';
|
|
3
|
+
import { generateInstanceId, INSTANCE_ID_TOOL_SLUGS } from './shared/instance-id';
|
|
3
4
|
import { unlayerToolsParseUnitKey } from './shared/tools';
|
|
4
5
|
import { versions } from './unlayer';
|
|
5
6
|
|
|
@@ -202,6 +203,56 @@ export const unlayerToolsListCustom = (design: UnlayerDesignFormat): UnlayerDesi
|
|
|
202
203
|
return tools;
|
|
203
204
|
};
|
|
204
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Makes `values.id` unique across all instance-id tools (see `INSTANCE_ID_TOOL_SLUGS`)
|
|
208
|
+
* in the design. Duplicating content/rows in Unlayer copies the values verbatim, so
|
|
209
|
+
* every copy ends up with the original's GUID; this gives each copy a fresh one.
|
|
210
|
+
*
|
|
211
|
+
* Of the contents sharing an id, the one that keeps it is the first in document
|
|
212
|
+
* order that is not the just-added content (`addedHtmlID`), so the original always
|
|
213
|
+
* wins over its duplicate regardless of where the copy was inserted.
|
|
214
|
+
*
|
|
215
|
+
* @returns `true` when at least one id was regenerated.
|
|
216
|
+
*/
|
|
217
|
+
export const unlayerToolsDedupeInstanceIds = (
|
|
218
|
+
design: UnlayerDesignFormat,
|
|
219
|
+
addedHtmlID?: string
|
|
220
|
+
): boolean => {
|
|
221
|
+
const byId = new Map<string, UnlayerDesignCustomTool[]>();
|
|
222
|
+
|
|
223
|
+
unlayerToolsIterateCustom(design, tool => {
|
|
224
|
+
const id = tool.values?.id;
|
|
225
|
+
|
|
226
|
+
if (INSTANCE_ID_TOOL_SLUGS.includes(tool.slug) && typeof id === 'string' && id) {
|
|
227
|
+
const key = `${tool.slug}|${id}`;
|
|
228
|
+
byId.set(key, [...(byId.get(key) ?? []), tool]);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
let hasChanges = false;
|
|
233
|
+
|
|
234
|
+
byId.forEach(tools => {
|
|
235
|
+
if (tools.length < 2) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const keeper = tools.find(tool => tool.values?._meta?.htmlID !== addedHtmlID) ?? tools[0];
|
|
240
|
+
|
|
241
|
+
for (const tool of tools) {
|
|
242
|
+
if (tool !== keeper) {
|
|
243
|
+
/*
|
|
244
|
+
* If no id can be generated the copy is left without one, which is still
|
|
245
|
+
* better than two instances bound to the same image.
|
|
246
|
+
*/
|
|
247
|
+
tool.values.id = generateInstanceId();
|
|
248
|
+
hasChanges = true;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
return hasChanges;
|
|
254
|
+
};
|
|
255
|
+
|
|
205
256
|
export const unlayerToolsBuildDesign = (tools: UnlayerDesignTool[]): UnlayerDesignFormat => {
|
|
206
257
|
const design = unlayerGetDefaultDesign();
|
|
207
258
|
|
|
@@ -45,13 +45,23 @@ export interface UnlayerRef {
|
|
|
45
45
|
sendFormList(forms: FormInfo[]): void;
|
|
46
46
|
sendFormFields(formId: number, fields: FormFieldInfo[]): void;
|
|
47
47
|
sendCalcFieldLabels(labels: Record<string, string>): void;
|
|
48
|
+
/**
|
|
49
|
+
* Replaces the editor's merge tag menu with `tags` (grouped). Safe to call before the editor is
|
|
50
|
+
* ready — the tags are applied once it is. Lets hosts add tags that finish loading after init
|
|
51
|
+
* (e.g. form fields) without remounting the editor.
|
|
52
|
+
*/
|
|
53
|
+
setMergeTags(tags: UnlayerEditorMergeTagInfo[] | undefined): void;
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
export interface UnlayerEditorMergeTagInfo {
|
|
51
57
|
id: string;
|
|
52
58
|
name: string;
|
|
53
59
|
propertyPath: string;
|
|
54
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Submenu the tag is listed under. A string is a single submenu (`'Custom Fields'`);
|
|
62
|
+
* an array nests submenus in order (`['Forms', 'Customer Intake']` → Forms ▸ Customer Intake ▸ tag).
|
|
63
|
+
*/
|
|
64
|
+
group?: string | string[];
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
export interface UnlayerEditorCustomTool {
|
package/src/unlayer.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { emitDisplayCondition } from './display-conditions/displayConditionController';
|
|
2
2
|
import { editorCoreScript, editorCoreStyles, editorCoreTools } from './editor-core';
|
|
3
|
+
import { logUnlayerError } from './log';
|
|
3
4
|
import { toUnlayerMergeTags } from './merge-tags';
|
|
4
5
|
import { constGenericsEditor } from './shared/const';
|
|
5
6
|
import { unlayerSupportedFonts } from './shared/fonts';
|
|
@@ -276,75 +277,94 @@ export const createUnlayerEditor = (
|
|
|
276
277
|
},
|
|
277
278
|
};
|
|
278
279
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
280
|
+
let result: Unlayer;
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
const unlayerApi = (window as any).unlayer;
|
|
284
|
+
|
|
285
|
+
if (!unlayerApi?.createEditor) {
|
|
286
|
+
throw new Error(
|
|
287
|
+
'Unlayer embed is not available. window.unlayer.createEditor is missing.',
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
result = unlayerApi.createEditor({
|
|
292
|
+
displayMode: 'web',
|
|
293
|
+
devices: ['desktop'],
|
|
294
|
+
features: {
|
|
295
|
+
preview: true,
|
|
296
|
+
userUploads: false,
|
|
297
|
+
stockImages: false,
|
|
298
|
+
textEditor: {
|
|
299
|
+
tables: true,
|
|
300
|
+
},
|
|
288
301
|
},
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
enabled:
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
302
|
+
/*
|
|
303
|
+
* Flat only: nested groups here break custom tool registration. UnlayerStore applies
|
|
304
|
+
* the grouped config via setMergeTags once the editor is ready.
|
|
305
|
+
*/
|
|
306
|
+
mergeTags: toUnlayerMergeTags(mergeTags, { groups: false }),
|
|
307
|
+
projectId: 5713,
|
|
308
|
+
version: latest ? undefined : versions.unlayer,
|
|
309
|
+
appearance: {
|
|
310
|
+
theme: 'classic_light',
|
|
311
|
+
},
|
|
312
|
+
tools: {
|
|
313
|
+
'carousel': { enabled: false },
|
|
314
|
+
'button': { enabled: false },
|
|
315
|
+
'html': {
|
|
316
|
+
enabled: enableHTMLEditing,
|
|
317
|
+
properties: {
|
|
318
|
+
html: {
|
|
319
|
+
editor: {
|
|
320
|
+
widgetParams: {
|
|
321
|
+
codeMirrorOptions: {
|
|
322
|
+
readOnly: enableHTMLEditingReadonly,
|
|
323
|
+
},
|
|
307
324
|
},
|
|
308
325
|
},
|
|
309
326
|
},
|
|
310
327
|
},
|
|
311
328
|
},
|
|
329
|
+
'table': {
|
|
330
|
+
enabled: true,
|
|
331
|
+
},
|
|
332
|
+
'menu': { enabled: false },
|
|
333
|
+
'form': { enabled: false },
|
|
334
|
+
...(noCoreTools
|
|
335
|
+
? {
|
|
336
|
+
columns: { enabled: false },
|
|
337
|
+
text: { enabled: false },
|
|
338
|
+
heading: { enabled: false },
|
|
339
|
+
divider: { enabled: false },
|
|
340
|
+
image: { enabled: false },
|
|
341
|
+
}
|
|
342
|
+
: {}),
|
|
343
|
+
...unitsConfig,
|
|
344
|
+
'custom#e-sign': eSignComponentRecipients,
|
|
312
345
|
},
|
|
313
|
-
|
|
314
|
-
|
|
346
|
+
editor: {
|
|
347
|
+
autoSelectOnDrop: true,
|
|
315
348
|
},
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
: {}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
id,
|
|
336
|
-
fonts: {
|
|
337
|
-
showDefaultFonts: false,
|
|
338
|
-
customFonts: unlayerSupportedFonts,
|
|
339
|
-
},
|
|
340
|
-
tabs: {
|
|
341
|
-
content: {},
|
|
342
|
-
body: {},
|
|
343
|
-
blocks: { enabled: false },
|
|
344
|
-
},
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
document.getElementById = currentFind;
|
|
349
|
+
customJS: customScripts,
|
|
350
|
+
customCSS: customStyles,
|
|
351
|
+
id,
|
|
352
|
+
fonts: {
|
|
353
|
+
showDefaultFonts: false,
|
|
354
|
+
customFonts: unlayerSupportedFonts,
|
|
355
|
+
},
|
|
356
|
+
tabs: {
|
|
357
|
+
content: {},
|
|
358
|
+
body: {},
|
|
359
|
+
blocks: { enabled: false },
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
} catch (error: unknown) {
|
|
363
|
+
logUnlayerError('unlayer.createEditor failed', error);
|
|
364
|
+
throw error;
|
|
365
|
+
} finally {
|
|
366
|
+
document.getElementById = currentFind;
|
|
367
|
+
}
|
|
348
368
|
|
|
349
369
|
if (displayConditions) {
|
|
350
370
|
result.registerCallback(
|