@innovastudio/contentbuilder 1.5.13 → 1.5.16

Sign up to get free protection for your applications and to get access to all the features.
@@ -11527,7 +11527,7 @@ class HtmlUtil {
11527
11527
  elm.removeAttribute('grideditor');
11528
11528
  elm.removeAttribute('gridoutline');
11529
11529
  });
11530
- elms = tmp.querySelectorAll('.is-row-tool,.is-col-tool,.is-rowadd-tool,.is-canvas-tool,.is-canvasadd-tool');
11530
+ elms = tmp.querySelectorAll('.is-row-tool,.is-col-tool,.is-rowadd-tool,.is-canvas-tool,.is-canvasadd-tool,.h-ruler,.v-ruler');
11531
11531
  elms.forEach(elm => {
11532
11532
  if (elm.previousSibling && elm.previousSibling.nodeType === Node.TEXT_NODE) {
11533
11533
  elm.previousSibling.remove();
@@ -11904,6 +11904,8 @@ class UndoRedo {
11904
11904
  dom.removeElements(tmp.querySelectorAll('.is-canvasadd-tool'));
11905
11905
  dom.removeElements(tmp.querySelectorAll('.ovl'));
11906
11906
  dom.removeElements(tmp.querySelectorAll('.row-add-initial'));
11907
+ dom.removeElements(tmp.querySelectorAll('.h-ruler'));
11908
+ dom.removeElements(tmp.querySelectorAll('.v-ruler'));
11907
11909
 
11908
11910
  // freeform
11909
11911
  elms = tmp.querySelectorAll('.is-block .handle, .is-block .rotate-handle');
@@ -12562,11 +12564,11 @@ const prepareSvgIcons = builder => {
12562
12564
  <path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 16.572v2.42a2.01 2.01 0 0 1 -2.009 2.008h-7.981a2.01 2.01 0 0 1 -2.01 -2.009v-7.981a2.01 2.01 0 0 1 2.009 -2.01h2.954" /><path d="M9.167 4.511a2.04 2.04 0 0 1 2.496 -1.441l7.826 2.097a2.04 2.04 0 0 1 1.441 2.496l-2.097 7.826a2.04 2.04 0 0 1 -2.496 1.441l-7.827 -2.097a2.04 2.04 0 0 1 -1.441 -2.496l2.098 -7.827z" />
12563
12565
  </symbol>
12564
12566
 
12565
- <symbol id="icon-duplicate" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
12567
+ <symbol id="icon-duplicate2" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
12566
12568
  <path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 16.572v2.42a2.01 2.01 0 0 1 -2.009 2.008h-7.981a2.01 2.01 0 0 1 -2.01 -2.009v-7.981a2.01 2.01 0 0 1 2.009 -2.01h2.954" /><path d="M9.167 4.511a2.04 2.04 0 0 1 2.496 -1.441l7.826 2.097a2.04 2.04 0 0 1 1.441 2.496l-2.097 7.826a2.04 2.04 0 0 1 -2.496 1.441l-7.827 -2.097a2.04 2.04 0 0 1 -1.441 -2.496l2.098 -7.827z" />
12567
12569
  </symbol>
12568
- <symbol id="icon-duplicate2" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
12569
- <path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z" /><path d="M17 17v2a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h2" />
12570
+ <symbol id="icon-duplicate" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
12571
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 7m0 2.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z" /><path d="M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1" />
12570
12572
  </symbol>
12571
12573
 
12572
12574
  <symbol id="icon-trash" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -12617,7 +12619,7 @@ const prepareSvgIcons = builder => {
12617
12619
  </symbol>
12618
12620
 
12619
12621
  <symbol id="icon-pagesize" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
12620
- <path d="M3 5m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" /><path d="M7 12v-3h3" /><path d="M17 12v3h-3" />
12622
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6 4h11a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-11a1 1 0 0 1 -1 -1v-14a1 1 0 0 1 1 -1m3 0v18" /><path d="M13 8l2 0" /><path d="M13 12l2 0" />
12621
12623
  </symbol>
12622
12624
  <symbol id="icon-print" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
12623
12625
  <path d="M17 17h2a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-14a2 2 0 0 0 -2 2v4a2 2 0 0 0 2 2h2" /><path d="M17 9v-4a2 2 0 0 0 -2 -2h-6a2 2 0 0 0 -2 2v4" /><path d="M7 13m0 2a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v4a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2z" />
@@ -64487,7 +64489,7 @@ class Rte {
64487
64489
  var btn = builder.opts.buttonsMore[j].toLowerCase();
64488
64490
  if (btn === 'createlink') html_rtemore += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;else if (btn === 'icon' && !this.builder.opts.emailMode) html_rtemore += `<button tabindex="-1" title="${util.out('Icon')}" class="rte-icon"><svg class="is-icon-flex" style="width:14px;height:14px;margin-top:2px;"><use xlink:href="#ion-android-happy"></use></svg></button>`;else if (btn === 'svg' && !this.builder.opts.emailMode) html_rtemore += `<button tabindex="-1" title="${util.out('SVG')}" class="rte-svg"><svg class="is-icon-flex" style="width:19px;height:19px;margin-top:2px;"><use xlink:href="#icon-svg"></use></svg></button>`;else if (btn === 'removeformat') html_rtemore += `<button tabindex="-1" title="${util.out('Clean')}" class="rte-clean"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#icon-clean"></use></svg></button>`;else if (btn === 'bold') html_rtemore += `<button tabindex="-1" title="${util.out('Bold')}" class="rte-format" data-command="bold"><span style="font-family:serif;font-size:14px;">B</span></button>`;else if (btn === 'italic') html_rtemore += `<button tabindex="-1" title="${util.out('Italic')}" class="rte-format" data-command="italic"><span style="font-family:serif;font-size:16px;font-style:italic;">i</span></button>`;else if (btn === 'underline') html_rtemore += `<button tabindex="-1" title="${util.out('Underline')}" class="rte-format" data-command="underline"><span style="font-family:serif;font-size:14px;text-decoration:underline;">U</span></button>`;
64489
64491
  // else if(btn==='createlink') html_rtemore += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;
64490
- else if (btn === 'align') html_rtemore += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'list') html_rtemore += `<button tabindex="-1" title="${util.out('List')}" class="rte-list"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#icon-list-bullet"></use></svg></button>`;else if (btn === 'color') html_rtemore += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'formatting') html_rtemore += `<button tabindex="-1" title="${util.out('Formatting')}" class="rte-formatting"><span style="font-family:serif;font-size:15px;display:inline-block;">A</span></button>`;else if (btn === 'tags') html_rtemore += customtag_button;else if (btn === 'image') html_rtemore += `<button tabindex="-1" title="${util.out('Image')}" class="rte-image"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-image"></use></svg></button>`;else if (btn === 'gridtool') html_rtemore += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_rtemore += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_rtemore += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_rtemore += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'formatpara') html_rtemore += `<button tabindex="-1" title="${util.out('Paragraph')}" class="rte-paragraph"><span style="font-family:serif;font-size:14px;display:inline-block;margin-top:2px;">H</span></button>`;else if (btn === 'font') html_rtemore += `<button tabindex="-1" title="${util.out('Font')}" class="rte-fontfamily"><span style="font-family:serif;font-size:18px;text-transform:none;display:inline-block;margin-top: -3px;">a</span></button>`;else if (btn === 'textsettings') html_rtemore += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'undo') html_rtemore += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_rtemore += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_rtemore += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_rtemore += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_rtemore += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;transform:rotate(90deg)"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_rtemore += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_rtemore += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_rtemore += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64492
+ else if (btn === 'align') html_rtemore += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'list') html_rtemore += `<button tabindex="-1" title="${util.out('List')}" class="rte-list"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#icon-list-bullet"></use></svg></button>`;else if (btn === 'color') html_rtemore += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'formatting') html_rtemore += `<button tabindex="-1" title="${util.out('Formatting')}" class="rte-formatting"><span style="font-family:serif;font-size:15px;display:inline-block;">A</span></button>`;else if (btn === 'tags') html_rtemore += customtag_button;else if (btn === 'image') html_rtemore += `<button tabindex="-1" title="${util.out('Image')}" class="rte-image"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-image"></use></svg></button>`;else if (btn === 'gridtool') html_rtemore += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_rtemore += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_rtemore += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_rtemore += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'formatpara') html_rtemore += `<button tabindex="-1" title="${util.out('Paragraph')}" class="rte-paragraph"><span style="font-family:serif;font-size:14px;display:inline-block;margin-top:2px;">H</span></button>`;else if (btn === 'font') html_rtemore += `<button tabindex="-1" title="${util.out('Font')}" class="rte-fontfamily"><span style="font-family:serif;font-size:18px;text-transform:none;display:inline-block;margin-top: -3px;">a</span></button>`;else if (btn === 'textsettings') html_rtemore += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'undo') html_rtemore += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_rtemore += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_rtemore += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_rtemore += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_rtemore += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_rtemore += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_rtemore += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:1px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_rtemore += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64491
64493
  html_rtemore += '<div class="rte-separator"></div>';
64492
64494
  } else {
64493
64495
  html_rtemore += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -64497,7 +64499,7 @@ class Rte {
64497
64499
  let html_rte = '';
64498
64500
  for (j = 0; j < builder.opts.buttons.length; j++) {
64499
64501
  btn = builder.opts.buttons[j].toLowerCase();
64500
- if (btn === 'bold') html_rte += `<button tabindex="-1" title="${util.out('Bold')}" class="rte-format" data-command="bold"><span style="font-family:serif;font-size:14px;">B</span></button>`;else if (btn === 'italic') html_rte += `<button tabindex="-1" title="${util.out('Italic')}" class="rte-format" data-command="italic"><span style="font-family:serif;font-size:16px;font-style:italic;">i</span></button>`;else if (btn === 'underline') html_rte += `<button tabindex="-1" title="${util.out('Underline')}" class="rte-format" data-command="underline"><span style="font-family:serif;font-size:14px;text-decoration:underline;">U</span></button>`;else if (btn === 'createlink') html_rte += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;else if (btn === 'align') html_rte += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'formatpara') html_rte += `<button tabindex="-1" title="${util.out('Paragraph')}" class="rte-paragraph"><span style="font-family:serif;font-size:14px;display:inline-block;margin-top:2px;">H</span></button>`;else if (btn === 'color') html_rte += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'formatting') html_rte += `<button tabindex="-1" title="${util.out('Formatting')}" class="rte-formatting"><span style="font-family:serif;font-size:15px;display:inline-block;">A</span></button>`;else if (btn === 'list') html_rte += `<button tabindex="-1" title="${util.out('List')}" class="rte-list"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#icon-list-bullet"></use></svg></button>`;else if (btn === 'textsettings') html_rte += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'icon' && !this.builder.opts.emailMode) html_rte += `<button tabindex="-1" title="${util.out('Icon')}" class="rte-icon"><svg class="is-icon-flex" style="width:14px;height:14px;margin-top:2px"><use xlink:href="#ion-android-happy"></use></svg></button>`;else if (btn === 'svg' && !this.builder.opts.emailMode) html_rte += `<button tabindex="-1" title="${util.out('SVG')}" class="rte-svg"><svg class="is-icon-flex" style="width:19px;height:19px;margin-top:2px"><use xlink:href="#icon-svg"></use></svg></button>`;else if (btn === 'tags') html_rte += customtag_button;else if (btn === 'removeformat') html_rte += `<button tabindex="-1" title="${util.out('Clean')}" class="rte-format" data-command="clean"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#icon-clean"></use></svg></button>`;else if (btn === 'font') html_rte += `<button tabindex="-1" title="${util.out('Font')}" class="rte-fontfamily"><span style="font-family:serif;font-size:18px;text-transform:none;display:inline-block;margin-top: -3px;">a</span></button>`;else if (btn === 'image') html_rte += `<button tabindex="-1" title="${util.out('Image')}" class="rte-image"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-image"></use></svg></button>`;else if (btn === 'gridtool') html_rte += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;width:17px;height:17px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_rte += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_rte += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_rte += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'undo') html_rte += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_rte += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_rte += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_rte += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'more' && html_rtemore !== '') html_rte += `<button tabindex="-1" title="${util.out('More')}" class="rte-more"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-more"></use></svg></button>`;else if (btn === 'pageoptions') html_rte += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;transform:rotate(90deg)"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_rte += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_rte += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_rte += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64502
+ if (btn === 'bold') html_rte += `<button tabindex="-1" title="${util.out('Bold')}" class="rte-format" data-command="bold"><span style="font-family:serif;font-size:14px;">B</span></button>`;else if (btn === 'italic') html_rte += `<button tabindex="-1" title="${util.out('Italic')}" class="rte-format" data-command="italic"><span style="font-family:serif;font-size:16px;font-style:italic;">i</span></button>`;else if (btn === 'underline') html_rte += `<button tabindex="-1" title="${util.out('Underline')}" class="rte-format" data-command="underline"><span style="font-family:serif;font-size:14px;text-decoration:underline;">U</span></button>`;else if (btn === 'createlink') html_rte += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;else if (btn === 'align') html_rte += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'formatpara') html_rte += `<button tabindex="-1" title="${util.out('Paragraph')}" class="rte-paragraph"><span style="font-family:serif;font-size:14px;display:inline-block;margin-top:2px;">H</span></button>`;else if (btn === 'color') html_rte += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'formatting') html_rte += `<button tabindex="-1" title="${util.out('Formatting')}" class="rte-formatting"><span style="font-family:serif;font-size:15px;display:inline-block;">A</span></button>`;else if (btn === 'list') html_rte += `<button tabindex="-1" title="${util.out('List')}" class="rte-list"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#icon-list-bullet"></use></svg></button>`;else if (btn === 'textsettings') html_rte += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'icon' && !this.builder.opts.emailMode) html_rte += `<button tabindex="-1" title="${util.out('Icon')}" class="rte-icon"><svg class="is-icon-flex" style="width:14px;height:14px;margin-top:2px"><use xlink:href="#ion-android-happy"></use></svg></button>`;else if (btn === 'svg' && !this.builder.opts.emailMode) html_rte += `<button tabindex="-1" title="${util.out('SVG')}" class="rte-svg"><svg class="is-icon-flex" style="width:19px;height:19px;margin-top:2px"><use xlink:href="#icon-svg"></use></svg></button>`;else if (btn === 'tags') html_rte += customtag_button;else if (btn === 'removeformat') html_rte += `<button tabindex="-1" title="${util.out('Clean')}" class="rte-format" data-command="clean"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#icon-clean"></use></svg></button>`;else if (btn === 'font') html_rte += `<button tabindex="-1" title="${util.out('Font')}" class="rte-fontfamily"><span style="font-family:serif;font-size:18px;text-transform:none;display:inline-block;margin-top: -3px;">a</span></button>`;else if (btn === 'image') html_rte += `<button tabindex="-1" title="${util.out('Image')}" class="rte-image"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-image"></use></svg></button>`;else if (btn === 'gridtool') html_rte += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;width:17px;height:17px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_rte += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_rte += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_rte += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'undo') html_rte += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_rte += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_rte += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_rte += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'more' && html_rtemore !== '') html_rte += `<button tabindex="-1" title="${util.out('More')}" class="rte-more"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-more"></use></svg></button>`;else if (btn === 'pageoptions') html_rte += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_rte += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_rte += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:1px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_rte += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64501
64503
  html_rte += '<div class="rte-separator"></div>';
64502
64504
  } else {
64503
64505
  html_rte += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -64515,7 +64517,7 @@ class Rte {
64515
64517
  let html_elementrtemore = '';
64516
64518
  for (j = 0; j < builder.opts.elementButtonsMore.length; j++) {
64517
64519
  btn = builder.opts.elementButtonsMore[j].toLowerCase();
64518
- if (btn === 'left') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Left')}" data-align="left"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-left"></use></svg></button>`;else if (btn === 'center') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Center')}" data-align="center"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-center"></use></svg></button>`;else if (btn === 'right') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Right')}" data-align="right"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-right"></use></svg></button>`;else if (btn === 'full') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Full')}" data-align="justify"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'gridtool') html_elementrtemore += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_elementrtemore += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_elementrtemore += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_elementrtemore += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'undo') html_elementrtemore += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_elementrtemore += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_elementrtemore += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_elementrtemore += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_elementrtemore += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;transform:rotate(90deg)"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_elementrtemore += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_elementrtemore += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_elementrtemore += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64520
+ if (btn === 'left') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Left')}" data-align="left"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-left"></use></svg></button>`;else if (btn === 'center') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Center')}" data-align="center"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-center"></use></svg></button>`;else if (btn === 'right') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Right')}" data-align="right"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-right"></use></svg></button>`;else if (btn === 'full') html_elementrtemore += `<button tabindex="-1" title="${util.out('Align Full')}" data-align="justify"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'gridtool') html_elementrtemore += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_elementrtemore += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_elementrtemore += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_elementrtemore += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'undo') html_elementrtemore += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_elementrtemore += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_elementrtemore += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_elementrtemore += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_elementrtemore += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_elementrtemore += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_elementrtemore += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:1px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_elementrtemore += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64519
64521
  html_elementrtemore += '<div class="rte-separator"></div>';
64520
64522
  } else {
64521
64523
  html_elementrtemore += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -64525,7 +64527,7 @@ class Rte {
64525
64527
  let html_elementrte = '';
64526
64528
  for (j = 0; j < builder.opts.elementButtons.length; j++) {
64527
64529
  btn = builder.opts.elementButtons[j].toLowerCase();
64528
- if (btn === 'left') html_elementrte += `<button tabindex="-1" title="${util.out('Align Left')}" data-align="left"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-left"></use></svg></button>`;else if (btn === 'center') html_elementrte += `<button tabindex="-1" title="${util.out('Align Center')}" data-align="center"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-center"></use></svg></button>`;else if (btn === 'right') html_elementrte += `<button tabindex="-1" title="${util.out('Align Right')}" data-align="right"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-right"></use></svg></button>`;else if (btn === 'full') html_elementrte += `<button tabindex="-1" title="${util.out('Align Full')}" data-align="justify"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'gridtool') html_elementrte += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;width:17px;height:17px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_elementrte += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_elementrte += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_elementrte += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'group') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Group')}" class="rte-group"><svg class="is-icon-flex" style="width:20px;height:20px;margin-top:-1px;"><use xlink:href="#icon-group"></use></svg></button>`;else if (btn === 'ungroup') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Ungroup')}" class="rte-ungroup"><svg class="is-icon-flex" style="width:20px;height:20px;margin-top:-1px;"><use xlink:href="#icon-ungroup"></use></svg></button>`;else if (btn === 'duplicate') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Duplicate')}" class="rte-duplicate"><svg class="is-icon-flex" style="width:20px;height:20px;margin-top:-1px;"><use xlink:href="#icon-duplicate"></use></svg></button>`;else if (btn === 'front') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Bring to Front')}" class="rte-front"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-stack-forward"></use></svg></button>`;else if (btn === 'backward') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Send to Back')}" class="rte-backward"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-stack-backward"></use></svg></button>`;else if (btn === 'moveup') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Move Up')}" class="rte-moveup"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-arrow-up"></use></svg></button>`;else if (btn === 'movedown') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Move Down')}" class="rte-movedown"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-arrow-down"></use></svg></button>`;else if (btn === 'delete') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Delete')}" class="rte-delete"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-trash"></use></svg></button>`;else if (btn === 'blocksettings' && this.builder.canvas) html_elementrte += `<button tabindex="-1" title="${util.out('Block Settings')}" class="rte-blocksettings"><svg class="is-icon-flex"><use xlink:href="#icon-settings"></use></svg></button>`;else if (btn === 'undo') html_elementrte += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_elementrte += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_elementrte += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_elementrte += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'more' && html_elementrtemore !== '') html_elementrte += `<button tabindex="-1" title="${util.out('More')}" class="rte-more"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-more"></use></svg></button>`;else if (btn === 'pageoptions') html_elementrte += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;transform:rotate(90deg)"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_elementrte += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_elementrte += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_elementrte += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64530
+ if (btn === 'left') html_elementrte += `<button tabindex="-1" title="${util.out('Align Left')}" data-align="left"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-left"></use></svg></button>`;else if (btn === 'center') html_elementrte += `<button tabindex="-1" title="${util.out('Align Center')}" data-align="center"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-center"></use></svg></button>`;else if (btn === 'right') html_elementrte += `<button tabindex="-1" title="${util.out('Align Right')}" data-align="right"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-right"></use></svg></button>`;else if (btn === 'full') html_elementrte += `<button tabindex="-1" title="${util.out('Align Full')}" data-align="justify"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'gridtool') html_elementrte += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;width:17px;height:17px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_elementrte += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_elementrte += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_elementrte += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'group') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Group')}" class="rte-group"><svg class="is-icon-flex" style="width:20px;height:20px;margin-top:-1px;"><use xlink:href="#icon-group"></use></svg></button>`;else if (btn === 'ungroup') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Ungroup')}" class="rte-ungroup"><svg class="is-icon-flex" style="width:20px;height:20px;margin-top:-1px;"><use xlink:href="#icon-ungroup"></use></svg></button>`;else if (btn === 'duplicate') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Duplicate')}" class="rte-duplicate"><svg class="is-icon-flex" style="width:16px;height:16px;margin-top:-1px;"><use xlink:href="#icon-duplicate"></use></svg></button>`;else if (btn === 'front') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Bring to Front')}" class="rte-front"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-stack-forward"></use></svg></button>`;else if (btn === 'backward') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Send to Back')}" class="rte-backward"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-stack-backward"></use></svg></button>`;else if (btn === 'moveup') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Move Up')}" class="rte-moveup"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-arrow-up"></use></svg></button>`;else if (btn === 'movedown') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Move Down')}" class="rte-movedown"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-arrow-down"></use></svg></button>`;else if (btn === 'delete') html_elementrte += `<button style="display:none" tabindex="-1" title="${util.out('Delete')}" class="rte-delete"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#icon-trash"></use></svg></button>`;else if (btn === 'blocksettings' && this.builder.canvas) html_elementrte += `<button tabindex="-1" title="${util.out('Block Settings')}" class="rte-blocksettings"><svg class="is-icon-flex"><use xlink:href="#icon-settings"></use></svg></button>`;else if (btn === 'undo') html_elementrte += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_elementrte += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_elementrte += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_elementrte += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'more' && html_elementrtemore !== '') html_elementrte += `<button tabindex="-1" title="${util.out('More')}" class="rte-more"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-more"></use></svg></button>`;else if (btn === 'pageoptions') html_elementrte += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_elementrte += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_elementrte += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:1px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_elementrte += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64529
64531
  html_elementrte += '<div class="rte-separator"></div>';
64530
64532
  } else {
64531
64533
  html_elementrte += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -64545,7 +64547,7 @@ class Rte {
64545
64547
  let html_iconrte = '';
64546
64548
  for (j = 0; j < builder.opts.iconButtonsMore.length; j++) {
64547
64549
  btn = builder.opts.iconButtonsMore[j].toLowerCase();
64548
- if (btn === 'createlink') html_iconrtemore += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;else if (btn === 'icon' && !this.builder.opts.emailMode) html_iconrtemore += `<button tabindex="-1" title="${util.out('Icon')}" class="rte-icon"><svg class="is-icon-flex" style="width:14px;height:14px;margin-top:2px;"><use xlink:href="#ion-android-happy"></use></svg></button>`;else if (btn === 'svg' && !this.builder.opts.emailMode) html_iconrtemore += `<button tabindex="-1" title="${util.out('SVG')}" class="rte-svg"><svg class="is-icon-flex" style="width:19px;height:19px;margin-top:2px;"><use xlink:href="#icon-svg"></use></svg></button>`;else if (btn === 'align') html_iconrtemore += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'color') html_iconrtemore += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'gridtool') html_iconrtemore += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_iconrtemore += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_iconrtemore += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_iconrtemore += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'textsettings') html_iconrtemore += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'undo') html_iconrtemore += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_iconrtemore += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_iconrtemore += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_iconrtemore += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_iconrtemore += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;transform:rotate(90deg)"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_iconrtemore += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_iconrtemore += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_iconrtemore += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64550
+ if (btn === 'createlink') html_iconrtemore += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;else if (btn === 'icon' && !this.builder.opts.emailMode) html_iconrtemore += `<button tabindex="-1" title="${util.out('Icon')}" class="rte-icon"><svg class="is-icon-flex" style="width:14px;height:14px;margin-top:2px;"><use xlink:href="#ion-android-happy"></use></svg></button>`;else if (btn === 'svg' && !this.builder.opts.emailMode) html_iconrtemore += `<button tabindex="-1" title="${util.out('SVG')}" class="rte-svg"><svg class="is-icon-flex" style="width:19px;height:19px;margin-top:2px;"><use xlink:href="#icon-svg"></use></svg></button>`;else if (btn === 'align') html_iconrtemore += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'color') html_iconrtemore += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'gridtool') html_iconrtemore += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_iconrtemore += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_iconrtemore += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_iconrtemore += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'textsettings') html_iconrtemore += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'undo') html_iconrtemore += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_iconrtemore += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_iconrtemore += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_iconrtemore += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_iconrtemore += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_iconrtemore += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_iconrtemore += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:1px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_iconrtemore += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === '|') {
64549
64551
  html_iconrtemore += '<div class="rte-separator"></div>';
64550
64552
  } else {
64551
64553
  html_iconrtemore += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -64554,7 +64556,7 @@ class Rte {
64554
64556
 
64555
64557
  for (j = 0; j < builder.opts.iconButtons.length; j++) {
64556
64558
  btn = builder.opts.iconButtons[j].toLowerCase();
64557
- if (btn === 'createlink') html_iconrte += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;else if (btn === 'icon' && !this.builder.opts.emailMode) html_iconrte += `<button tabindex="-1" title="${util.out('Icon')}" class="rte-icon"><svg class="is-icon-flex" style="width:14px;height:14px;margin-top:2px;"><use xlink:href="#ion-android-happy"></use></svg></button>`;else if (btn === 'svg' && !this.builder.opts.emailMode) html_iconrte += `<button tabindex="-1" title="${util.out('SVG')}" class="rte-svg"><svg class="is-icon-flex" style="width:19px;height:19px;margin-top:2px;"><use xlink:href="#icon-svg"></use></svg></button>`;else if (btn === 'align') html_iconrte += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'color') html_iconrte += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'gridtool') html_iconrte += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_iconrte += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_iconrte += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_iconrte += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'textsettings') html_iconrte += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'undo') html_iconrte += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_iconrte += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_iconrte += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_iconrte += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_iconrte += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;transform:rotate(90deg)"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_iconrte += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_iconrte += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_iconrte += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === 'more' && html_rtemore !== '') html_iconrte += `<button tabindex="-1" title="${util.out('More')}" class="rte-more"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-more"></use></svg></button>`;else if (btn === '|') {
64559
+ if (btn === 'createlink') html_iconrte += `<button tabindex="-1" title="${util.out('Hyperlink')}" class="rte-link"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#ion-link"></use></svg></button>`;else if (btn === 'icon' && !this.builder.opts.emailMode) html_iconrte += `<button tabindex="-1" title="${util.out('Icon')}" class="rte-icon"><svg class="is-icon-flex" style="width:14px;height:14px;margin-top:2px;"><use xlink:href="#ion-android-happy"></use></svg></button>`;else if (btn === 'svg' && !this.builder.opts.emailMode) html_iconrte += `<button tabindex="-1" title="${util.out('SVG')}" class="rte-svg"><svg class="is-icon-flex" style="width:19px;height:19px;margin-top:2px;"><use xlink:href="#icon-svg"></use></svg></button>`;else if (btn === 'align') html_iconrte += `<button tabindex="-1" title="${util.out('Align')}" class="rte-align"><svg class="is-icon-flex" style="width:12px;height:12px;margin-top:-2px;"><use xlink:href="#icon-align-full"></use></svg></button>`;else if (btn === 'color') html_iconrte += `<button tabindex="-1" title="${util.out('Color')}" class="rte-color"><svg class="is-icon-flex" style="width:12px;height:12px;"><use xlink:href="#ion-contrast"></use></svg></button>`;else if (btn === 'gridtool') html_iconrte += `<button tabindex="-1" title="${util.out('Grid Tool')}" class="rte-grideditor"><svg class="is-icon-flex" style="margin-right:-3px;"><use xlink:href="#ion-grid"></use></svg></button>`;else if (btn === 'html') html_iconrte += `<button tabindex="-1" title="${util.out('HTML')}" class="rte-html"><svg class="is-icon-flex" style="margin-right:-3px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-left"></use></svg><svg class="is-icon-flex" style="margin-left:-2px;width:14px;height:14px;"><use xlink:href="#ion-ios-arrow-right"></use></svg></button>`;else if (btn === 'preferences') html_iconrte += `<button tabindex="-1" title="${util.out('Preferences')}" class="rte-preferences"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-wrench"></use></svg></button>`;else if (btn === 'addsnippet') html_iconrte += `<button tabindex="-1" title="${util.out('Add Snippet')}" class="rte-addsnippet"><svg class="is-icon-flex" style="width:18px;height:18px;margin-top:-1px;"><use xlink:href="#ion-ios-plus-empty"></use></svg></button>`;else if (btn === 'textsettings') html_iconrte += `<button tabindex="-1" title="${util.out('Text Settings')}" class="rte-textsettings"><svg class="is-icon-flex" style="width:16px;height:16px;"><use xlink:href="#ion-ios-settings"></use></svg></button>`;else if (btn === 'undo') html_iconrte += `<button tabindex="-1" title="${util.out('Undo')}" class="rte-undo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-undo"></use></svg></button>`;else if (btn === 'redo') html_iconrte += `<button tabindex="-1" title="${util.out('Redo')}" class="rte-redo"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#ion-ios-redo"></use></svg></button>`;else if (btn === 'aiassistant') html_iconrte += `<button tabindex="-1" title="${util.out('AI Assistant')}" class="rte-ai"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-message"></use></svg></button>`;else if (btn === 'snippets') html_iconrte += `<button tabindex="-1" title="${util.out('Snippets')}" class="rte-snippets"><svg class="is-icon-flex" style="width:19px;height:19px;"><use xlink:href="#icon-snippets"></use></svg></button>`;else if (btn === 'pageoptions') html_iconrte += `<button tabindex="-1" title="${util.out('Page Options')}" class="rte-pageoptions"><svg class="is-icon-flex"><use xlink:href="#icon-pagesize"></use></svg></button>`;else if (btn === 'print') html_iconrte += `<button tabindex="-1" title="${util.out('Print')}" class="rte-print"><svg class="is-icon-flex" style="width:15px;height:15px;"><use xlink:href="#icon-print"></use></svg></button>`;else if (btn === 'zoom') html_iconrte += `<button tabindex="-1" title="${util.out('Zoom')}" class="rte-zoom"><svg class="is-icon-flex" style="margin-top:1px;width:15px;height:15px;"><use xlink:href="#icon-zoom-in"></use></svg></button>`;else if (btn === 'livepreview') html_iconrte += `<button tabindex="-1" title="${util.out('Live Preview')}" class="rte-livepreview"><svg class="is-icon-flex" style="margin-top:2px;width:15px;height:15px;"><use xlink:href="#icon-device-desktop"></use></svg></button>`;else if (btn === 'more' && html_rtemore !== '') html_iconrte += `<button tabindex="-1" title="${util.out('More')}" class="rte-more"><svg class="is-icon-flex" style="width:13px;height:13px;"><use xlink:href="#ion-more"></use></svg></button>`;else if (btn === '|') {
64558
64560
  html_iconrte += '<div class="rte-separator"></div>';
64559
64561
  } else {
64560
64562
  html_iconrte += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -64701,6 +64703,9 @@ class Rte {
64701
64703
  <div style="padding-top:4px">
64702
64704
  <input type="range" min="50" max="${zoomMax}" value="1" class="rte-zoom-slider is-rangeslider">
64703
64705
  </div>
64706
+ <div style="display:flex;justify-content:flex-end">
64707
+ <button title="${util.out('Reset')}" class="reset-zoom" style="background:transparent;padding:0;height:27px;text-decoration:underline">${util.out('Reset')}</button>
64708
+ </div>
64704
64709
  </div>
64705
64710
  </div>
64706
64711
 
@@ -65879,6 +65884,16 @@ class Rte {
65879
65884
  showTools();
65880
65885
  });
65881
65886
 
65887
+ // Reset Zoom
65888
+ const btnResetZoom = builderStuff.querySelector('.reset-zoom');
65889
+ btnResetZoom.addEventListener('click', () => {
65890
+ this.builder.opts.zoom = 1;
65891
+ localStorage.setItem('_zoom', 1); // Save
65892
+
65893
+ // setZoomOnArea
65894
+ this.builder.setZoomOnArea();
65895
+ });
65896
+
65882
65897
  // Zoom Modal
65883
65898
  this.inpZoomSlider.onfocus = () => {
65884
65899
  if (this.builder.onZoomStart) {
@@ -73397,7 +73412,6 @@ class ContentStuff {
73397
73412
  <button title="${util.out('Settings')}" data-title="${util.out('Settings')}" style="width:37px;height:37px;background:none;"><svg class="is-icon-flex"><use xlink:href="#ion-ios-gear"></use></svg></button>
73398
73413
  </div>
73399
73414
 
73400
-
73401
73415
  <div class="is-locked-indicator">
73402
73416
  <svg class="is-icon-flex"><use xlink:href="#icon-lock"></use></svg>
73403
73417
  </div>
@@ -73891,6 +73905,35 @@ class ContentStuff {
73891
73905
  }
73892
73906
  .is-tool.is-element-tool .elm-settings { display: none; }
73893
73907
 
73908
+ /* is-block-tool
73909
+
73910
+ .is-tool.is-block-tool {
73911
+ background: rgba(243, 243, 243, 0.9);
73912
+ border-radius: 3px;
73913
+ overflow: hidden;
73914
+ top: 3px;
73915
+ right: 3px;
73916
+ left: auto;
73917
+ width: 25px;
73918
+ }
73919
+ .is-tool.is-block-tool button {
73920
+ width: 25px;
73921
+ height: 25px;
73922
+ background: transparent;
73923
+ display: flex;
73924
+ align-items: center;
73925
+ justify-content: center;
73926
+ }
73927
+ .is-tool.is-block-tool svg {
73928
+ width: 14px;
73929
+ height: 14px;
73930
+ fill: #000;
73931
+ }
73932
+ .is-block.active:not(.multi):not(.editable) .is-block-tool {
73933
+ display:flex;
73934
+ }
73935
+ */
73936
+
73894
73937
  /* is-column-tool */
73895
73938
 
73896
73939
  .is-tool.is-column-tool {
@@ -74987,7 +75030,7 @@ class LivePreview {
74987
75030
  // ContentBuilder
74988
75031
 
74989
75032
  if (this.builder.previewURL) {
74990
- if (this.builder.livePreviewAlwaysReload) {
75033
+ if (this.builder.livePreviewAlwaysReload || hardReload) {
74991
75034
  iframe.src = this.builder.previewURL + '?' + Math.floor(Date.now() / 1000);
74992
75035
  } else {
74993
75036
  let iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
@@ -81759,7 +81802,25 @@ class Common {
81759
81802
  applyPercentage(block) {
81760
81803
  const zoom = this.zoom;
81761
81804
  const rect = this.getRect(block);
81762
- const container = block.parentNode;
81805
+ const container = block.closest('.box-canvas');
81806
+ const containerRect = this.getRect(container); // if container has top/left
81807
+
81808
+ this.horizontalRulerTop = container.querySelector('.h-ruler-top');
81809
+ this.horizontalRulerBottom = container.querySelector('.h-ruler-bottom');
81810
+ this.horizontalRulerMiddle = container.querySelector('.h-ruler-middle');
81811
+ this.verticalRulerLeft = container.querySelector('.v-ruler-left');
81812
+ this.verticalRulerRight = container.querySelector('.v-ruler-right');
81813
+ this.verticalRulerCenter = container.querySelector('.v-ruler-center');
81814
+
81815
+ // Check Edges
81816
+ let topTouched = false;
81817
+ let bottomTouched = false;
81818
+ let leftTouched = false;
81819
+ let rightTouched = false;
81820
+ if (this.horizontalRulerTop.hasAttribute('data-topTouched')) topTouched = true;
81821
+ if (this.horizontalRulerBottom.hasAttribute('data-bottomTouched')) bottomTouched = true;
81822
+ if (this.verticalRulerLeft.hasAttribute('data-leftTouched')) leftTouched = true;
81823
+ if (this.verticalRulerRight.hasAttribute('data-rightTouched')) rightTouched = true;
81763
81824
  let isChildBlock = false;
81764
81825
  if (block.parentNode.matches(this.selector)) {
81765
81826
  // child block
@@ -81767,7 +81828,7 @@ class Common {
81767
81828
  }
81768
81829
 
81769
81830
  // const containerRect = container.getBoundingClientRect(); // if container has top/left
81770
- const containerRect = this.getRect(container); // if container has top/left
81831
+ // const containerRect = this.getRect(container); // if container has top/left
81771
81832
  let left = (rect.left - containerRect.left) / container.offsetWidth * 100;
81772
81833
  let top = (rect.top - containerRect.top) / container.offsetHeight * 100;
81773
81834
  let isBlockFixed = block.classList.contains('block-steady');
@@ -81806,6 +81867,35 @@ class Common {
81806
81867
  block.style.left = left / zoom + '%';
81807
81868
  if (block.classList.contains('height-auto')) block.style.height = '';
81808
81869
  }
81870
+
81871
+ // Check
81872
+
81873
+ block.style.right = ''; //reset
81874
+ block.style.bottom = ''; //reset
81875
+
81876
+ if (topTouched) block.style.top = 0;
81877
+ // if(topTouched && bottomTouched) block.style.height = '100%';
81878
+ if (leftTouched) block.style.left = 0;
81879
+ // if(leftTouched && rightTouched) block.style.width = '100%';
81880
+
81881
+ if (topTouched && bottomTouched) {
81882
+ block.style.top = 0;
81883
+ block.style.bottom = 0;
81884
+ block.style.height = '';
81885
+ }
81886
+ if (leftTouched && rightTouched) {
81887
+ block.style.left = 0;
81888
+ block.style.right = 0;
81889
+ block.style.width = '';
81890
+ }
81891
+ if (bottomTouched && !topTouched) {
81892
+ block.style.bottom = 0;
81893
+ block.style.height = '';
81894
+ }
81895
+ if (rightTouched && !leftTouched) {
81896
+ block.style.right = 0;
81897
+ block.style.width = '';
81898
+ }
81809
81899
  }
81810
81900
  applyPixels(block) {
81811
81901
  const zoom = this.zoom;
@@ -81960,15 +82050,16 @@ class Common {
81960
82050
  right = Math.max(right, blockLeft + blockWidth);
81961
82051
  }
81962
82052
  });
82053
+ const container = blocks[0].parentNode;
82054
+ const containerRect = this.getRect(container);
81963
82055
  const group = this.doc.createElement('div');
81964
82056
  group.classList.add(className);
81965
82057
  group.classList.add(groupClassName);
81966
82058
  group.classList.add('block-steady');
81967
- group.style.top = top + 'px';
81968
- group.style.left = left + 'px';
82059
+ group.style.top = top - containerRect.top + 'px';
82060
+ group.style.left = left - containerRect.left + 'px';
81969
82061
  group.style.width = right + 1 - left + 'px';
81970
82062
  group.style.height = bottom + 1 - top + 'px';
81971
- const container = blocks[0].parentNode;
81972
82063
  container.appendChild(group);
81973
82064
  blocks.forEach(block => {
81974
82065
  if (!block.parentNode.matches(this.selector)) {
@@ -81977,8 +82068,8 @@ class Common {
81977
82068
  let blockLeft = parseFloat(block.style.left) || 0;
81978
82069
 
81979
82070
  // Adjust position relative to the group div
81980
- block.style.top = blockTop - top + 'px';
81981
- block.style.left = blockLeft - left + 'px';
82071
+ block.style.top = blockTop - top + containerRect.top + 'px';
82072
+ block.style.left = blockLeft - left + containerRect.left + 'px';
81982
82073
  group.appendChild(block);
81983
82074
  this.applyPercentage(block);
81984
82075
  }
@@ -82033,14 +82124,15 @@ class Common {
82033
82124
  const top = rect.top;
82034
82125
  const left = rect.left;
82035
82126
  const container = group.parentNode;
82127
+ const containerRect = this.getRect(container);
82036
82128
  group.querySelectorAll(this.selector).forEach(block => {
82037
82129
  this.applyPixels(block);
82038
82130
  let blockTop = parseFloat(block.style.top) || 0;
82039
82131
  let blockLeft = parseFloat(block.style.left) || 0;
82040
82132
 
82041
82133
  // Adjust position relative to the group div
82042
- block.style.top = blockTop + top + 'px';
82043
- block.style.left = blockLeft + left + 'px';
82134
+ block.style.top = blockTop + top - containerRect.top + 'px';
82135
+ block.style.left = blockLeft + left - containerRect.left + 'px';
82044
82136
  container.appendChild(block);
82045
82137
 
82046
82138
  // Remove all breakpoints
@@ -82252,10 +82344,23 @@ class Ruler {
82252
82344
  this.zoom = scale;
82253
82345
  }
82254
82346
  setup() {
82255
- this.elements = this.doc.querySelectorAll(this.selector);
82347
+ // this.elements = this.doc.querySelectorAll(this.selector);
82348
+ this.refresh();
82256
82349
  }
82257
82350
  refresh() {
82258
82351
  this.elements = this.doc.querySelectorAll(this.selector);
82352
+ const rulerHTML = `
82353
+ <div class="ruler h-ruler h-ruler-top""></div>
82354
+ <div class="ruler h-ruler h-ruler-bottom"></div>
82355
+ <div class="ruler h-ruler h-ruler-middle"></div>
82356
+ <div class="ruler v-ruler v-ruler-left"></div>
82357
+ <div class="ruler v-ruler v-ruler-right"></div>
82358
+ <div class="ruler v-ruler v-ruler-center"></div>
82359
+ `;
82360
+ const containers = this.doc.querySelectorAll('.box-canvas');
82361
+ containers.forEach(container => {
82362
+ if (!container.querySelector('.h-ruler-top')) container.insertAdjacentHTML('beforeend', rulerHTML);
82363
+ });
82259
82364
  }
82260
82365
  destroy() {
82261
82366
  [this.horizontalRulerTop, this.horizontalRulerBottom, this.verticalRulerLeft, this.verticalRulerRight].forEach(elm => {
@@ -82263,6 +82368,18 @@ class Ruler {
82263
82368
  });
82264
82369
  }
82265
82370
  hideRulers() {
82371
+ this.horizontalRulerTop.classList.remove('active');
82372
+ this.horizontalRulerBottom.classList.remove('active');
82373
+ this.horizontalRulerMiddle.classList.remove('active');
82374
+ this.verticalRulerLeft.classList.remove('active');
82375
+ this.verticalRulerRight.classList.remove('active');
82376
+ this.verticalRulerCenter.classList.remove('active');
82377
+ this.rulerTop = null;
82378
+ this.rulerBottom = null; //new
82379
+ this.rulerLeft = null;
82380
+ this.rulerRight = null;
82381
+ }
82382
+ hideRulers_bak() {
82266
82383
  this.horizontalRulerTop.style.top = '-1000px';
82267
82384
  this.horizontalRulerBottom.style.top = '-1000px';
82268
82385
  this.horizontalRulerMiddle.style.top = '-1000px';
@@ -82270,10 +82387,207 @@ class Ruler {
82270
82387
  this.verticalRulerRight.style.left = '-1000px';
82271
82388
  this.verticalRulerCenter.style.left = '-1000px';
82272
82389
  this.rulerTop = null;
82390
+ this.rulerBottom = null; //new
82273
82391
  this.rulerLeft = null;
82274
82392
  this.rulerRight = null;
82275
82393
  }
82276
82394
  updateRulers(block) {
82395
+ const container = block.closest('.box-canvas');
82396
+ this.horizontalRulerTop = container.querySelector('.h-ruler-top');
82397
+ this.horizontalRulerBottom = container.querySelector('.h-ruler-bottom');
82398
+ this.horizontalRulerMiddle = container.querySelector('.h-ruler-middle');
82399
+ this.verticalRulerLeft = container.querySelector('.v-ruler-left');
82400
+ this.verticalRulerRight = container.querySelector('.v-ruler-right');
82401
+ this.verticalRulerCenter = container.querySelector('.v-ruler-center');
82402
+ let transform = block.style.transform;
82403
+ if (transform.includes('rotate') || transform.includes('matrix3d')) return;
82404
+ let parentTransform = block.parentNode.style.transform;
82405
+ if (parentTransform.includes('rotate')) return;
82406
+ this.hideRulers();
82407
+ const top = block.offsetTop;
82408
+ const bottom = top + block.offsetHeight;
82409
+ const left = block.offsetLeft;
82410
+ const right = left + block.offsetWidth;
82411
+ const center = left + block.offsetWidth / 2;
82412
+ const middle = top + block.offsetHeight / 2;
82413
+ this.rulerTop = null;
82414
+ this.rulerBottom = null; //new
82415
+ this.rulerLeft = null;
82416
+ this.rulerRight = null;
82417
+ this.elements = container.querySelectorAll(this.selector);
82418
+ this.elements.forEach(element => {
82419
+ if (!this.doc.body.contains(element)) return; // in case element removed (eg. unGroup, block deleted)
82420
+
82421
+ if (block.contains(element)) return; // In case of group moving
82422
+
82423
+ let transform = element.style.transform;
82424
+ let parentTransform = element.parentNode.style.transform;
82425
+ if (!transform.includes('rotate') && !parentTransform.includes('rotate') && !transform.includes('matrix3d') && !parentTransform.includes('matrix3d') && element !== block && !element.classList.contains('cloned')) {
82426
+ const otherTop = element.offsetTop;
82427
+ const otherBottom = otherTop + element.offsetHeight;
82428
+ const otherLeft = element.offsetLeft;
82429
+ const otherRight = otherLeft + element.offsetWidth;
82430
+ const otherMiddle = otherTop + element.offsetHeight / 2;
82431
+ const otherCenter = otherLeft + element.offsetWidth / 2;
82432
+
82433
+ // block top
82434
+ if (otherTop - 4 <= top && top <= otherTop + 4) {
82435
+ this.horizontalRulerTop.style.top = otherTop + 'px';
82436
+ this.horizontalRulerTop.classList.add('active');
82437
+ let val = otherTop;
82438
+ if (this.rulerTop === null) this.rulerTop = val;
82439
+ }
82440
+ if (otherBottom - 4 <= top && top <= otherBottom + 4) {
82441
+ this.horizontalRulerTop.style.top = otherBottom + 'px';
82442
+ this.horizontalRulerTop.classList.add('active');
82443
+ let val = otherBottom;
82444
+ if (this.rulerTop === null) this.rulerTop = val;
82445
+ }
82446
+
82447
+ // block bottom
82448
+ if (otherTop - 4 <= bottom && bottom <= otherTop + 4) {
82449
+ /*
82450
+ _____
82451
+ ___________________|__x__|__ rulerBottom
82452
+ | other |
82453
+ */
82454
+ this.horizontalRulerBottom.style.top = otherTop + 'px';
82455
+ this.horizontalRulerBottom.classList.add('active');
82456
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop; // new
82457
+ }
82458
+
82459
+ if (otherBottom - 4 <= bottom && bottom <= otherBottom + 4) {
82460
+ /*
82461
+ _____
82462
+ | other |__________|__x__|__ rulerBottom
82463
+
82464
+ */
82465
+ this.horizontalRulerBottom.style.top = otherBottom + 'px';
82466
+ this.horizontalRulerBottom.classList.add('active');
82467
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop + element.offsetHeight; // new
82468
+ }
82469
+
82470
+ // block middle
82471
+ if (this.rulerTop === null && this.rulerBottom === null) {
82472
+ if (otherMiddle - 4 <= middle && middle <= otherMiddle + 4) {
82473
+ this.horizontalRulerMiddle.style.top = otherTop + (element.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
82474
+ this.horizontalRulerMiddle.classList.add('active');
82475
+ let val = otherTop + (element.offsetHeight - block.offsetHeight) / 2;
82476
+ if (this.rulerTop === null) this.rulerTop = val;
82477
+ }
82478
+ }
82479
+
82480
+ // block left
82481
+ if (otherLeft - 4 <= left && left <= otherLeft + 4) {
82482
+ this.verticalRulerLeft.style.left = otherLeft + 'px';
82483
+ this.verticalRulerLeft.classList.add('active');
82484
+ let val = otherLeft;
82485
+ if (this.rulerLeft === null) this.rulerLeft = val;
82486
+ }
82487
+ if (otherRight - 4 <= left && left <= otherRight + 4) {
82488
+ this.verticalRulerLeft.style.left = otherRight + 'px';
82489
+ this.verticalRulerLeft.classList.add('active');
82490
+ let val = otherRight;
82491
+ if (this.rulerLeft === null) this.rulerLeft = val;
82492
+ }
82493
+
82494
+ // block right
82495
+ if (otherLeft - 4 <= right && right <= otherLeft + 4) {
82496
+ this.verticalRulerRight.style.left = otherLeft + 'px';
82497
+ this.verticalRulerRight.classList.add('active');
82498
+ let val = otherLeft;
82499
+ if (this.rulerRight === null) this.rulerRight = val;
82500
+ }
82501
+ if (otherRight - 4 <= right && right <= otherRight + 4) {
82502
+ this.verticalRulerRight.style.left = otherRight + 'px';
82503
+ this.verticalRulerRight.classList.add('active');
82504
+ let val = otherRight;
82505
+ if (this.rulerRight === null) this.rulerRight = val;
82506
+ }
82507
+
82508
+ // block center
82509
+ if (this.rulerLeft === null && this.rulerRight === null) {
82510
+ if (otherCenter - 4 <= center && center <= otherCenter + 4) {
82511
+ this.verticalRulerCenter.style.left = otherLeft + (element.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
82512
+ this.verticalRulerCenter.classList.add('active');
82513
+ let val = otherLeft + (element.offsetWidth - block.offsetWidth) / 2;
82514
+ if (this.rulerLeft === null) this.rulerLeft = val;
82515
+ }
82516
+ }
82517
+ }
82518
+ });
82519
+
82520
+ // Edges
82521
+ const conTop = 0;
82522
+ const conBottom = container.offsetHeight;
82523
+ const conLeft = 0;
82524
+ const conRight = container.offsetWidth;
82525
+ const conCenter = container.offsetWidth / 2;
82526
+ const conMiddle = container.offsetHeight / 2;
82527
+
82528
+ // block top
82529
+ this.horizontalRulerTop.removeAttribute('data-topTouched');
82530
+ if (conTop - 4 <= top && top <= conTop + 4) {
82531
+ this.horizontalRulerTop.style.top = conTop + 'px';
82532
+ this.horizontalRulerTop.classList.add('active');
82533
+ let val = conTop;
82534
+ if (this.rulerTop === null) this.rulerTop = val;
82535
+ this.topTouched = true;
82536
+ this.horizontalRulerTop.setAttribute('data-topTouched', 1);
82537
+ }
82538
+
82539
+ // block bottom
82540
+ this.horizontalRulerBottom.removeAttribute('data-bottomTouched');
82541
+ if (conBottom - 4 <= bottom && bottom <= conBottom + 4) {
82542
+ this.horizontalRulerBottom.style.top = conBottom - 2 + 'px'; // -2 is an adjustment to make the line visible
82543
+ this.horizontalRulerBottom.classList.add('active');
82544
+ if (this.rulerBottom === null) this.rulerBottom = conBottom; //conRect.height;// or block.parentNode.offsetHeight; // new
82545
+
82546
+ this.bottomTouched = true;
82547
+ this.horizontalRulerBottom.setAttribute('data-bottomTouched', 1);
82548
+ }
82549
+
82550
+ // block middle
82551
+ if (this.rulerTop === null && this.rulerBottom === null) {
82552
+ if (conMiddle - 4 <= middle && middle <= conMiddle + 4) {
82553
+ this.horizontalRulerMiddle.style.top = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
82554
+ this.horizontalRulerMiddle.classList.add('active');
82555
+ let val = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2;
82556
+ if (this.rulerTop === null) this.rulerTop = val;
82557
+ }
82558
+ }
82559
+
82560
+ // block left
82561
+ this.verticalRulerLeft.removeAttribute('data-leftTouched');
82562
+ if (conLeft - 4 <= left && left <= conLeft + 4) {
82563
+ this.verticalRulerLeft.style.left = conLeft + 0 + 'px'; // +0 is an adjustment
82564
+ this.verticalRulerLeft.classList.add('active');
82565
+ let val = conLeft;
82566
+ if (this.rulerLeft === null) this.rulerLeft = val;
82567
+ this.verticalRulerLeft.setAttribute('data-leftTouched', 1);
82568
+ }
82569
+
82570
+ // block right
82571
+ this.verticalRulerRight.removeAttribute('data-rightTouched');
82572
+ if (conRight - 4 <= right && right <= conRight + 4) {
82573
+ this.verticalRulerRight.style.left = conRight - 2 + 'px'; // -2 is an adjustment
82574
+ this.verticalRulerRight.classList.add('active');
82575
+ let val = conRight;
82576
+ if (this.rulerRight === null) this.rulerRight = val;
82577
+ this.verticalRulerRight.setAttribute('data-rightTouched', 1);
82578
+ }
82579
+
82580
+ // block center
82581
+ if (this.rulerLeft === null && this.rulerRight === null) {
82582
+ if (conCenter - 4 <= center && center <= conCenter + 4) {
82583
+ this.verticalRulerCenter.style.left = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
82584
+ this.verticalRulerCenter.classList.add('active');
82585
+ let val = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2;
82586
+ if (this.rulerLeft === null) this.rulerLeft = val;
82587
+ }
82588
+ }
82589
+ }
82590
+ updateRulers_bak(block) {
82277
82591
  // if(block.querySelector(this.selector)) return; // group (because updateRules also calls parent group if child block is dragged)
82278
82592
 
82279
82593
  let transform = block.style.transform;
@@ -82291,6 +82605,7 @@ class Ruler {
82291
82605
  const center = left + block.offsetWidth / 2;
82292
82606
  const middle = top + block.offsetHeight / 2;
82293
82607
  this.rulerTop = null;
82608
+ this.rulerBottom = null; //new
82294
82609
  this.rulerLeft = null;
82295
82610
  this.rulerRight = null;
82296
82611
  let containerTop = 0;
@@ -82314,18 +82629,6 @@ class Ruler {
82314
82629
  const otherRight = rect.left + element.offsetWidth;
82315
82630
  const otherMiddle = rect.top + element.offsetHeight / 2;
82316
82631
  const otherCenter = rect.left + element.offsetWidth / 2;
82317
- if (otherMiddle - 4 <= middle && middle <= otherMiddle + 4) {
82318
- this.horizontalRulerMiddle.style.top = containerTop + otherTop + (element.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
82319
- let val = otherTop + (element.offsetHeight - block.offsetHeight) / 2;
82320
- if (this.rulerTop === null) this.rulerTop = val;
82321
- }
82322
- if (otherCenter - 4 <= center && center <= otherCenter + 4) {
82323
- this.verticalRulerCenter.style.left = otherLeft + (element.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
82324
- this.verticalRulerCenter.style.top = containerTop + 'px'; // adj
82325
-
82326
- let val = otherLeft + (element.offsetWidth - block.offsetWidth) / 2;
82327
- if (this.rulerLeft === null) this.rulerLeft = val;
82328
- }
82329
82632
 
82330
82633
  // block top
82331
82634
  if (otherTop - 4 <= top && top <= otherTop + 4) {
@@ -82341,14 +82644,38 @@ class Ruler {
82341
82644
 
82342
82645
  // block bottom
82343
82646
  if (otherTop - 4 <= bottom && bottom <= otherTop + 4) {
82647
+ /*
82648
+ _____
82649
+ ___________________|__x__|__ rulerBottom
82650
+ | other |
82651
+ */
82344
82652
  this.horizontalRulerBottom.style.top = containerTop + otherTop + 'px';
82345
- let val = otherTop - block.offsetHeight;
82346
- if (this.rulerTop === null) this.rulerTop = val;
82653
+
82654
+ // let val = otherTop - block.offsetHeight;
82655
+ // if(this.rulerTop===null) this.rulerTop = val;
82656
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop; // new
82347
82657
  }
82658
+
82348
82659
  if (otherBottom - 4 <= bottom && bottom <= otherBottom + 4) {
82660
+ /*
82661
+ _____
82662
+ | other |__________|__x__|__ rulerBottom
82663
+
82664
+ */
82349
82665
  this.horizontalRulerBottom.style.top = containerTop + otherBottom + 'px';
82350
- let val = otherBottom - block.offsetHeight;
82351
- if (this.rulerTop === null) this.rulerTop = val;
82666
+
82667
+ // let val = otherBottom - block.offsetHeight;
82668
+ // if(this.rulerTop===null) this.rulerTop = val;
82669
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop + element.offsetHeight; // new
82670
+ }
82671
+
82672
+ // block middle
82673
+ if (this.rulerTop === null && this.rulerBottom === null) {
82674
+ if (otherMiddle - 4 <= middle && middle <= otherMiddle + 4) {
82675
+ this.horizontalRulerMiddle.style.top = containerTop + otherTop + (element.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
82676
+ let val = otherTop + (element.offsetHeight - block.offsetHeight) / 2;
82677
+ if (this.rulerTop === null) this.rulerTop = val;
82678
+ }
82352
82679
  }
82353
82680
 
82354
82681
  // block left
@@ -82382,6 +82709,17 @@ class Ruler {
82382
82709
  let val = otherRight;
82383
82710
  if (this.rulerRight === null) this.rulerRight = val;
82384
82711
  }
82712
+
82713
+ // block center
82714
+ if (this.rulerLeft === null && this.rulerRight === null) {
82715
+ if (otherCenter - 4 <= center && center <= otherCenter + 4) {
82716
+ this.verticalRulerCenter.style.left = otherLeft + (element.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
82717
+ this.verticalRulerCenter.style.top = containerTop + 'px'; // adj
82718
+
82719
+ let val = otherLeft + (element.offsetWidth - block.offsetWidth) / 2;
82720
+ if (this.rulerLeft === null) this.rulerLeft = val;
82721
+ }
82722
+ }
82385
82723
  }
82386
82724
  });
82387
82725
 
@@ -82393,44 +82731,69 @@ class Ruler {
82393
82731
  const conRight = conRect.left + block.parentNode.offsetWidth;
82394
82732
  const conCenter = conRect.left + block.parentNode.offsetWidth / 2;
82395
82733
  const conMiddle = conRect.top + block.parentNode.offsetHeight / 2;
82396
- if (conMiddle - 4 <= middle && middle <= conMiddle + 4) {
82397
- this.horizontalRulerMiddle.style.top = containerTop + conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
82398
- let val = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2;
82399
- if (this.rulerTop === null) this.rulerTop = val;
82400
- }
82401
- if (conCenter - 4 <= center && center <= conCenter + 4) {
82402
- this.verticalRulerCenter.style.left = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
82403
- this.verticalRulerCenter.style.top = containerTop + 'px';
82404
- let val = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2;
82405
- if (this.rulerLeft === null) this.rulerLeft = val;
82406
- }
82407
82734
 
82408
82735
  // block top
82736
+ this.horizontalRulerTop.removeAttribute('data-topTouched');
82409
82737
  if (conTop - 4 <= top && top <= conTop + 4) {
82410
82738
  this.horizontalRulerTop.style.top = containerTop + conTop + 'px';
82411
82739
  let val = conTop;
82412
82740
  if (this.rulerTop === null) this.rulerTop = val;
82741
+ this.topTouched = true;
82742
+ this.horizontalRulerTop.setAttribute('data-topTouched', 1);
82413
82743
  }
82744
+
82414
82745
  // block bottom
82746
+ this.horizontalRulerBottom.removeAttribute('data-bottomTouched');
82415
82747
  if (conBottom - 4 <= bottom && bottom <= conBottom + 4) {
82416
- this.horizontalRulerBottom.style.top = containerTop + conBottom - 3 + 'px'; // -3 is an adjustment to make the line visible
82748
+ this.horizontalRulerBottom.style.top = containerTop + conBottom - 2 + 'px'; // -2 is an adjustment to make the line visible
82417
82749
 
82418
- let val = conBottom - block.offsetHeight;
82419
- if (this.rulerTop === null) this.rulerTop = val;
82750
+ // let val = conBottom - block.offsetHeight;
82751
+ // if(this.rulerTop===null) this.rulerTop = val;
82752
+ if (this.rulerBottom === null) this.rulerBottom = conRect.height; // or block.parentNode.offsetHeight; // new
82753
+
82754
+ this.bottomTouched = true;
82755
+ this.horizontalRulerBottom.setAttribute('data-bottomTouched', 1);
82756
+ }
82757
+
82758
+ // block middle
82759
+ if (this.rulerTop === null && this.rulerBottom === null) {
82760
+ if (conMiddle - 4 <= middle && middle <= conMiddle + 4) {
82761
+ this.horizontalRulerMiddle.style.top = containerTop + conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
82762
+ let val = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2;
82763
+ if (this.rulerTop === null) this.rulerTop = val;
82764
+ }
82420
82765
  }
82766
+
82421
82767
  // block left
82768
+ this.verticalRulerLeft.removeAttribute('data-leftTouched');
82422
82769
  if (conLeft - 4 <= left && left <= conLeft + 4) {
82423
- this.verticalRulerLeft.style.left = conLeft + 2 + 'px'; // +3 is an adjustment
82424
- this.verticalRulerLeft.style.top = containerTop + 'px';
82770
+ this.verticalRulerLeft.style.left = conLeft + 0 + 'px'; // +0 is an adjustment
82771
+ this.verticalRulerLeft.style.top = containerTop + 'px'; // adj
82772
+
82425
82773
  let val = conLeft;
82426
82774
  if (this.rulerLeft === null) this.rulerLeft = val;
82775
+ this.verticalRulerLeft.setAttribute('data-leftTouched', 1);
82427
82776
  }
82777
+
82428
82778
  // block right
82779
+ this.verticalRulerRight.removeAttribute('data-rightTouched');
82429
82780
  if (conRight - 4 <= right && right <= conRight + 4) {
82430
82781
  this.verticalRulerRight.style.left = conRight - 2 + 'px'; // -2 is an adjustment
82431
- this.verticalRulerRight.style.top = containerTop + 'px';
82782
+ this.verticalRulerRight.style.top = containerTop + 'px'; // adj
82783
+
82432
82784
  let val = conRight;
82433
82785
  if (this.rulerRight === null) this.rulerRight = val;
82786
+ this.verticalRulerRight.setAttribute('data-rightTouched', 1);
82787
+ }
82788
+
82789
+ // block center
82790
+ if (this.rulerLeft === null && this.rulerRight === null) {
82791
+ if (conCenter - 4 <= center && center <= conCenter + 4) {
82792
+ this.verticalRulerCenter.style.left = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
82793
+ this.verticalRulerCenter.style.top = containerTop + 'px';
82794
+ let val = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2;
82795
+ if (this.rulerLeft === null) this.rulerLeft = val;
82796
+ }
82434
82797
  }
82435
82798
  }
82436
82799
  }
@@ -82905,38 +83268,129 @@ class Resizable {
82905
83268
  }
82906
83269
 
82907
83270
  // Replace with ruler's alignment
82908
- if (this.ruler.rulerTop !== null) {
82909
- target.style.top = this.ruler.rulerTop + 'px';
82910
- // if container has top/left
82911
- if (target.parentNode.matches(this.selector)) {
82912
- const containerRect = target.parentNode.getBoundingClientRect();
82913
- target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
83271
+
83272
+ if (this.resizeHandle.includes('top')) {
83273
+ if (this.ruler.rulerTop !== null) {
83274
+ //bottom fixed
83275
+ let targetBottom = target.offsetTop + target.offsetHeight;
83276
+ target.style.top = this.ruler.rulerTop + 'px';
83277
+ target.style.height = targetBottom - this.ruler.rulerTop + 'px';
82914
83278
  }
82915
83279
  }
82916
-
82917
- // If resizing by dragging the right corners (top or bottom)
82918
- if (this.resizeHandle === 'top-right' || this.resizeHandle === 'bottom-right' || this.resizeHandle === 'right') {
82919
- // Check if vertical right ruler visible (has value)
83280
+ if (this.resizeHandle.includes('bottom')) {
83281
+ if (this.ruler.rulerBottom !== null) {
83282
+ // top fixed
83283
+ target.style.height = this.ruler.rulerBottom - target.offsetTop + 'px';
83284
+ }
83285
+ }
83286
+ if (this.resizeHandle.includes('left')) {
83287
+ if (this.ruler.rulerLeft !== null) {
83288
+ //right fixed
83289
+ let targetRight = target.offsetLeft + target.offsetWidth;
83290
+ target.style.left = this.ruler.rulerLeft + 'px';
83291
+ target.style.width = targetRight - this.ruler.rulerLeft + 'px';
83292
+ }
83293
+ }
83294
+ if (this.resizeHandle.includes('right')) {
82920
83295
  if (this.ruler.rulerRight !== null) {
82921
- // If so, keep the left position
82922
- // target.style.left = newLeft + 'px';
83296
+ //left fixed
83297
+ target.style.width = this.ruler.rulerRight - target.offsetLeft + 'px';
83298
+ }
83299
+ }
82923
83300
 
82924
- // And update the width to align with vertical right ruler
82925
- const rect = target.getBoundingClientRect();
82926
- target.style.width = this.ruler.rulerRight - rect.left + 'px';
83301
+ // Convert px to %
83302
+ this.common.applyPercentage(target);
83303
+ setTimeout(() => {
83304
+ const breakpoint = this.doc.body.getAttribute('data-breakpoint');
83305
+
83306
+ // const screenWidth = window.innerWidth;
83307
+ // let defaultPoint;
83308
+ // if(screenWidth<=1920) {
83309
+ // defaultPoint = 1366;
83310
+ // } else {
83311
+ // defaultPoint = 1900;
83312
+ // }
83313
+
83314
+ let largeScreenBreakpoint = 1280; //1920
83315
+ largeScreenBreakpoint = window.innerWidth - 360; //351
83316
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
83317
+ let isPrint = false;
83318
+ let elmBox = target.closest('[data-pagesize]');
83319
+ if (elmBox) {
83320
+ if (elmBox.getAttribute('data-pagesize').includes('web')) ; else {
83321
+ isPrint = true;
83322
+ }
82927
83323
  }
82928
- } else if (this.resizeHandle === 'top-left' || this.resizeHandle === 'bottom-left' || this.resizeHandle === 'left') {
82929
- if (this.ruler.rulerLeft !== null) {
82930
- const currentRight = this.initialLeft + this.initialWidth;
83324
+ if (isPrint) {
83325
+ target.setAttribute('data--t', target.style.top);
83326
+ target.setAttribute('data--l', target.style.left);
83327
+ target.setAttribute('data--b', target.style.bottom);
83328
+ target.setAttribute('data--r', target.style.right);
83329
+ target.setAttribute('data--w', target.style.width);
83330
+ target.setAttribute('data--h', target.style.height);
83331
+ } else {
83332
+ if (breakpoint && breakpoint < largeScreenBreakpoint) {
83333
+ target.setAttribute('data--t-' + breakpoint, target.style.top);
83334
+ target.setAttribute('data--l-' + breakpoint, target.style.left);
83335
+ target.setAttribute('data--b-' + breakpoint, target.style.bottom);
83336
+ target.setAttribute('data--r-' + breakpoint, target.style.right);
83337
+ if (!target.classList.contains('fluid')) target.setAttribute('data--w-' + breakpoint, target.style.width);
83338
+ target.setAttribute('data--h-' + breakpoint, target.style.height);
83339
+ } else {
83340
+ target.setAttribute('data--t', target.style.top);
83341
+ target.setAttribute('data--l', target.style.left);
83342
+ target.setAttribute('data--b', target.style.bottom);
83343
+ target.setAttribute('data--r', target.style.right);
83344
+ target.setAttribute('data--w', target.style.width);
83345
+ target.setAttribute('data--h', target.style.height);
83346
+ }
83347
+ }
83348
+ target.removeAttribute('data-prev'); // reset
83349
+ target.removeAttribute('data-fluid');
83350
+ }, 30); // delay needed since we use updateHeight() previously that has 20ms process
82931
83351
 
82932
- // if container has top/left
82933
- const containerRect = target.parentNode.getBoundingClientRect();
82934
- this.ruler.rulerLeft = this.ruler.rulerLeft - containerRect.left;
83352
+ if (this.onChange) this.onChange();
83353
+ }
83354
+ updateBlockStyle_bak(target) {
83355
+ if (target.querySelector(this.selector)) ; else {
83356
+ // this.common.updateHeight(target);
83357
+ if (target.classList.contains('height-auto')) target.style.height = '';
83358
+ }
82935
83359
 
82936
- // And update the width to align with vertical left ruler
82937
- target.style.left = this.ruler.rulerLeft + 'px';
82938
- let newWidth = currentRight - this.ruler.rulerLeft;
82939
- target.style.width = newWidth + 'px';
83360
+ // Replace with ruler's alignment
83361
+ const containerRect = this.common.getRect(target.parentNode); // if container has top/left
83362
+
83363
+ if (this.resizeHandle.includes('top')) {
83364
+ if (this.ruler.rulerTop !== null) {
83365
+ //bottom fixed
83366
+ const rect = target.getBoundingClientRect();
83367
+ let targetBottom = rect.top + rect.height;
83368
+ target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
83369
+ target.style.height = targetBottom - this.ruler.rulerTop + 'px';
83370
+ }
83371
+ }
83372
+ if (this.resizeHandle.includes('bottom')) {
83373
+ if (this.ruler.rulerBottom !== null) {
83374
+ // top fixed
83375
+ // const rect = target.getBoundingClientRect();
83376
+ // target.style.height = this.ruler.rulerBottom - rect.top + containerRect.top + 'px';
83377
+ target.style.height = this.ruler.rulerBottom - target.offsetTop + 'px';
83378
+ }
83379
+ }
83380
+ if (this.resizeHandle.includes('left')) {
83381
+ if (this.ruler.rulerLeft !== null) {
83382
+ //right fixed
83383
+ const rect = target.getBoundingClientRect();
83384
+ let targetRight = rect.left + rect.width;
83385
+ target.style.left = this.ruler.rulerLeft - containerRect.left + 'px';
83386
+ target.style.width = targetRight - this.ruler.rulerLeft + 'px';
83387
+ }
83388
+ }
83389
+ if (this.resizeHandle.includes('right')) {
83390
+ if (this.ruler.rulerRight !== null) {
83391
+ //left fixed
83392
+ const rect = target.getBoundingClientRect();
83393
+ target.style.width = this.ruler.rulerRight - rect.left + 'px';
82940
83394
  }
82941
83395
  }
82942
83396
 
@@ -82953,8 +83407,9 @@ class Resizable {
82953
83407
  // defaultPoint = 1900;
82954
83408
  // }
82955
83409
 
82956
- const largeScreenBreakpoint = 1920; //1920
82957
-
83410
+ let largeScreenBreakpoint = 1280; //1920
83411
+ largeScreenBreakpoint = window.innerWidth - 360; //351
83412
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
82958
83413
  let isPrint = false;
82959
83414
  let elmBox = target.closest('[data-pagesize]');
82960
83415
  if (elmBox) {
@@ -83138,6 +83593,10 @@ class Draggable {
83138
83593
  const y = startY - rect.top + containerRect.top;
83139
83594
  target.setAttribute('data-startx', x);
83140
83595
  target.setAttribute('data-starty', y);
83596
+
83597
+ // reset (from applyPercentage bottomTouched)
83598
+ target.style.height = target.offsetHeight + 'px';
83599
+ target.style.bottom = '';
83141
83600
  this.common.applyPixels(target);
83142
83601
  });
83143
83602
  this.clickedBlock = this.common.getSelectedBlock();
@@ -83205,10 +83664,9 @@ class Draggable {
83205
83664
  }
83206
83665
  updateBlockStyle(target) {
83207
83666
  // Replace with ruler's alignment
83208
- const containerRect = this.common.getRect(target.parentNode); // if container has top/left
83209
- const initialWidth = parseFloat(getComputedStyle(target).width);
83210
- if (this.ruler.rulerTop !== null) target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
83211
- if (this.ruler.rulerLeft !== null) target.style.left = this.ruler.rulerLeft - containerRect.left + 'px';else if (this.ruler.rulerRight !== null) target.style.left = this.ruler.rulerRight - initialWidth - containerRect.left + 'px';
83667
+ if (this.ruler.rulerTop !== null) target.style.top = this.ruler.rulerTop + 'px';
83668
+ if (this.ruler.rulerBottom !== null) target.style.top = this.ruler.rulerBottom - target.offsetHeight + 'px'; //new
83669
+ if (this.ruler.rulerLeft !== null) target.style.left = this.ruler.rulerLeft + 'px';else if (this.ruler.rulerRight !== null) target.style.left = this.ruler.rulerRight - target.offsetWidth + 'px';
83212
83670
  this.doc.querySelectorAll('[data-startx]').forEach(elm => elm.removeAttribute('data-startx'));
83213
83671
  this.doc.querySelectorAll('[data-starty]').forEach(elm => elm.removeAttribute('data-starty'));
83214
83672
  this.common.applyPercentage(target);
@@ -83222,8 +83680,9 @@ class Draggable {
83222
83680
  // defaultPoint = 1900;
83223
83681
  // }
83224
83682
 
83225
- const largeScreenBreakpoint = 1920; //1920
83226
-
83683
+ let largeScreenBreakpoint = 1280; //1920
83684
+ largeScreenBreakpoint = window.innerWidth - 360; //351
83685
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
83227
83686
  let isPrint = false;
83228
83687
  let elmBox = target.closest('[data-pagesize]');
83229
83688
  if (elmBox) {
@@ -83898,6 +84357,9 @@ class EditableBlocks {
83898
84357
  win: this.win,
83899
84358
  onContentClick: this.onContentClick,
83900
84359
  onEditStart: (event, block) => {
84360
+ const container = block.querySelector('.is-container');
84361
+ if (!container) return; // if block is empty, no edit required
84362
+
83901
84363
  if (block.classList.contains('clone')) {
83902
84364
  const clonedTarget = this.doc.querySelector(this.selector + '.cloned');
83903
84365
  this.onEditStart(event, clonedTarget);
@@ -84068,133 +84530,181 @@ class BlockModal {
84068
84530
  </div>
84069
84531
  </div>
84070
84532
 
84533
+ <div class="label-page-grayscale label checkbox grayscale" style="padding:30px 0 10px;">
84534
+ <label class="label-checkbox" for="chkPageGrayscale"><input id="chkPageGrayscale" class="chk-grayscale" type="checkbox" /> ${util.out('Grayscale')}</label>
84535
+ </div>
84536
+
84537
+ <div style="padding-top:30px;padding-bottom:3px;">${util.out('Auto layout on mobile')}:</div>
84538
+
84539
+ <label class="switch"><input id="inpAutoLayout" type="checkbox" checked=""><span class="slider round"></span></label>
84540
+
84071
84541
  </div>
84072
84542
 
84073
- <div class="modal-content">
84543
+ <div class="modal-content" style="padding:0">
84074
84544
 
84075
- <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
84076
- <div style="display:flex;">
84077
- <button title="${util.out('Background Color')}" class="input-block-bgcolor is-btn-color" style="margin-right:15px"></button>
84078
- <button title="${util.out('Gradient')}" class="btn-block-gradient classic" data-value="+"> ${util.out('Gradient')} </button>
84545
+ <div class="is-tabs" data-group="blocksettings" style="background-color:transparent">
84546
+ <a title="${util.out('General')}" id="tabBlockGeneral" href="#" data-content="divBlockGeneral" class="active">${util.out('General')}</a>
84547
+ <a title="${util.out('More')}" id="tabBlockMore" href="#" data-content="divBlockMore">${util.out('More')}</a>
84079
84548
  </div>
84080
84549
 
84081
- <div style="padding-top:20px;padding-bottom: 3px;">${util.out('Background Image')}:</div>
84082
- <div>
84083
- <div class="asset-block-preview" style="display:none"></div>
84084
- <div style="display: flex">
84085
- <button title="${util.out('Image')}" class="btn-block-bgimage">
84086
- <svg class="is-icon-flex"><use xlink:href="#ion-image"></use></svg>
84087
- <span>${util.out('Image')}</span>
84550
+ <div id="divBlockMore" class="is-tab-content" data-group="blocksettings" tabindex="-1" style="padding:25px 25px 28px">
84551
+
84552
+ <div class="div-target" style="display: flex;justify-content: flex-end;padding: 5px 0 0;">
84553
+ <button title="${util.out('Desktop')}" class="input-device on" data-value="" style="width:40px;height:25px;">
84554
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-device-desktop"></use></svg>
84555
+ </button>
84556
+ <button title="${util.out('Laptop/Tablet (Landscape)')}" class="input-device" data-value="md" style="width:40px;height:25px;">
84557
+ <svg class="is-icon-flex" style="width:16px;height:16px;transform:rotate(-90deg)"><use xlink:href="#icon-device-tablet"></use></svg>
84558
+ </button>
84559
+ <button title="${util.out('Tablet (Portrait)')}" class="input-device" data-value="sm" style="width:40px;height:25px;">
84560
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-device-tablet"></use></svg>
84561
+ </button>
84562
+ <button title="${util.out('Mobile')}" class="input-device" data-value="xs" style="width:40px;height:25px;">
84563
+ <svg class="is-icon-flex" style="width:13px;height:13px"><use xlink:href="#icon-device-mobile"></use></svg>
84088
84564
  </button>
84089
- <button title="${util.out('Select')}" class="btn-block-asset">${this.builder.opts.selectIcon}</button>
84090
- <button title="${util.out('Remove')}" class="btn-block-clear"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#icon-clean"></use></svg></button>
84091
- <button title="${util.out('Adjust')}" class="btn-block-adjust" style="width:40px"><svg class="is-icon-flex"><use xlink:href="#ion-wrench"></use></svg></button>
84092
84565
  </div>
84093
- </div>
84094
84566
 
84095
- <div class="div-content-textcolor flex flex-col">
84096
- <div style="padding-top:20px;padding-bottom:3px;">${util.out('Text Color')}:</div>
84097
- <div class="flex flex-row">
84098
- <button title="0" data-textcolor="dark">${util.out('Dark')}</button>
84099
- <button title="10" data-textcolor="light">${util.out('Light')}</button>
84100
-
84101
- <button title="${util.out('Clear')}" data-textcolor=""><svg class="is-icon-flex" style="flex:none;width:18px;height:18px;margin-top: 2px;"><use xlink:href="#ion-ios-close-empty"></use></svg></button>
84567
+ <div style="padding-top:0;padding-bottom:3px;">${util.out('Visibility')}:</div>
84568
+ <div class="div-visibility" style="display:flex;">
84569
+ <button title="${util.out('Visible')}" class="input-visible on" data-value="sm" style="width:100px;height:34px;">
84570
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-eye"></use></svg>
84571
+ <span>${util.out('Visible')}</span>
84572
+ </button>
84573
+ <button title="${util.out('Hidden')}" class="input-hidden" data-value="xs" style="width:100px;height:34px;">
84574
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-eye-off"></use></svg>
84575
+ <span>${util.out('Hidden')}</span>
84576
+ </button>
84102
84577
  </div>
84578
+
84103
84579
  </div>
84104
84580
 
84105
- <div class="label checkbox grayscale" style="padding:30px 0 10px;">
84106
- <label class="label-block-grayscale label-checkbox" for="chkBlockGrayscale"><input id="chkBlockGrayscale" class="chk-grayscale" type="checkbox" /> ${util.out('Grayscale')}</label>
84107
- </div>
84581
+ <div id="divBlockGeneral" class="is-tab-content active" data-group="blocksettings" style="display:flex" tabindex="-1" style="padding:25px 25px 28px">
84108
84582
 
84109
- <button title="${util.out('Remove Content/Text')}" class="btn-clear-text" style="margin-top:20px">
84110
- <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
84111
- <span>${util.out('Remove Content/Text')}</span>
84112
- </button>
84583
+ <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
84584
+ <div style="display:flex;">
84585
+ <button title="${util.out('Background Color')}" class="input-block-bgcolor is-btn-color" style="margin-right:15px"></button>
84586
+ <button title="${util.out('Gradient')}" class="btn-block-gradient classic" data-value="+"> ${util.out('Gradient')} </button>
84587
+ </div>
84113
84588
 
84114
- <button title="${util.out('Clear Breakpoints')}" class="btn-clear-breakpoint" style="margin-top:20px">
84115
- <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
84116
- <span>${util.out('Clear Breakpoints')}</span>
84117
- </button>
84589
+ <div style="padding-top:20px;padding-bottom: 3px;">${util.out('Background Image')}:</div>
84590
+ <div>
84591
+ <div class="asset-block-preview" style="display:none"></div>
84592
+ <div style="display: flex">
84593
+ <button title="${util.out('Image')}" class="btn-block-bgimage">
84594
+ <svg class="is-icon-flex"><use xlink:href="#ion-image"></use></svg>
84595
+ <span>${util.out('Image')}</span>
84596
+ </button>
84597
+ <button title="${util.out('Select')}" class="btn-block-asset">${this.builder.opts.selectIcon}</button>
84598
+ <button title="${util.out('Remove')}" class="btn-block-clear"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#icon-clean"></use></svg></button>
84599
+ <button title="${util.out('Adjust')}" class="btn-block-adjust" style="width:40px"><svg class="is-icon-flex"><use xlink:href="#ion-wrench"></use></svg></button>
84600
+ </div>
84601
+ </div>
84118
84602
 
84119
- <div style="padding-top:23px;padding-bottom:3px;">${util.out('Lock')}:</div>
84603
+ <div class="div-content-textcolor flex flex-col">
84604
+ <div style="padding-top:20px;padding-bottom:3px;">${util.out('Text Color')}:</div>
84605
+ <div class="flex flex-row">
84606
+ <button title="0" data-textcolor="dark">${util.out('Dark')}</button>
84607
+ <button title="10" data-textcolor="light">${util.out('Light')}</button>
84608
+
84609
+ <button title="${util.out('Clear')}" data-textcolor=""><svg class="is-icon-flex" style="flex:none;width:18px;height:18px;margin-top: 2px;"><use xlink:href="#ion-ios-close-empty"></use></svg></button>
84610
+ </div>
84611
+ </div>
84120
84612
 
84121
- <label class="switch"><input id="inpLockBlock" type="checkbox" checked=""><span class="slider round"></span></label>
84613
+ <div class="label-block-grayscale label checkbox grayscale" style="padding:30px 0 10px;">
84614
+ <label class="label-checkbox" for="chkBlockGrayscale"><input id="chkBlockGrayscale" class="chk-grayscale" type="checkbox" /> ${util.out('Grayscale')}</label>
84615
+ </div>
84122
84616
 
84123
- <div id="divBlockPos">
84617
+ <button title="${util.out('Remove Content/Text')}" class="btn-clear-text" style="margin-top:20px">
84618
+ <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
84619
+ <span>${util.out('Remove Content/Text')}</span>
84620
+ </button>
84124
84621
 
84125
- <div class="flex" style="gap:10px">
84126
- <div>
84127
- <label for="inpBlockTop" class="flex" style="padding:10px 0 3px;">${util.out('Top')}:</label>
84128
- <div style="display:flex">
84129
- <input id="inpBlockTop" class="inp-block-top" type="text" style="width:74px;height:35px">
84130
- <select id="inpBlockTopUnit">
84131
- <option></option>
84132
- <option>px</option>
84133
- <option>%</option>
84134
- </select>
84622
+ <button title="${util.out('Clear Breakpoints')}" class="btn-clear-breakpoint" style="margin-top:20px">
84623
+ <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
84624
+ <span>${util.out('Clear Breakpoints')}</span>
84625
+ </button>
84626
+
84627
+ <div style="padding-top:23px;padding-bottom:3px;">${util.out('Lock')}:</div>
84628
+
84629
+ <label class="switch"><input id="inpLockBlock" type="checkbox" checked=""><span class="slider round"></span></label>
84630
+
84631
+ <div id="divBlockPos">
84632
+
84633
+ <div class="flex" style="gap:10px">
84634
+ <div>
84635
+ <label for="inpBlockTop" class="flex" style="padding:10px 0 3px;">${util.out('Top')}:</label>
84636
+ <div style="display:flex">
84637
+ <input id="inpBlockTop" class="inp-block-top" type="text" style="width:74px;height:35px">
84638
+ <select id="inpBlockTopUnit">
84639
+ <option></option>
84640
+ <option>px</option>
84641
+ <option>%</option>
84642
+ </select>
84643
+ </div>
84135
84644
  </div>
84136
- </div>
84137
- <div>
84138
- <label for="inpBlockBottom" class="flex" style="padding:10px 0 3px;">${util.out('Bottom')}:</label>
84139
- <div style="display:flex">
84140
- <input id="inpBlockBottom" class="inp-block-top" type="text" style="width:74px;height:35px">
84141
- <select id="inpBlockBottomUnit">
84142
- <option></option>
84143
- <option>px</option>
84144
- <option>%</option>
84145
- </select>
84645
+ <div>
84646
+ <label for="inpBlockBottom" class="flex" style="padding:10px 0 3px;">${util.out('Bottom')}:</label>
84647
+ <div style="display:flex">
84648
+ <input id="inpBlockBottom" class="inp-block-top" type="text" style="width:74px;height:35px">
84649
+ <select id="inpBlockBottomUnit">
84650
+ <option></option>
84651
+ <option>px</option>
84652
+ <option>%</option>
84653
+ </select>
84654
+ </div>
84146
84655
  </div>
84147
84656
  </div>
84148
- </div>
84149
84657
 
84150
- <div class="flex" style="gap:10px">
84151
- <div>
84152
- <label for="inpBlockLeft" class="flex" style="padding:10px 0 3px;">${util.out('Left')}:</label>
84153
- <div style="display:flex">
84154
- <input id="inpBlockLeft" class="inp-block-left" type="text" style="width:74px;height:35px">
84155
- <select id="inpBlockLeftUnit">
84156
- <option></option>
84157
- <option>px</option>
84158
- <option>%</option>
84159
- </select>
84658
+ <div class="flex" style="gap:10px">
84659
+ <div>
84660
+ <label for="inpBlockLeft" class="flex" style="padding:10px 0 3px;">${util.out('Left')}:</label>
84661
+ <div style="display:flex">
84662
+ <input id="inpBlockLeft" class="inp-block-left" type="text" style="width:74px;height:35px">
84663
+ <select id="inpBlockLeftUnit">
84664
+ <option></option>
84665
+ <option>px</option>
84666
+ <option>%</option>
84667
+ </select>
84668
+ </div>
84160
84669
  </div>
84161
- </div>
84162
- <div>
84163
- <label for="inpBlockRight" class="flex" style="padding:10px 0 3px;">${util.out('Right')}:</label>
84164
- <div style="display:flex">
84165
- <input id="inpBlockRight" class="inp-block-left" type="text" style="width:74px;height:35px">
84166
- <select id="inpBlockRightUnit">
84167
- <option></option>
84168
- <option>px</option>
84169
- <option>%</option>
84170
- </select>
84670
+ <div>
84671
+ <label for="inpBlockRight" class="flex" style="padding:10px 0 3px;">${util.out('Right')}:</label>
84672
+ <div style="display:flex">
84673
+ <input id="inpBlockRight" class="inp-block-left" type="text" style="width:74px;height:35px">
84674
+ <select id="inpBlockRightUnit">
84675
+ <option></option>
84676
+ <option>px</option>
84677
+ <option>%</option>
84678
+ </select>
84679
+ </div>
84171
84680
  </div>
84172
84681
  </div>
84173
- </div>
84174
84682
 
84175
- <div class="flex" style="gap:10px">
84176
- <div>
84177
- <label for="inpBlockWidth" class="flex" style="padding:10px 0 3px;">${util.out('Width')}:</label>
84178
- <div style="display:flex">
84179
- <input id="inpBlockWidth" class="inp-block-left" type="text" style="width:74px;height:35px">
84180
- <select id="inpBlockWidthUnit">
84181
- <option></option>
84182
- <option>px</option>
84183
- <option>%</option>
84184
- </select>
84683
+ <div class="flex" style="gap:10px">
84684
+ <div>
84685
+ <label for="inpBlockWidth" class="flex" style="padding:10px 0 3px;">${util.out('Width')}:</label>
84686
+ <div style="display:flex">
84687
+ <input id="inpBlockWidth" class="inp-block-left" type="text" style="width:74px;height:35px">
84688
+ <select id="inpBlockWidthUnit">
84689
+ <option></option>
84690
+ <option>px</option>
84691
+ <option>%</option>
84692
+ </select>
84693
+ </div>
84185
84694
  </div>
84186
- </div>
84187
- <div>
84188
- <label for="inpBlockHeight" class="flex" style="padding:10px 0 3px;">${util.out('Height')}:</label>
84189
- <div style="display:flex">
84190
- <input id="inpBlockHeight" class="inp-block-left" type="text" style="width:74px;height:35px">
84191
- <select id="inpBlockHeightUnit">
84192
- <option></option>
84193
- <option>px</option>
84194
- <option>%</option>
84195
- </select>
84695
+ <div>
84696
+ <label for="inpBlockHeight" class="flex" style="padding:10px 0 3px;">${util.out('Height')}:</label>
84697
+ <div style="display:flex">
84698
+ <input id="inpBlockHeight" class="inp-block-left" type="text" style="width:74px;height:35px">
84699
+ <select id="inpBlockHeightUnit">
84700
+ <option></option>
84701
+ <option>px</option>
84702
+ <option>%</option>
84703
+ </select>
84704
+ </div>
84196
84705
  </div>
84197
84706
  </div>
84707
+
84198
84708
  </div>
84199
84709
 
84200
84710
  </div>
@@ -84296,19 +84806,19 @@ class BlockModal {
84296
84806
  const btnPageBgImage = modal.querySelector('.btn-page-bgimage');
84297
84807
  if (btnPageBgImage) dom.addEventListener(btnPageBgImage, 'click', () => {
84298
84808
  // Background image
84299
- const page = this.getPage();
84809
+ let pageOverlay = this.pageOverlay();
84300
84810
  let src = '';
84301
- if (page) if (page.style.backgroundImage) {
84302
- if (page.style.backgroundImage.indexOf('url(') !== -1) {
84303
- src = page.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
84811
+ if (pageOverlay) if (pageOverlay.style.backgroundImage) {
84812
+ if (pageOverlay.style.backgroundImage.indexOf('url(') !== -1) {
84813
+ src = pageOverlay.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
84304
84814
  }
84305
84815
  }
84306
84816
  this.openImagePicker(src, url => {
84307
- const page = this.getPage();
84817
+ let pageOverlay = this.pageOverlay();
84308
84818
  this.builder.uo.saveForUndo();
84309
- page.style.backgroundImage = `url("${url}")`;
84310
- page.style.backgroundSize = 'cover';
84311
- page.style.backgroundRepeat = 'no-repeat';
84819
+ pageOverlay.style.backgroundImage = `url("${url}")`;
84820
+ pageOverlay.style.backgroundSize = 'cover';
84821
+ pageOverlay.style.backgroundRepeat = 'no-repeat';
84312
84822
  const div = this.pageImagePreview;
84313
84823
  const btnPageAdjust = modal.querySelector('.btn-page-adjust');
84314
84824
  const btnPageClear = modal.querySelector('.btn-page-clear');
@@ -84339,9 +84849,43 @@ class BlockModal {
84339
84849
  });
84340
84850
  const btnPageAdjust = modal.querySelector('.btn-page-adjust');
84341
84851
  btnPageAdjust.addEventListener('click', () => {
84342
- let page = this.getPage();
84343
- this.builder.colTool.openImageAdjust(page, btnPageAdjust);
84852
+ let pageOverlay = this.pageOverlay();
84853
+ this.builder.colTool.openImageAdjust(pageOverlay, btnPageAdjust);
84344
84854
  });
84855
+ const chkPageGrayscale = modal.querySelector('#chkPageGrayscale');
84856
+ chkPageGrayscale.addEventListener('click', () => {
84857
+ this.builder.uo.saveForUndo();
84858
+ let pageOverlay = this.pageOverlay();
84859
+ const checked = chkPageGrayscale.checked;
84860
+ if (checked) {
84861
+ pageOverlay.style.filter = 'grayscale(1)';
84862
+ } else {
84863
+ if (pageOverlay.style.filter) pageOverlay.style.filter = pageOverlay.style.filter.replace('grayscale(1)', '');
84864
+ }
84865
+ this.builder.onChange();
84866
+ });
84867
+
84868
+ // Page Auto Layout
84869
+ const chkAutoLayout = modal.querySelector('#inpAutoLayout');
84870
+ chkAutoLayout.addEventListener(this.builder.isTouchSupport ? 'touchstart' : 'click', () => {
84871
+ const page = this.getPage();
84872
+ if (chkAutoLayout.checked) {
84873
+ page.classList.add('autolayout');
84874
+ } else {
84875
+ page.classList.remove('autolayout');
84876
+ }
84877
+ });
84878
+ if (this.builder.isTouchSupport) {
84879
+ let chkAutoLayoutLabel = chkAutoLayout.parentNode;
84880
+ chkAutoLayoutLabel.addEventListener('touchstart', () => {
84881
+ const page = this.getPage();
84882
+ if (chkAutoLayout.checked) {
84883
+ page.classList.add('autolayout');
84884
+ } else {
84885
+ page.classList.remove('autolayout');
84886
+ }
84887
+ });
84888
+ }
84345
84889
 
84346
84890
  // Block Background Image
84347
84891
 
@@ -84395,7 +84939,7 @@ class BlockModal {
84395
84939
  let blockOverlay = this.blockOverlay();
84396
84940
  this.builder.colTool.openImageAdjust(blockOverlay, btnAdjust);
84397
84941
  });
84398
- const chkGrayscale = modal.querySelector('.chk-grayscale');
84942
+ const chkGrayscale = modal.querySelector('#chkBlockGrayscale');
84399
84943
  chkGrayscale.addEventListener('click', () => {
84400
84944
  this.builder.uo.saveForUndo();
84401
84945
  let blockOverlay = this.blockOverlay();
@@ -84622,6 +85166,62 @@ class BlockModal {
84622
85166
  }
84623
85167
  });
84624
85168
  }
85169
+
85170
+ // Responsive Visibility
85171
+
85172
+ let btns = modal.querySelectorAll('.input-device');
85173
+ btns.forEach(btn => {
85174
+ btn.addEventListener('click', () => {
85175
+ const block = this.blockSelected();
85176
+ let elms = modal.querySelectorAll('.input-device');
85177
+ elms.forEach(elm => {
85178
+ elm.classList.remove('on');
85179
+ });
85180
+ btn.classList.add('on');
85181
+ this.realtimeVisibility(block);
85182
+ });
85183
+ });
85184
+ let btnVisible = modal.querySelector('.input-visible');
85185
+ let btnHidden = modal.querySelector('.input-hidden');
85186
+ btnVisible.addEventListener('click', () => {
85187
+ const block = this.blockSelected();
85188
+ this.builder.uo.saveForUndo();
85189
+ let divTarget = modal.querySelector('.div-target');
85190
+ let target = this.builder.responsive.readTarget(divTarget);
85191
+ if (target === 'xs') {
85192
+ block.classList.remove('xs-hidden');
85193
+ } else if (target === 'sm') {
85194
+ block.classList.remove('sm-hidden');
85195
+ } else if (target === 'md') {
85196
+ block.classList.remove('md-hidden');
85197
+ } else if (target === '') {
85198
+ block.classList.remove('desktop-hidden');
85199
+ }
85200
+ btnVisible.classList.add('on');
85201
+ btnHidden.classList.remove('on');
85202
+ this.builder.opts.onChange();
85203
+ });
85204
+ btnHidden.addEventListener('click', () => {
85205
+ const block = this.blockSelected();
85206
+ this.builder.uo.saveForUndo();
85207
+ let divTarget = modal.querySelector('.div-target');
85208
+ let target = this.builder.responsive.readTarget(divTarget);
85209
+ if (target === 'xs') {
85210
+ block.classList.add('xs-hidden');
85211
+ } else if (target === 'sm') {
85212
+ block.classList.add('sm-hidden');
85213
+ } else if (target === 'md') {
85214
+ block.classList.add('md-hidden');
85215
+ } else if (target === '') {
85216
+ block.classList.add('desktop-hidden');
85217
+ }
85218
+ btnVisible.classList.remove('on');
85219
+ btnHidden.classList.add('on');
85220
+ this.builder.opts.onChange();
85221
+ });
85222
+ new Tabs({
85223
+ element: modal
85224
+ });
84625
85225
  } // constructor
84626
85226
 
84627
85227
  getPage() {
@@ -84653,6 +85253,16 @@ class BlockModal {
84653
85253
  // this.builder.eb.common.applyPercentage(target);
84654
85254
  }
84655
85255
 
85256
+ pageOverlay() {
85257
+ const page = this.getPage();
85258
+ if (!page) return false;
85259
+ let pageOverlay = page.querySelector('.is-page-overlay');
85260
+ if (!pageOverlay) {
85261
+ page.insertAdjacentHTML('afterbegin', '<div class="is-page-overlay"></div>');
85262
+ pageOverlay = page.querySelector('.is-page-overlay');
85263
+ }
85264
+ return pageOverlay;
85265
+ }
84656
85266
  blockOverlay() {
84657
85267
  const block = this.builder.doc.querySelector('.is-block.active:not(.multi)');
84658
85268
  if (!block) return false;
@@ -84669,6 +85279,7 @@ class BlockModal {
84669
85279
  }
84670
85280
  realtime() {
84671
85281
  const modal = this.modal;
85282
+ if (!modal.classList.contains('active')) return;
84672
85283
  const page = this.getPage();
84673
85284
  const block = this.blockSelected();
84674
85285
  if (block) {
@@ -84711,7 +85322,7 @@ class BlockModal {
84711
85322
  }
84712
85323
 
84713
85324
  // Grayscale
84714
- const chkGrayscale = modal.querySelector('.chk-grayscale');
85325
+ const chkGrayscale = modal.querySelector('#chkBlockGrayscale');
84715
85326
  chkGrayscale.checked = false;
84716
85327
  if (blockOverlay) {
84717
85328
  if (blockOverlay.style.filter) {
@@ -84862,23 +85473,38 @@ class BlockModal {
84862
85473
  inpHeight.value = '';
84863
85474
  inpHeightUnit.value = '%';
84864
85475
  }
85476
+ this.realtimeVisibility(block);
84865
85477
  } else if (page) {
85478
+ let pageOverlay = this.pageOverlay();
85479
+
84866
85480
  // Background image
84867
85481
  let src = '';
84868
- if (page) if (page.style.backgroundImage) {
84869
- if (page.style.backgroundImage.indexOf('url(') !== -1) {
84870
- src = page.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
85482
+ if (pageOverlay) if (pageOverlay.style.backgroundImage) {
85483
+ if (pageOverlay.style.backgroundImage.indexOf('url(') !== -1) {
85484
+ src = pageOverlay.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
84871
85485
  }
84872
85486
  }
84873
85487
 
84874
85488
  // Update preview
84875
85489
  this.updatePanelPageImage(src);
84876
85490
 
84877
- // Show/hide
85491
+ // Show/hide grayscale
85492
+ const divPageGrayscale = modal.querySelector('.label-page-grayscale');
84878
85493
  if (src === '') {
84879
85494
  this.pageImagePreview.style.display = 'none';
85495
+ divPageGrayscale.style.display = 'none';
84880
85496
  } else {
84881
85497
  this.pageImagePreview.style.display = '';
85498
+ divPageGrayscale.style.display = '';
85499
+ }
85500
+
85501
+ // Grayscale
85502
+ const chkPageGrayscale = modal.querySelector('#chkPageGrayscale');
85503
+ chkPageGrayscale.checked = false;
85504
+ if (pageOverlay.style.filter) {
85505
+ if (pageOverlay.style.filter.indexOf('grayscale') !== -1) {
85506
+ chkPageGrayscale.checked = true;
85507
+ }
84882
85508
  }
84883
85509
 
84884
85510
  // Background color
@@ -84901,6 +85527,58 @@ class BlockModal {
84901
85527
  } else {
84902
85528
  btnPageGradient.style.backgroundImage = '';
84903
85529
  }
85530
+
85531
+ // Page Auto Layout
85532
+ const chkAutoLayout = modal.querySelector('#inpAutoLayout');
85533
+ if (page.classList.contains('autolayout')) {
85534
+ chkAutoLayout.checked = true;
85535
+ } else {
85536
+ chkAutoLayout.checked = false;
85537
+ }
85538
+ }
85539
+ }
85540
+ realtimeVisibility(row, initialOpen) {
85541
+ if (!this.modal) return;
85542
+ if (initialOpen) {
85543
+ const builderStuff = this.builder.builderStuff;
85544
+ const modal = builderStuff.querySelector('.is-modal.content-preview.active');
85545
+ if (modal) {
85546
+ let elms = this.modal.querySelectorAll('.input-device');
85547
+ elms.forEach(elm => {
85548
+ elm.classList.remove('on');
85549
+ });
85550
+ if (modal.classList.contains('is-screen-1920')) {
85551
+ this.modal.querySelector('.input-device[data-value=""]').classList.add('on');
85552
+ } else if (modal.classList.contains('is-screen-1440')) {
85553
+ this.modal.querySelector('.input-device[data-value=""]').classList.add('on');
85554
+ } else if (modal.classList.contains('is-screen-1024')) {
85555
+ this.modal.querySelector('.input-device[data-value="md"]').classList.add('on');
85556
+ } else if (modal.classList.contains('is-screen-768')) {
85557
+ this.modal.querySelector('.input-device[data-value="sm"]').classList.add('on');
85558
+ } else if (modal.classList.contains('is-screen-375')) {
85559
+ this.modal.querySelector('.input-device[data-value="xs"]').classList.add('on');
85560
+ }
85561
+ }
85562
+ }
85563
+ let divTarget = this.modal.querySelector('.div-target');
85564
+ let divVisibility = this.modal.querySelector('.div-visibility');
85565
+ let target = this.builder.responsive.readTarget(divTarget);
85566
+ let valVisibility = this.builder.responsive.getVisibility(row, target);
85567
+ this.builder.responsive.showVisibility(divVisibility, valVisibility);
85568
+
85569
+ // const divColsPerLine = this.modal.querySelector('.div-colsperline');
85570
+ let btns = this.modal.querySelectorAll('.input-colsperline');
85571
+ btns.forEach(btn => {
85572
+ btn.classList.remove('on');
85573
+ });
85574
+ if (target === 'xs') {
85575
+ if (!initialOpen) this.builder.livePreview.resizePreview(375);
85576
+ } else if (target === 'sm') {
85577
+ if (!initialOpen) this.builder.livePreview.resizePreview(768);
85578
+ } else if (target === 'md') {
85579
+ if (!initialOpen) this.builder.livePreview.resizePreview(1024);
85580
+ } else {
85581
+ if (!initialOpen) this.builder.livePreview.resizePreview(1920);
84904
85582
  }
84905
85583
  }
84906
85584
  openImagePicker(currentUrl, callback, btn) {
@@ -84924,17 +85602,17 @@ class BlockModal {
84924
85602
  }
84925
85603
  updatePageImage(src) {
84926
85604
  this.builder.uo.saveForUndo();
84927
- let page = this.getPage();
84928
- page.style.backgroundImage = 'url(\'' + src + '\')';
85605
+ let pageOverlay = this.pageOverlay();
85606
+ pageOverlay.style.backgroundImage = 'url(\'' + src + '\')';
84929
85607
 
84930
85608
  // Reset position & filter (grayscale)
84931
- page.style.filter = '';
84932
- page.style.backgroundSize = '';
84933
- page.style.backgroundPosition = '50% 60%';
84934
- page.removeAttribute('data-bg-xs');
84935
- page.removeAttribute('data-bg-sm');
84936
- page.removeAttribute('data-bg-md');
84937
- page.removeAttribute('data-bg-lg');
85609
+ pageOverlay.style.filter = '';
85610
+ pageOverlay.style.backgroundSize = '';
85611
+ pageOverlay.style.backgroundPosition = '50% 60%';
85612
+ pageOverlay.removeAttribute('data-bg-xs');
85613
+ pageOverlay.removeAttribute('data-bg-sm');
85614
+ pageOverlay.removeAttribute('data-bg-md');
85615
+ pageOverlay.removeAttribute('data-bg-lg');
84938
85616
  this.updatePanelPageImage(src);
84939
85617
  this.builder.onChange();
84940
85618
  }
@@ -84958,6 +85636,16 @@ class BlockModal {
84958
85636
  }
84959
85637
  const btnPageGradient = modal.querySelector('.btn-page-gradient');
84960
85638
  btnPageGradient.style.backgroundImage = '';
85639
+
85640
+ // Show/hide grayscale
85641
+ const divPageGrayscale = modal.querySelector('.label-page-grayscale');
85642
+ if (src === '') {
85643
+ this.pageImagePreview.style.display = 'none';
85644
+ divPageGrayscale.style.display = 'none';
85645
+ } else {
85646
+ this.pageImagePreview.style.display = '';
85647
+ divPageGrayscale.style.display = '';
85648
+ }
84961
85649
  }
84962
85650
  updateImage(src) {
84963
85651
  this.builder.uo.saveForUndo();
@@ -84973,6 +85661,7 @@ class BlockModal {
84973
85661
  blockOverlay.removeAttribute('data-bg-md');
84974
85662
  blockOverlay.removeAttribute('data-bg-lg');
84975
85663
  this.updatePanelImage(src);
85664
+ this.realtime();
84976
85665
  this.builder.onChange();
84977
85666
  }
84978
85667
  updatePanelImage(src) {
@@ -84995,6 +85684,16 @@ class BlockModal {
84995
85684
  }
84996
85685
  const btnGradient = modal.querySelector('.btn-block-gradient');
84997
85686
  btnGradient.style.backgroundImage = '';
85687
+
85688
+ // Show/hide grayscale
85689
+ const divGrayscale = modal.querySelector('.label-block-grayscale');
85690
+ if (src === '') {
85691
+ this.imagePreview.style.display = 'none';
85692
+ divGrayscale.style.display = 'none';
85693
+ } else {
85694
+ this.imagePreview.style.display = '';
85695
+ divGrayscale.style.display = '';
85696
+ }
84998
85697
  }
84999
85698
  show() {
85000
85699
  const modal = this.modal;
@@ -85025,6 +85724,7 @@ class BlockModal {
85025
85724
  }
85026
85725
  showHideControls() {
85027
85726
  const modal = this.modal;
85727
+ if (!modal.classList.contains('active')) return;
85028
85728
  const content1 = modal.querySelector('.modal-none');
85029
85729
  const content2 = modal.querySelector('.modal-content');
85030
85730
  const content3 = modal.querySelector('.modal-page-content');
@@ -85065,6 +85765,60 @@ class BlockModal {
85065
85765
  this.builder.doc.removeEventListener('click', this.handleBlockClick);
85066
85766
  }
85067
85767
  }
85768
+ position() {
85769
+ const dom = this.dom;
85770
+ let elementTool = this.elementTool;
85771
+ let elementMore = this.elementMore;
85772
+ dom.addClass(elementMore, 'transition1');
85773
+ let elmMore = elementTool.querySelector('.elm-more');
85774
+ const viewportHeight = window.innerHeight;
85775
+
85776
+ /*
85777
+ let top, left;
85778
+ if(!this.builder.iframe) {
85779
+ top = elmMore.getBoundingClientRect().top;
85780
+ left = elmMore.getBoundingClientRect().left;
85781
+ } else {
85782
+ let adjY = this.builder.iframe.getBoundingClientRect().top;
85783
+ let adjX = this.builder.iframe.getBoundingClientRect().left;
85784
+ top = elmMore.getBoundingClientRect().top;
85785
+ left = elmMore.getBoundingClientRect().left;
85786
+ top = top + adjY;
85787
+ left = left + adjX;
85788
+ }
85789
+ */
85790
+ const newPos = this.builder.util.getElementPosition(elmMore);
85791
+ let top = newPos.top;
85792
+ let left = newPos.left;
85793
+
85794
+ // elementMore.style.display = 'flex';
85795
+ const btnMore = elementTool.querySelector('.elm-more');
85796
+ this.util.showPop(elementMore, false, btnMore);
85797
+ const w = elementMore.offsetWidth; //to get value, element must not hidden (display:none). So set display:flex before this.
85798
+ const h = elementMore.offsetHeight;
85799
+ if (viewportHeight - top > h) {
85800
+ elementMore.style.top = top + window.pageYOffset + 27 + 'px';
85801
+ elementMore.style.left = left - w / 2 + 10 + 'px';
85802
+ dom.removeClass(elementMore, 'arrow-bottom');
85803
+ dom.removeClass(elementMore, 'arrow-right');
85804
+ dom.removeClass(elementMore, 'arrow-left');
85805
+ dom.removeClass(elementMore, 'center');
85806
+ dom.addClass(elementMore, 'arrow-top');
85807
+ dom.addClass(elementMore, 'center');
85808
+ } else {
85809
+ elementMore.style.top = top + window.pageYOffset - h - 8 + 'px';
85810
+ elementMore.style.left = left - w / 2 + 10 + 'px';
85811
+ dom.removeClass(elementMore, 'arrow-top');
85812
+ dom.removeClass(elementMore, 'arrow-right');
85813
+ dom.removeClass(elementMore, 'arrow-left');
85814
+ dom.removeClass(elementMore, 'center');
85815
+ dom.addClass(elementMore, 'arrow-bottom');
85816
+ dom.addClass(elementMore, 'center');
85817
+ }
85818
+ setTimeout(() => {
85819
+ dom.removeClass(elementMore, 'transition1');
85820
+ }, 300);
85821
+ }
85068
85822
  }
85069
85823
 
85070
85824
  class PageSize {
@@ -85197,12 +85951,19 @@ class PageSize {
85197
85951
  // let h = arr[1].trim();
85198
85952
  if (arr.length === 3) {
85199
85953
  // web
85200
- const docWidth = docContainer.offsetWidth;
85201
- const viewportWidth = this.builder.win.innerWidth;
85202
- if (docWidth < viewportWidth - 50) {
85203
- // web (container)
85204
- docContainer.classList.remove('page-web');
85205
- docContainer.classList.add('page-web-container');
85954
+ let box = docContainer.querySelector('.is-box');
85955
+ if (box) {
85956
+ const boxWidth = box.offsetWidth;
85957
+ const viewportWidth = this.builder.win.innerWidth;
85958
+ if (boxWidth < viewportWidth - 50) {
85959
+ // web (container)
85960
+ docContainer.classList.remove('page-web');
85961
+ docContainer.classList.add('page-web-container');
85962
+ } else {
85963
+ // web (full)
85964
+ docContainer.classList.remove('page-web-container');
85965
+ docContainer.classList.add('page-web');
85966
+ }
85206
85967
  } else {
85207
85968
  // web (full)
85208
85969
  docContainer.classList.remove('page-web-container');
@@ -85291,18 +86052,53 @@ class PageSize {
85291
86052
  position: relative;
85292
86053
  flex:none;
85293
86054
  background: #fff;
85294
- overflow: hidden;
86055
+ /* overflow: hidden;*/
85295
86056
  box-shadow: none;
85296
86057
  }
85297
86058
  ${css}
85298
86059
  </style>
86060
+
86061
+ ${html.includes('data-module="codeview"') ? `
86062
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism.min.css" rel="stylesheet">
86063
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-coy.min.css" rel="stylesheet">
86064
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/prism.min.js"></script>
86065
+ <style>
86066
+ :not(pre)>code[class*=language-], pre[class*=language-] {
86067
+ background-color: #f4f4f4 !important;
86068
+ padding: 12px 16px !important;
86069
+ }
86070
+ pre[class*=language-]:after, pre[class*=language-]:before {
86071
+ box-shadow: none;
86072
+ }
86073
+ :not(pre)>code[class*=language-], pre[class*=language-] {
86074
+ margin-bottom: 1.2rem;
86075
+ }
86076
+ div[data-html] {
86077
+ min-height: 40px;
86078
+ }
86079
+ code[class*=language-], pre[class*=language-] {
86080
+ text-shadow: none;
86081
+ }
86082
+ </style>
86083
+ ` : ''}
85299
86084
  </head>
85300
86085
  <body class="print">
85301
86086
 
85302
86087
  <div class="is-page">${html}</div>
85303
86088
 
85304
86089
  <script>
85305
- window.print();
86090
+ var docReady = function(fn) {
86091
+ var stateCheck = setInterval(function() {
86092
+ if (document.readyState !== "complete") return;
86093
+ clearInterval(stateCheck);
86094
+ try {
86095
+ fn()
86096
+ } catch (e) {}
86097
+ }, 1);
86098
+ };
86099
+ docReady(function() {
86100
+ window.print();
86101
+ });
85306
86102
  </script>
85307
86103
  </body>
85308
86104
  </html>
@@ -85387,6 +86183,9 @@ class PageSize {
85387
86183
  width: ${docWidth};
85388
86184
  height: ${docHeight};
85389
86185
  }
86186
+ .hide-on-print {
86187
+ display: none !important;
86188
+ }
85390
86189
  }
85391
86190
  @page {
85392
86191
  size:${docWidth} ${docHeight};;
@@ -85407,6 +86206,9 @@ class PageSize {
85407
86206
  width: ${w};
85408
86207
  height: ${h};
85409
86208
  }
86209
+ .hide-on-print {
86210
+ display: none !important;
86211
+ }
85410
86212
  }
85411
86213
  @page {
85412
86214
  size:${w} ${h};
@@ -85676,7 +86478,7 @@ class ContentBuilder {
85676
86478
  style: 'width:180px;height:112.5px'
85677
86479
  }, {
85678
86480
  title: 'Web (container)',
85679
- pagesize: '800px,1000px,web',
86481
+ pagesize: '1000px,1000px,web',
85680
86482
  style: 'width:180px;height:112.5px'
85681
86483
  }, {
85682
86484
  title: '8.27x5.52',
@@ -86517,6 +87319,12 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
86517
87319
  if (window.data_basic) {
86518
87320
  // if snippet file included
86519
87321
  this.opts.snippetJSON = window.data_basic;
87322
+ if (!this.canvas) for (let i = this.opts.snippetJSON.snippets.length - 1; i >= 0; i--) {
87323
+ if (this.opts.snippetJSON.snippets[i].mode === 'canvas') {
87324
+ this.opts.snippetJSON.snippets.splice(i, 1);
87325
+ }
87326
+ }
87327
+
86520
87328
  // if snippetPath is specified (not empty), then use the specified. Otherwise, use the one generated from snippet file (_snippets_path)
86521
87329
  if (this.opts.snippetPath === '') {
86522
87330
  this.opts.snippetPath = window._snippets_path;
@@ -86557,12 +87365,19 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
86557
87365
  this.blockContainer = '.is-box';
86558
87366
  this.imageResizeOnBlock = false;
86559
87367
  this.toolbarDisplay = 'always';
86560
- this.buttons = ['bold', 'italic', 'underline', 'formatting', 'color', 'align', 'textsettings', 'createLink', 'tags', '|', 'undo', 'redo', 'aiassistant', 'snippets', 'zoom', 'pageoptions', 'print', 'html', 'more'];
86561
- this.buttonsMore = ['icon', 'image', '|', 'list', 'font', 'formatPara'];
86562
- this.elementButtons = ['front', 'backward', 'moveup', 'movedown', 'group', 'ungroup', 'duplicate', 'delete', 'left', 'center', 'right', 'full', 'undo', 'redo', 'aiassistant', 'snippets', 'blocksettings', 'zoom', 'pageoptions', 'print', 'html'];
86563
- this.elementButtonsMore = [];
86564
- this.iconButtons = ['icon', 'color', 'textsettings', 'createLink', '|', 'undo', 'redo', 'aiassistant', 'snippets', 'zoom', 'pageoptions', 'print', 'html'];
86565
- this.iconButtonsMore = [];
87368
+ // this.buttons = ['bold', 'italic', 'underline', 'formatting', 'color', 'align', 'textsettings', 'createLink', 'tags', '|', 'undo', 'redo', 'aiassistant', 'snippets','pageoptions', 'print', 'html', 'zoom', 'more'];
87369
+ // this.buttonsMore = ['icon', 'image', '|', 'list', 'font', 'formatPara'];
87370
+ // this.elementButtons = ['front', 'backward', 'moveup', 'movedown', 'group', 'ungroup', 'duplicate', 'delete','left', 'center', 'right', 'full' , 'undo', 'redo', 'aiassistant', 'snippets', 'blocksettings', 'pageoptions', 'print', 'zoom', 'html'];
87371
+ // this.elementButtonsMore = [];
87372
+ // this.iconButtons = ['icon', 'color','textsettings', 'createLink','|', 'undo', 'redo', 'aiassistant', 'snippets', 'pageoptions', 'print', 'zoom', 'html'];
87373
+ // this.iconButtonsMore = [];
87374
+
87375
+ this.buttons = ['bold', 'italic', 'underline', 'formatting', 'color', 'align', 'textsettings', 'createLink', 'tags', '|', 'undo', 'redo', 'zoom', 'pageoptions', 'print', 'html', 'more'];
87376
+ this.buttonsMore = ['icon', 'image', '|', 'list', 'font', 'formatPara', '|', 'aiassistant', 'snippets', 'preferences'];
87377
+ this.elementButtons = ['front', 'backward', 'moveup', 'movedown', 'group', 'ungroup', 'duplicate', 'delete', 'left', 'center', 'right', 'full', 'undo', 'redo', 'blocksettings', 'zoom', 'pageoptions', 'print', 'html', 'more'];
87378
+ this.elementButtonsMore = ['aiassistant', 'snippets', 'preferences'];
87379
+ this.iconButtons = ['icon', 'color', 'textsettings', 'createLink', '|', 'undo', 'redo', 'zoom', 'pageoptions', 'print', 'html', 'more'];
87380
+ this.iconButtonsMore = ['aiassistant', 'snippets', 'preferences'];
86566
87381
  if (!this.docContainer && this.container !== '.is-container') {
86567
87382
  this.docContainer = this.container;
86568
87383
  this.container = '.is-container';
@@ -87074,6 +87889,11 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
87074
87889
  this.rte.hideBlockButtons();
87075
87890
  this.rte.positionToolbar();
87076
87891
  }
87892
+ if (this.blockmodal) {
87893
+ setTimeout(() => {
87894
+ this.blockmodal.showHideControls();
87895
+ }, 30);
87896
+ }
87077
87897
  },
87078
87898
  onSelectBlock: block => {
87079
87899
  if (this.onSelectBlock) this.onSelectBlock(block);
@@ -87229,6 +88049,57 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
87229
88049
  }
87230
88050
  }
87231
88051
  });
88052
+
88053
+ // Copy & Paste Block
88054
+ document.addEventListener('keydown', e => {
88055
+ if ((e.ctrlKey || e.metaKey) && e.which === 67) {
88056
+ //CTRL-C
88057
+ const activeBlock = docContainer.querySelector('.is-block.active'); // always get .cloned
88058
+ if (activeBlock) {
88059
+ this.copyBlock = activeBlock;
88060
+ }
88061
+ }
88062
+ });
88063
+ document.addEventListener('keydown', e => {
88064
+ if ((e.ctrlKey || e.metaKey) && e.which === 86) {
88065
+ //CTRL-V
88066
+
88067
+ const box = docContainer.querySelector('.is-box.box-select'); // always get .cloned
88068
+ let block = this.copyBlock;
88069
+ if (box && block) {
88070
+ if (document.querySelector('.is-modal.active:not(.is-modal-content)')) return;
88071
+ const focusedElement = e.target;
88072
+ const isEditable = focusedElement.tagName === 'INPUT' || focusedElement.tagName === 'TEXTAREA' || focusedElement.hasAttribute('contenteditable');
88073
+ if (isEditable) return;
88074
+ this.uo.saveForUndo();
88075
+ let block = this.copyBlock;
88076
+ const builder = block.querySelector(this.container);
88077
+ let html = '';
88078
+ if (builder) {
88079
+ html = this.readHtml(builder);
88080
+ }
88081
+ let clonedDiv = block.cloneNode(true);
88082
+ clonedDiv.style.top = '20%';
88083
+ clonedDiv.style.left = '20%';
88084
+ if (builder) {
88085
+ const cloneBuilder = clonedDiv.querySelector(this.container);
88086
+ cloneBuilder.innerHTML = '';
88087
+ box.appendChild(clonedDiv);
88088
+ const range = document.createRange();
88089
+ cloneBuilder.appendChild(range.createContextualFragment(html));
88090
+ this.applyBehaviorOn(cloneBuilder);
88091
+ cloneBuilder.click();
88092
+ } else {
88093
+ block.parentNode.appendChild(clonedDiv);
88094
+ }
88095
+ block.classList.remove('active');
88096
+ this.doc.querySelectorAll('.clone').forEach(elm => elm.parentNode.removeChild(elm));
88097
+ this.doc.querySelectorAll('.cloned').forEach(elm => elm.classList.remove('cloned'));
88098
+ this.eb.refresh();
88099
+ this.opts.onChange();
88100
+ }
88101
+ }
88102
+ });
87232
88103
  }
87233
88104
  let previousWidth = this.win.innerWidth;
87234
88105
  let timer;
@@ -87567,6 +88438,15 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
87567
88438
  }
87568
88439
  }
87569
88440
  }, 300);
88441
+
88442
+ // info
88443
+ let largeScreenBreakpoint = 1280; //1920
88444
+ largeScreenBreakpoint = window.innerWidth - 360; //351
88445
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
88446
+ if (this.consoleLog) {
88447
+ console.log('vw: ' + window.innerWidth);
88448
+ console.log('lg: ' + largeScreenBreakpoint);
88449
+ }
87570
88450
  } // constructor
87571
88451
 
87572
88452
  // Convenience constructor, so that the plugin can be called directly using: ContentBuilder.run({ ... });
@@ -87649,6 +88529,22 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
87649
88529
  top: 0;
87650
88530
  left: -1000px;
87651
88531
  }
88532
+ .h-ruler {
88533
+ top:0;
88534
+ left:-100vw;
88535
+ width: 300vw;
88536
+ height:2px;
88537
+ display:none;
88538
+ }
88539
+ .h-ruler.active { display: block }
88540
+ .v-ruler {
88541
+ top:0;
88542
+ left:0;
88543
+ width:2px;
88544
+ height: 100%;
88545
+ display:none;
88546
+ }
88547
+ .v-ruler.active { display: block }
87652
88548
 
87653
88549
  /* Resize Handles */
87654
88550
  .handle {
@@ -87823,16 +88719,19 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
87823
88719
  @media (max-width: 760px) {
87824
88720
  .is-box.autolayout .is-block > .rotate-handle,
87825
88721
  .is-box.autolayout .is-block > .handle {
87826
- display: none;
88722
+ display: none;
87827
88723
  }
87828
88724
 
87829
88725
  /* NEW */
87830
- .is-block.clone {
88726
+ .is-box.autolayout .is-block.clone {
87831
88727
  display:none;
87832
88728
  }
87833
- .is-block.cloned {
88729
+ .is-box.autolayout .is-block.cloned {
87834
88730
  outline: var(--is-outline);
87835
88731
  }
88732
+ .is-box.box-select {
88733
+ outline: none !important;
88734
+ }
87836
88735
  }
87837
88736
 
87838
88737
  .is-block.locked .handle,
@@ -88499,7 +89398,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
88499
89398
  this.setZoomOnControl(builder);
88500
89399
  }
88501
89400
  html(area) {
88502
- if (this.docContainer) {
89401
+ if (this.docContainer && !area) {
88503
89402
  // freeform
88504
89403
 
88505
89404
  const docContainer = this.doc.querySelector(this.docContainer);
@@ -88607,7 +89506,33 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
88607
89506
  }
88608
89507
  refresh() {
88609
89508
  if (this.eb) this.eb.refresh();
89509
+
89510
+ /*
89511
+ // Add block tool
89512
+ let html = `
89513
+ <div class="is-tool is-block-tool">
89514
+ <button type="button" tabindex="-1" title="${this.util.out('Settings')}" class="block-settings"><svg class="is-icon-flex"><use xlink:href="#icon-settings"></use></svg></button>
89515
+ </div>
89516
+ `;
89517
+ let blocks = this.doc.querySelectorAll('.is-block');
89518
+ blocks.forEach(block => {
89519
+ let tool = block.querySelector('.is-block-tool');
89520
+ if(tool) tool.remove();
89521
+ block.insertAdjacentHTML('beforeend', html);
89522
+ tool = block.querySelector('.is-block-tool');
89523
+ tool.addEventListener('click',(e)=>{
89524
+ if(document.querySelector('.is-modal.editblock.active')) {
89525
+ this.blockmodal.hide();
89526
+ } else {
89527
+ this.blockmodal.show();
89528
+ }
89529
+ e.preventDefault();
89530
+ e.stopImmediatePropagation();
89531
+ });
89532
+ });
89533
+ */
88610
89534
  }
89535
+
88611
89536
  group() {
88612
89537
  if (!this.eb) return;
88613
89538
  this.uo.saveForUndo();
@@ -88762,6 +89687,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
88762
89687
  <!--
88763
89688
  <button type="button" tabindex="-1" class="box-settings" title="${this.util.out('Settings')}"><svg class="is-icon-flex"><use xlink:href="#ion-more"></use></svg></button>
88764
89689
  -->
89690
+ <button type="button" tabindex="-1" class="box-duplicate" title="${this.util.out('Duplicate')}"><svg class="is-icon-flex" style="width:14px;height:14px"><use xlink:href="#icon-duplicate"></use></svg></button>
88765
89691
  <button type="button" tabindex="-1" class="box-remove" title="${this.util.out('Remove')}"><svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg></button>
88766
89692
  </div>
88767
89693
  <div class="is-tool is-canvasadd-tool" style="transform: scale(1); transform-origin: center top;">
@@ -88812,6 +89738,57 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
88812
89738
  });
88813
89739
  this.opts.onChange();
88814
89740
  });
89741
+ const btnDuplicate = box.querySelector('.is-canvas-tool .box-duplicate');
89742
+ btnDuplicate.addEventListener('click', e => {
89743
+ this.eb.selectClear(); // clear clone
89744
+
89745
+ // clear active
89746
+ const box = e.target.closest('.is-box');
89747
+ const block = box.querySelector('.is-block.active');
89748
+ if (block) block.classList.remove('active');
89749
+ this.uo.saveForUndo();
89750
+ let copiedBox = box.cloneNode(true);
89751
+ copiedBox.setAttribute('data-box-copied', '1');
89752
+ let parent = box.parentNode;
89753
+ parent.insertBefore(copiedBox, box.nextElementSibling);
89754
+ let newBox = docContainer.querySelector('[data-box-copied]');
89755
+ newBox.removeAttribute('data-box-copied');
89756
+
89757
+ // Code Blocks Handling
89758
+ let codeBlocks = newBox.querySelectorAll('[data-module]');
89759
+ codeBlocks.forEach(element => {
89760
+ let html = decodeURIComponent(element.getAttribute('data-html')); // Original code is stored in data-html attribute
89761
+ html = html.replace(/{id}/g, this.util.makeId());
89762
+ //Fill the block with original code
89763
+ this.html(element, html);
89764
+ });
89765
+ newBox.scrollIntoView({
89766
+ behavior: 'smooth',
89767
+ block: 'center'
89768
+ });
89769
+ this.applyBehaviorCanvas();
89770
+
89771
+ // ContentBuilder Handling
89772
+ let containers = newBox.querySelectorAll('.is-builder');
89773
+ containers.forEach(container => {
89774
+ let containerHtml = this.html(container);
89775
+ let range = document.createRange();
89776
+ container.innerHTML = '';
89777
+ container.appendChild(range.createContextualFragment(containerHtml));
89778
+ container.removeAttribute('data-sort'); //important (ContentBuilder cleanup for the container)
89779
+ this.applyBehaviorOn(container);
89780
+ });
89781
+ this.eb.refresh();
89782
+ this.opts.onChange();
89783
+
89784
+ // Change selection
89785
+ setTimeout(() => {
89786
+ box.classList.remove('box-select');
89787
+ const prevBox = docContainer.querySelector('.box-select');
89788
+ if (prevBox) prevBox.classList.remove('box-select');
89789
+ newBox.classList.add('box-select');
89790
+ }, 30);
89791
+ });
88815
89792
  const btnRemove = box.querySelector('.is-canvas-tool .box-remove');
88816
89793
  btnRemove.addEventListener('click', e => {
88817
89794
  const box = e.target.closest('.is-box');
@@ -89878,6 +90855,12 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
89878
90855
  script.async = true;
89879
90856
  script.onload = () => {
89880
90857
  this.opts.snippetJSON = window.data_basic;
90858
+ if (!this.canvas) for (let i = this.opts.snippetJSON.snippets.length - 1; i >= 0; i--) {
90859
+ if (this.opts.snippetJSON.snippets[i].mode === 'canvas') {
90860
+ this.opts.snippetJSON.snippets.splice(i, 1);
90861
+ }
90862
+ }
90863
+
89881
90864
  // if snippetPath is specified (not empty), then use the specified. Otherwise, use the one generated from snippet file (_snippets_path)
89882
90865
  if (this.opts.snippetPath === '') {
89883
90866
  this.opts.snippetPath = window._snippets_path;
@@ -89904,7 +90887,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
89904
90887
  html = `
89905
90888
  <div class="is-box box-canvas autolayout">
89906
90889
  <div class="is-block block-steady height-auto" style="top: calc(50% - 357px); left: calc(50% - 348px); width: 696px;" data--t="calc(50% - 357px)" data--l="calc(50% - 348px)" data--b="" data--r="" data--w="696px" data--h="">
89907
- <div class="is-container leading-12 size-17">
90890
+ <div class="is-container">
89908
90891
  ${html}
89909
90892
  </div>
89910
90893
  <div class="is-block-overlay"></div>
@@ -91476,6 +92459,13 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
91476
92459
 
91477
92460
  if (this.opts.emailMode) bSnippet = false;
91478
92461
 
92462
+ // check if is block
92463
+ let isBlock = false;
92464
+ if (html.includes('"is-block')) {
92465
+ isBlock = true;
92466
+ bSnippet = false;
92467
+ }
92468
+
91479
92469
  // Convert snippet into your defined 12 columns grid
91480
92470
  var rowClass = this.opts.row; //row
91481
92471
  var 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']
@@ -91522,24 +92512,26 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
91522
92512
  this.dom.removeClass(itemEl, 'snippet-item');
91523
92513
  let bw = '';
91524
92514
  if (this.page && this.page === '.is-wrapper') {
91525
- bw = '800px';
92515
+ bw = '760px';
91526
92516
  } else {
91527
92517
  if (occurrences === 2) {
91528
- bw = '800px';
92518
+ bw = '760px';
91529
92519
  } else if (occurrences >= 3) {
91530
- bw = '800px';
92520
+ bw = '760px';
91531
92521
  } else {
91532
92522
  bw = '540px';
91533
92523
  }
91534
92524
  }
91535
92525
  const blockTemplate = `
91536
92526
  <div class="is-block block-steady height-auto" data-new-dummy="1" style="top: 20%; left: 20%; width: ${bw};">
91537
- <div class="is-container container-new leading-12 size-17">
92527
+ <div class="is-container container-new">
91538
92528
  [%CONTENT%]
91539
92529
  </div>
91540
92530
  </div>
91541
92531
  `; // data-new-dummy will be used by onSort to apply top/left position (snippetpanel.js)
91542
92532
  itemEl.outerHTML = blockTemplate.replace('[%CONTENT%]', html);
92533
+ } else if (isBlock) {
92534
+ itemEl.outerHTML = html;
91543
92535
  } else {
91544
92536
  // Snippet is wrapped in row/colum (may contain custom code or has [data-html] attribute)
91545
92537
  // Can only be inserted after current row or last row (not on column or element).
@@ -91572,19 +92564,19 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
91572
92564
  itemEl.appendChild(range.createContextualFragment(html));
91573
92565
  let bw = '';
91574
92566
  if (this.page && this.page === '.is-wrapper') {
91575
- bw = '800px';
92567
+ bw = '760px';
91576
92568
  } else {
91577
92569
  if (occurrences === 2) {
91578
- bw = '800px';
92570
+ bw = '760px';
91579
92571
  } else if (occurrences >= 3) {
91580
- bw = '800px';
92572
+ bw = '760px';
91581
92573
  } else {
91582
92574
  bw = '540px';
91583
92575
  }
91584
92576
  }
91585
92577
  const blockTemplate = `
91586
92578
  <div class="is-block block-steady height-auto" data-new-dummy="1" style="top: 20%; left: 20%; width: ${bw};">
91587
- <div class="is-container container-new leading-12 size-17">
92579
+ <div class="is-container container-new">
91588
92580
  [%CONTENT%]
91589
92581
  </div>
91590
92582
  </div>