@innovastudio/contentbuilder 1.5.47 → 1.5.49
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/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 = [];
|