@innovastudio/contentbuilder 1.5.13 → 1.5.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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>