@innovastudio/contentbuilder 1.5.47 → 1.5.49
Sign up to get free protection for your applications and to get access to all the features.
package/index.d.ts
CHANGED
@@ -1,28 +1,233 @@
|
|
1
1
|
interface ContentBuilderOptions {
|
2
|
+
page?: string;
|
2
3
|
container?: string;
|
4
|
+
row?: string;
|
5
|
+
cols?: any[];
|
6
|
+
colequal?: any[];
|
7
|
+
colsizes?: any[];
|
8
|
+
imageQuality?: number;
|
9
|
+
elementSelection?: boolean;
|
10
|
+
paste?: string;
|
11
|
+
snippetJSON?: object;
|
12
|
+
screenMode?: string;
|
13
|
+
onPreviewOpen?: () => void;
|
14
|
+
previewURL?: string;
|
15
|
+
onPreviewClose?: () => void;
|
16
|
+
previewStyle?: string;
|
17
|
+
livePreviewOpen?: boolean;
|
18
|
+
livePreviewAlwaysReload?: boolean;
|
19
|
+
livePreviewReloadEvery?: number;
|
20
|
+
scriptPath?: string;
|
21
|
+
plugins?: any[];
|
22
|
+
pluginPath?: string;
|
23
|
+
disableConfig?: boolean;
|
24
|
+
modulePath?: string;
|
25
|
+
assetPath?: string;
|
26
|
+
fontAssetPath?: string;
|
27
|
+
fontPath?: string;
|
3
28
|
snippetModal?: boolean;
|
4
29
|
snippetModalLeft?: boolean;
|
30
|
+
snippetData?: string;
|
31
|
+
snippetUrl?: string;
|
32
|
+
snippetPath?: string;
|
33
|
+
snippetPathReplace?: any[];
|
34
|
+
snippetCategories?: any[];
|
35
|
+
defaultSnippetCategory?: number;
|
36
|
+
snippetHandle?: boolean;
|
37
|
+
sidePanel?: string;
|
38
|
+
snippetList?: string;
|
39
|
+
onRender?: () => void;
|
40
|
+
onContentClick?: () => void;
|
41
|
+
onChange?: () => void;
|
42
|
+
onAdd?: () => void;
|
43
|
+
largerImageHandler?: string;
|
44
|
+
onLargerImageUpload?: () => void;
|
45
|
+
imageHandler?: string;
|
46
|
+
onImageUpload?: () => void;
|
47
|
+
fileHandler?: string;
|
48
|
+
onFileUpload?: () => void;
|
49
|
+
mediaHandler?: string;
|
50
|
+
onMediaUpload?: () => void;
|
51
|
+
videoHandler?: string;
|
52
|
+
onVideoUpload?: () => void;
|
53
|
+
audioHandler?: string;
|
54
|
+
onAudioUpload?: () => void;
|
55
|
+
colors?: any[];
|
56
|
+
builderMode?: string;
|
57
|
+
rowTool?: string;
|
58
|
+
rowcolOutline?: boolean;
|
59
|
+
columnTool?: boolean;
|
60
|
+
outlineMode?: string;
|
61
|
+
toolStyle?: string;
|
62
|
+
outlineStyle?: string;
|
63
|
+
snippetAddTool?: boolean;
|
64
|
+
elementTool?: boolean;
|
65
|
+
elementHighlight?: boolean;
|
66
|
+
columnHtmlEditor?: boolean;
|
67
|
+
rowHtmlEditor?: boolean;
|
68
|
+
htmlSyntaxHighlighting?: boolean;
|
69
|
+
snippetOpen?: boolean;
|
70
|
+
toolbar?: string;
|
71
|
+
toolbarDisplay?: string;
|
72
|
+
shortenHTML?: boolean;
|
73
|
+
imageResizeOnBlock?: boolean;
|
74
|
+
simpleEditingBreakpoint?: string;
|
75
|
+
resizeHeight?: boolean;
|
76
|
+
snippetsSidebarDisplay?: string;
|
77
|
+
snippetDisplay?: string;
|
78
|
+
onImageSelectClick?: () => void;
|
79
|
+
onFileSelectClick?: () => void;
|
80
|
+
onVideoSelectClick?: () => void;
|
81
|
+
onAudioSelectClick?: () => void;
|
82
|
+
onMediaSelectClick?: () => void;
|
83
|
+
onPluginsLoaded?: () => void;
|
84
|
+
onImageBrowseClick?: () => void;
|
85
|
+
onImageSettingClick?: () => void;
|
86
|
+
onImageEditClick?: () => void;
|
87
|
+
setCropperConfig?: () => void;
|
88
|
+
imageEmbed?: boolean;
|
89
|
+
imageselect?: string;
|
90
|
+
fileselect?: string;
|
91
|
+
videoselect?: string;
|
92
|
+
imageSelect?: string;
|
93
|
+
fileSelect?: string;
|
94
|
+
videoSelect?: string;
|
95
|
+
audioSelect?: string;
|
96
|
+
mediaSelect?: string;
|
97
|
+
selectIcon?: string;
|
98
|
+
otherSelect?: string;
|
99
|
+
otherSelectCaption?: string;
|
100
|
+
otherSelectIcon?: string;
|
101
|
+
imageSelectWidth?: string;
|
102
|
+
imageSelectHeight?: string;
|
103
|
+
fileSelectWidth?: string;
|
104
|
+
fileSelectHeight?: string;
|
105
|
+
videoSelectWidth?: string;
|
106
|
+
videoSelectHeight?: string;
|
107
|
+
audioSelectWidth?: string;
|
108
|
+
audioSelectHeight?: string;
|
109
|
+
mediaSelectWidth?: string;
|
110
|
+
mediaSelectHeight?: string;
|
111
|
+
otherSelectWidth?: string;
|
112
|
+
otherSelectHeight?: string;
|
113
|
+
imageSelectMaxWidth?: string;
|
114
|
+
fileSelectMaxWidth?: string;
|
115
|
+
videoSelectMaxWidth?: string;
|
116
|
+
audioSelectMaxWidth?: string;
|
117
|
+
mediaSelectMaxWidth?: string;
|
118
|
+
otherSelectMaxWidth?: string;
|
119
|
+
assetPanelFullScreen?: boolean;
|
120
|
+
codeEditorWidth?: string;
|
121
|
+
codeEditorHeight?: string;
|
122
|
+
codeEditorMaxWidth?: string;
|
123
|
+
blockCodeEditorWidth?: string;
|
124
|
+
blockCodeEditorHeight?: string;
|
125
|
+
blockCodeEditorMaxWidth?: string;
|
126
|
+
assetRefresh?: boolean;
|
127
|
+
customTags?: any[];
|
128
|
+
buttons?: any[];
|
129
|
+
buttonsMore?: any[];
|
130
|
+
elementButtons?: any[];
|
131
|
+
elementButtonsMore?: any[];
|
132
|
+
iconButtons?: any[];
|
133
|
+
iconButtonsMore?: any[];
|
134
|
+
lang?: any[];
|
135
|
+
checkLang?: boolean;
|
136
|
+
clearPreferences?: boolean;
|
137
|
+
toolbarAddSnippetButton?: boolean;
|
138
|
+
animateModal?: boolean;
|
139
|
+
defaultFontSizes?: any[];
|
140
|
+
fontSizeClassValues?: any[];
|
141
|
+
gradientcolors?: any[];
|
142
|
+
elementEditor?: boolean;
|
143
|
+
customval?: string;
|
144
|
+
moduleConfig?: any[];
|
145
|
+
elementAnimate?: boolean;
|
146
|
+
cleanAOS?: boolean;
|
147
|
+
framework?: string;
|
148
|
+
cellFormat?: string;
|
149
|
+
rowFormat?: string;
|
150
|
+
emailMode?: boolean;
|
151
|
+
absolutePath?: boolean;
|
152
|
+
emailSnippetCategories?: any[];
|
153
|
+
defaultEmailSnippetCategory?: number;
|
154
|
+
undoRedoStyles?: boolean;
|
155
|
+
specialElementClasses?: any[];
|
156
|
+
onUndo?: () => void;
|
157
|
+
onRedo?: () => void;
|
158
|
+
onBlockCanvasAdd?: () => void;
|
159
|
+
docContainer?: string;
|
160
|
+
blockContainer?: string;
|
161
|
+
pageSize?: string;
|
162
|
+
pageSizes?: any[];
|
163
|
+
maxEmbedImageWidth?: number;
|
164
|
+
zoom?: number;
|
165
|
+
useLightbox?: boolean;
|
166
|
+
lightboxArrow?: boolean;
|
167
|
+
imageRenameOnEdit?: boolean;
|
168
|
+
disableAutoEmbedVideo?: boolean;
|
169
|
+
deleteConfirm?: boolean;
|
170
|
+
disableBootstrapIcons?: boolean;
|
171
|
+
sectionTemplate?: string;
|
172
|
+
onZoomStart?: () => void;
|
173
|
+
onZoom?: () => void;
|
174
|
+
onZoomEnd?: () => void;
|
175
|
+
themes?: any[];
|
176
|
+
colHeight?: any[];
|
177
|
+
maxColumns?: number;
|
178
|
+
leadingPreset?: any[];
|
179
|
+
cssClasses?: object;
|
180
|
+
useCssClasses?: boolean;
|
181
|
+
useButtonPlugin?: boolean;
|
182
|
+
enableDragResize?: boolean;
|
183
|
+
simpleTextSettings?: boolean;
|
184
|
+
enableColumnsPerLine?: boolean;
|
185
|
+
startAIAssistant?: boolean;
|
186
|
+
isContentBox?: boolean;
|
187
|
+
sendCommandUrl?: string;
|
188
|
+
speechTranscribeUrl?: string;
|
189
|
+
onlineDemo?: boolean;
|
190
|
+
autoSendDelay?: number;
|
191
|
+
autoEditBlock?: boolean;
|
192
|
+
disclaimerAI?: string;
|
193
|
+
showDisclaimer?: boolean;
|
194
|
+
AIModalStyle?: string;
|
195
|
+
enableShortCommands?: boolean;
|
196
|
+
speechRecognitionLang?: string;
|
197
|
+
assistantMode?: string;
|
198
|
+
triggerWords?: object;
|
199
|
+
temperature?: number;
|
200
|
+
topP?: number;
|
201
|
+
useMediaRecorder?: boolean;
|
202
|
+
encoderPath?: string;
|
203
|
+
imageAutoUpscale?: boolean;
|
204
|
+
headlineList?: any[];
|
205
|
+
mediaPath?: string;
|
206
|
+
media?: object;
|
207
|
+
shortCommandList?: object;
|
208
|
+
similarityThreshold?: number;
|
209
|
+
commandList?: object;
|
5
210
|
}
|
6
211
|
|
7
212
|
declare class ContentBuilder {
|
8
213
|
constructor(options?: ContentBuilderOptions);
|
9
214
|
|
10
|
-
html(element
|
11
|
-
loadSnippets(snippetFile: string, snippetOpen
|
215
|
+
html(element?: HTMLElement): void;
|
216
|
+
loadSnippets(snippetFile: string, snippetOpen?: boolean): void;
|
12
217
|
viewSnippets(): void;
|
13
|
-
saveImages(handler
|
218
|
+
saveImages(handler?: string, onComplete?: () => void, onBase64Upload?: () => void): void;
|
14
219
|
applyBehavior(): void;
|
15
220
|
applyBehaviorOn(element: HTMLElement): void;
|
16
221
|
viewConfig(): void;
|
17
|
-
setUIColor(mode: string, csslink
|
222
|
+
setUIColor(mode: string, csslink?: string): void;
|
18
223
|
viewHtml(): void;
|
19
|
-
loadHtml(html: string, area
|
20
|
-
pasteHtmlAtCaret(html: string, selectPastedContent
|
21
|
-
|
224
|
+
loadHtml(html: string, area?: HTMLElement): void;
|
225
|
+
pasteHtmlAtCaret(html: string, selectPastedContent?: boolean): void;
|
226
|
+
addSnippet(html: string, bSnippet?: boolean, noedit?: boolean): void;
|
22
227
|
undo(): void;
|
23
228
|
redo(): void;
|
24
229
|
destroy(): void;
|
25
|
-
returnUrl(
|
230
|
+
returnUrl(s: string): void;
|
26
231
|
toggleSnippetModal(): void;
|
27
232
|
openSnippetModal(): void;
|
28
233
|
closeSnippetModal(): void;
|
@@ -30,10 +235,10 @@ declare class ContentBuilder {
|
|
30
235
|
openAIAssistant(): void;
|
31
236
|
closeAIAssistant(): void;
|
32
237
|
saveForUndo(): void;
|
33
|
-
selectAsset(s: string, f
|
34
|
-
addBlock(html: string, blockContainer
|
35
|
-
addPage(box
|
36
|
-
setPageSize(s
|
238
|
+
selectAsset(s: string, f?: boolean)
|
239
|
+
addBlock(html: string, blockContainer?: HTMLElement)
|
240
|
+
addPage(box?: HTMLElement)
|
241
|
+
setPageSize(s?: string)
|
37
242
|
openPageOptions(): void;
|
38
243
|
print(): void;
|
39
244
|
}
|
package/package.json
CHANGED
@@ -3711,6 +3711,24 @@ class Dom {
|
|
3711
3711
|
constructor(builder) {
|
3712
3712
|
this.builder = builder;
|
3713
3713
|
}
|
3714
|
+
detectMobileOrTablet() {
|
3715
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
3716
|
+
const isIOS = /ipad|iphone|ipod/.test(userAgent) && !window.MSStream;
|
3717
|
+
const isAndroid = /android/.test(userAgent);
|
3718
|
+
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
|
3719
|
+
const screenWidth = window.innerWidth <= 1600;
|
3720
|
+
if (isIOS || isAndroid) {
|
3721
|
+
return true; // Definitely a mobile or tablet
|
3722
|
+
}
|
3723
|
+
|
3724
|
+
// Additional check for other touch devices with screen width under 1600px
|
3725
|
+
if (isTouchDevice && screenWidth) {
|
3726
|
+
return true; // Likely a mobile or tablet
|
3727
|
+
}
|
3728
|
+
|
3729
|
+
return false; // Likely not a mobile or tablet
|
3730
|
+
}
|
3731
|
+
|
3714
3732
|
getScale(container) {
|
3715
3733
|
let matrix = window.getComputedStyle(container).transform;
|
3716
3734
|
if (matrix === 'none') return 1;
|
@@ -17223,7 +17241,19 @@ const renderSnippetPanel = (builder, snippetOpen) => {
|
|
17223
17241
|
|
17224
17242
|
let activeBuilderArea;
|
17225
17243
|
let itemHeight;
|
17226
|
-
|
17244
|
+
const isMobile = dom.detectMobileOrTablet();
|
17245
|
+
let useClick = false;
|
17246
|
+
if (isMobile && builder.isContentBox) {
|
17247
|
+
const items = snippetlist.querySelectorAll('.snippet-item');
|
17248
|
+
items.forEach(item => {
|
17249
|
+
item.addEventListener('click', () => {
|
17250
|
+
const snippetid = item.getAttribute('data-id');
|
17251
|
+
builder.dropSnippet(snippetid);
|
17252
|
+
});
|
17253
|
+
});
|
17254
|
+
useClick = true;
|
17255
|
+
}
|
17256
|
+
if (!useClick) new Sortable(snippetlist, {
|
17227
17257
|
// forceFallback: safariAgent,
|
17228
17258
|
group: {
|
17229
17259
|
name: 'shared',
|
@@ -66679,6 +66709,7 @@ class Rte {
|
|
66679
66709
|
btnFront.forEach(btn => {
|
66680
66710
|
btn.addEventListener('click', () => {
|
66681
66711
|
let activeBlock = this.builder.doc.querySelector('.is-block.cloned');
|
66712
|
+
if (!activeBlock) activeBlock = this.builder.doc.querySelector('.is-block.active');
|
66682
66713
|
if (!activeBlock) return;
|
66683
66714
|
this.builder.forward(activeBlock);
|
66684
66715
|
});
|
@@ -66687,6 +66718,7 @@ class Rte {
|
|
66687
66718
|
btnBackward.forEach(btn => {
|
66688
66719
|
btn.addEventListener('click', () => {
|
66689
66720
|
let activeBlock = this.builder.doc.querySelector('.is-block.cloned');
|
66721
|
+
if (!activeBlock) activeBlock = this.builder.doc.querySelector('.is-block.active');
|
66690
66722
|
if (!activeBlock) return;
|
66691
66723
|
if (activeBlock.style.zIndex === '0') {
|
66692
66724
|
this.builder.moveUp(activeBlock);
|
@@ -66714,6 +66746,7 @@ class Rte {
|
|
66714
66746
|
btnDuplicate.forEach(btn => {
|
66715
66747
|
btn.addEventListener('click', () => {
|
66716
66748
|
let activeBlock = this.builder.doc.querySelector('.is-block.cloned');
|
66749
|
+
if (!activeBlock) activeBlock = this.builder.doc.querySelector('.is-block.active');
|
66717
66750
|
if (!activeBlock) return;
|
66718
66751
|
this.builder.duplicate(activeBlock);
|
66719
66752
|
});
|
@@ -83995,7 +84028,8 @@ class EditableBlocks {
|
|
83995
84028
|
}
|
83996
84029
|
if (block.classList.contains('is-group')) return; // do not clone if block is shape
|
83997
84030
|
|
83998
|
-
|
84031
|
+
const isMobileOrTablet = this.detectMobileOrTablet();
|
84032
|
+
if (!block.classList.contains('clone') & !isMobileOrTablet) {
|
83999
84033
|
let clonedDiv = block.cloneNode(true);
|
84000
84034
|
clonedDiv.classList.add('clone');
|
84001
84035
|
block.parentNode.appendChild(clonedDiv);
|
@@ -84003,6 +84037,24 @@ class EditableBlocks {
|
|
84003
84037
|
this.refresh();
|
84004
84038
|
}
|
84005
84039
|
}
|
84040
|
+
detectMobileOrTablet() {
|
84041
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
84042
|
+
const isIOS = /ipad|iphone|ipod/.test(userAgent) && !window.MSStream;
|
84043
|
+
const isAndroid = /android/.test(userAgent);
|
84044
|
+
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
|
84045
|
+
const screenWidth = window.innerWidth <= 1600;
|
84046
|
+
if (isIOS || isAndroid) {
|
84047
|
+
return true; // Definitely a mobile or tablet
|
84048
|
+
}
|
84049
|
+
|
84050
|
+
// Additional check for other touch devices with screen width under 1600px
|
84051
|
+
if (isTouchDevice && screenWidth) {
|
84052
|
+
return true; // Likely a mobile or tablet
|
84053
|
+
}
|
84054
|
+
|
84055
|
+
return false; // Likely not a mobile or tablet
|
84056
|
+
}
|
84057
|
+
|
84006
84058
|
selectClear() {
|
84007
84059
|
this.doc.querySelectorAll('.clone').forEach(elm => elm.parentNode.removeChild(elm));
|
84008
84060
|
this.doc.querySelectorAll('.cloned').forEach(elm => elm.classList.remove('cloned'));
|
@@ -92316,6 +92368,203 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
|
|
92316
92368
|
// return currentScript.replace(currentScriptFile, '');
|
92317
92369
|
}
|
92318
92370
|
|
92371
|
+
dropSnippet(snippetid) {
|
92372
|
+
// snippetJSON is snippet's JSON (from assets/minimalist-blocks/content.js) that store all snippets' html
|
92373
|
+
const result = this.opts.snippetJSON.snippets.filter(item => {
|
92374
|
+
if (item.id + '' === snippetid) return item;else return false;
|
92375
|
+
});
|
92376
|
+
let html = result[0].html;
|
92377
|
+
let noedit = result[0].noedit;
|
92378
|
+
let bSnippet;
|
92379
|
+
if (html.indexOf('"row') === -1) {
|
92380
|
+
bSnippet = true; // Just snippet (without row/column grid)
|
92381
|
+
} else {
|
92382
|
+
bSnippet = false; // Snippet is wrapped in row/colum
|
92383
|
+
}
|
92384
|
+
|
92385
|
+
if (this.opts.emailMode) bSnippet = false;
|
92386
|
+
|
92387
|
+
// check if is block
|
92388
|
+
let isBlock = false;
|
92389
|
+
if (html.includes('"is-block')) {
|
92390
|
+
isBlock = true;
|
92391
|
+
bSnippet = false;
|
92392
|
+
}
|
92393
|
+
|
92394
|
+
// Convert snippet into your defined 12 columns grid
|
92395
|
+
let rowClass = this.opts.row; //row
|
92396
|
+
let colClass = this.opts.cols; //['col s1', 'col s2', 'col s3', 'col s4', 'col s5', 'col s6', 'col s7', 'col s8', 'col s9', 'col s10', 'col s11', 'col s12']
|
92397
|
+
if (rowClass !== '' && colClass.length === 12) {
|
92398
|
+
// html = html.replace(new RegExp('row clearfix', 'g'), rowClass);
|
92399
|
+
html = html.replace(new RegExp('row clearfix', 'g'), 'row'); // backward
|
92400
|
+
html = html.replace(new RegExp('"row', 'g'), '"' + rowClass);
|
92401
|
+
html = html.replace(new RegExp('column full', 'g'), colClass[11]);
|
92402
|
+
html = html.replace(new RegExp('column half', 'g'), colClass[5]);
|
92403
|
+
html = html.replace(new RegExp('column third', 'g'), colClass[3]);
|
92404
|
+
html = html.replace(new RegExp('column fourth', 'g'), colClass[2]);
|
92405
|
+
html = html.replace(new RegExp('column fifth', 'g'), colClass[1]);
|
92406
|
+
html = html.replace(new RegExp('column sixth', 'g'), colClass[1]);
|
92407
|
+
html = html.replace(new RegExp('column two-third', 'g'), colClass[7]);
|
92408
|
+
html = html.replace(new RegExp('column two-fourth', 'g'), colClass[8]);
|
92409
|
+
html = html.replace(new RegExp('column two-fifth', 'g'), colClass[9]);
|
92410
|
+
html = html.replace(new RegExp('column two-sixth', 'g'), colClass[9]);
|
92411
|
+
}
|
92412
|
+
html = html.replace(/{id}/g, this.util.makeId());
|
92413
|
+
if (this.opts.onAdd) {
|
92414
|
+
html = this.opts.onAdd(html);
|
92415
|
+
}
|
92416
|
+
if (this.opts.snippetPathReplace.length > 0) {
|
92417
|
+
// try {
|
92418
|
+
if (this.opts.snippetPathReplace[0] !== '') {
|
92419
|
+
let regex = new RegExp(this.opts.snippetPathReplace[0], 'g');
|
92420
|
+
html = html.replace(regex, this.opts.snippetPathReplace[1]);
|
92421
|
+
let string1 = this.opts.snippetPathReplace[0].replace(/\//g, '%2F');
|
92422
|
+
let string2 = this.opts.snippetPathReplace[1].replace(/\//g, '%2F');
|
92423
|
+
let regex2 = new RegExp(string1, 'g');
|
92424
|
+
html = html.replace(regex2, string2);
|
92425
|
+
}
|
92426
|
+
// } catch (e) { 1; }
|
92427
|
+
}
|
92428
|
+
|
92429
|
+
// this.addSnippet(html, bSnippet, noedit);
|
92430
|
+
|
92431
|
+
if (bSnippet) {
|
92432
|
+
// Just snippet (without row/column grid), ex. buttons, line, social, video, map.
|
92433
|
+
// Can be inserted after current row, column (cell), element, or last row.
|
92434
|
+
|
92435
|
+
html = `<div class="${this.opts.row}"><div class="${this.opts.cols[this.opts.cols.length - 1]}"${noedit ? ' data-noedit' : ''}>${html}</div></div>`;
|
92436
|
+
} else if (isBlock) ; else {
|
92437
|
+
// Snippet is wrapped in row/colum (may contain custom code or has [data-html] attribute)
|
92438
|
+
// Can only be inserted after current row or last row (not on column or element).
|
92439
|
+
|
92440
|
+
let snippet = this.dom.createElement('div');
|
92441
|
+
snippet.innerHTML = html;
|
92442
|
+
let blocks = snippet.querySelectorAll('[data-html]');
|
92443
|
+
Array.prototype.forEach.call(blocks, block => {
|
92444
|
+
// Render custom code block
|
92445
|
+
html = decodeURIComponent(block.getAttribute('data-html'));
|
92446
|
+
html = html.replace(/{id}/g, this.util.makeId());
|
92447
|
+
html = html.replace(/<script>/g, `${this.nonce ? `<script nonce="${this.nonce}">` : '<script>'}`);
|
92448
|
+
for (var i = 1; i <= 20; i++) {
|
92449
|
+
html = html.replace('[%HTML' + i + '%]', block.getAttribute('data-html-' + i) === undefined ? '' : decodeURIComponent(block.getAttribute('data-html-' + i))); //render editable area
|
92450
|
+
}
|
92451
|
+
|
92452
|
+
block.innerHTML = html;
|
92453
|
+
});
|
92454
|
+
html = snippet.innerHTML;
|
92455
|
+
}
|
92456
|
+
const activeBox = this.doc.querySelector('.box-select');
|
92457
|
+
const activeRow = this.doc.querySelector('.row-active');
|
92458
|
+
if (activeRow) {
|
92459
|
+
this.addRow(html, activeBox);
|
92460
|
+
} else {
|
92461
|
+
if (activeBox) {
|
92462
|
+
if (activeBox.classList.contains('box-canvas')) {
|
92463
|
+
// Canvas Mode
|
92464
|
+
|
92465
|
+
let snippet = this.dom.createElement('div');
|
92466
|
+
snippet.innerHTML = html;
|
92467
|
+
let blocks = snippet.querySelectorAll('[data-html]');
|
92468
|
+
Array.prototype.forEach.call(blocks, block => {
|
92469
|
+
// Render custom code block
|
92470
|
+
html = decodeURIComponent(block.getAttribute('data-html'));
|
92471
|
+
html = html.replace(/{id}/g, this.util.makeId());
|
92472
|
+
html = html.replace(/<script>/g, `${this.nonce ? `<script nonce="${this.nonce}">` : '<script>'}`);
|
92473
|
+
for (var i = 1; i <= 20; i++) {
|
92474
|
+
html = html.replace('[%HTML' + i + '%]', block.getAttribute('data-html-' + i) === undefined ? '' : decodeURIComponent(block.getAttribute('data-html-' + i))); //render editable area
|
92475
|
+
}
|
92476
|
+
|
92477
|
+
block.innerHTML = html;
|
92478
|
+
});
|
92479
|
+
html = snippet.innerHTML;
|
92480
|
+
const blockTemplate = `
|
92481
|
+
<div class="is-block block-steady height-auto" data-new-dummy="1" style="top: 20%; left: 20%; width: 760px;">
|
92482
|
+
<div class="is-container container-new size-18 leading-14">
|
92483
|
+
[%CONTENT%]
|
92484
|
+
</div>
|
92485
|
+
</div>
|
92486
|
+
`; // data-new-dummy will be used by onSort to apply top/left position (snippetpanel.js)
|
92487
|
+
// html = blockTemplate.replace('[%CONTENT%]', html);
|
92488
|
+
|
92489
|
+
this.uo.saveForUndo();
|
92490
|
+
this.eb.addBlock(blockTemplate, activeBox);
|
92491
|
+
const builders = activeBox.querySelectorAll('.is-container.container-new');
|
92492
|
+
builders.forEach(builder => {
|
92493
|
+
// After snippet has been added, re-apply behavior on builder areas
|
92494
|
+
|
92495
|
+
var range = document.createRange();
|
92496
|
+
range.setStart(builder, 0);
|
92497
|
+
builder.appendChild(range.createContextualFragment(html));
|
92498
|
+
this.applyBehaviorOn(builder);
|
92499
|
+
builder.classList.remove('container-new');
|
92500
|
+
});
|
92501
|
+
this.opts.onChange();
|
92502
|
+
this.opts.onRender();
|
92503
|
+
if (this.opts.onBlockCanvasAdd) this.opts.onBlockCanvasAdd();
|
92504
|
+
} else {
|
92505
|
+
let container = activeBox.querySelector('.builder-active');
|
92506
|
+
if (container) {
|
92507
|
+
this.addRow(html, activeBox);
|
92508
|
+
} else {
|
92509
|
+
container = activeBox.querySelector('.is-container');
|
92510
|
+
if (container) {
|
92511
|
+
this.addRow(html, activeBox);
|
92512
|
+
}
|
92513
|
+
}
|
92514
|
+
}
|
92515
|
+
}
|
92516
|
+
}
|
92517
|
+
this.activeCol = null;
|
92518
|
+
}
|
92519
|
+
addRow(html, box) {
|
92520
|
+
this.uo.saveForUndo();
|
92521
|
+
let rowElement;
|
92522
|
+
let bAddLast = false;
|
92523
|
+
|
92524
|
+
// Add after selected row
|
92525
|
+
let cell = this.activeCol;
|
92526
|
+
let row;
|
92527
|
+
if (cell) {
|
92528
|
+
row = cell.parentNode; // in email mode, cell active is also under row active (incorrect, but cell active is not needed in email mode. So this line works!)
|
92529
|
+
} else {
|
92530
|
+
// If no active cell, check if it is from .row-add-initial (empty info)
|
92531
|
+
row = this.doc.querySelector('.row-active');
|
92532
|
+
if (!row) {
|
92533
|
+
bAddLast = true;
|
92534
|
+
}
|
92535
|
+
}
|
92536
|
+
// Add after last row
|
92537
|
+
if (bAddLast) {
|
92538
|
+
const container = box.querySelector('.is-builder');
|
92539
|
+
const rows = this.dom.elementChildren(container);
|
92540
|
+
const lastrow = rows[rows.length - 1];
|
92541
|
+
row = lastrow;
|
92542
|
+
}
|
92543
|
+
|
92544
|
+
// Use createContextualFragment() to make embedded script executable
|
92545
|
+
let range = document.createRange();
|
92546
|
+
row.parentNode.insertBefore(range.createContextualFragment(html), row.nextSibling);
|
92547
|
+
// rowElement = snippet.childNodes[0];
|
92548
|
+
|
92549
|
+
rowElement = row.nextElementSibling; // a must. Must be before applyBehavior to prevent element delete during fixLayout
|
92550
|
+
|
92551
|
+
// checkEmpty & onRender called here
|
92552
|
+
let builderActive = box.querySelector('.builder-active');
|
92553
|
+
if (builderActive) this.applyBehaviorOn(builderActive);else {
|
92554
|
+
builderActive = box.querySelector('.is-builder');
|
92555
|
+
this.applyBehaviorOn(builderActive);
|
92556
|
+
}
|
92557
|
+
let cellElement = rowElement.querySelector('div');
|
92558
|
+
if (cellElement) cellElement.click(); //change active block to the newly created
|
92559
|
+
|
92560
|
+
// Change to row selection
|
92561
|
+
rowElement.className = rowElement.className.replace('row-outline', '');
|
92562
|
+
|
92563
|
+
//Hide Column tool (new!)
|
92564
|
+
this.util.hideColumnTool();
|
92565
|
+
this.opts.onChange();
|
92566
|
+
this.opts.onRender();
|
92567
|
+
}
|
92319
92568
|
sectionDropSetup() {
|
92320
92569
|
if (this.blockContainer) {
|
92321
92570
|
this.sortableOnCanvas = [];
|