@innovastudio/contentbox 1.6.34 → 1.6.36

Sign up to get free protection for your applications and to get access to all the features.
@@ -36990,7 +36990,7 @@ class HtmlUtil {
36990
36990
  elm.removeAttribute('grideditor');
36991
36991
  elm.removeAttribute('gridoutline');
36992
36992
  });
36993
- elms = tmp.querySelectorAll('.is-row-tool,.is-col-tool,.is-rowadd-tool,.is-canvas-tool,.is-canvasadd-tool');
36993
+ elms = tmp.querySelectorAll('.is-row-tool,.is-col-tool,.is-rowadd-tool,.is-canvas-tool,.is-canvasadd-tool,.h-ruler,.v-ruler');
36994
36994
  elms.forEach(elm => {
36995
36995
  if (elm.previousSibling && elm.previousSibling.nodeType === Node.TEXT_NODE) {
36996
36996
  elm.previousSibling.remove();
@@ -37367,6 +37367,8 @@ class UndoRedo {
37367
37367
  dom.removeElements(tmp.querySelectorAll('.is-canvasadd-tool'));
37368
37368
  dom.removeElements(tmp.querySelectorAll('.ovl'));
37369
37369
  dom.removeElements(tmp.querySelectorAll('.row-add-initial'));
37370
+ dom.removeElements(tmp.querySelectorAll('.h-ruler'));
37371
+ dom.removeElements(tmp.querySelectorAll('.v-ruler'));
37370
37372
 
37371
37373
  // freeform
37372
37374
  elms = tmp.querySelectorAll('.is-block .handle, .is-block .rotate-handle');
@@ -38025,11 +38027,11 @@ const prepareSvgIcons = builder => {
38025
38027
  <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" />
38026
38028
  </symbol>
38027
38029
 
38028
- <symbol id="icon-duplicate" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
38030
+ <symbol id="icon-duplicate2" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
38029
38031
  <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" />
38030
38032
  </symbol>
38031
- <symbol id="icon-duplicate2" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
38032
- <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" />
38033
+ <symbol id="icon-duplicate" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
38034
+ <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" />
38033
38035
  </symbol>
38034
38036
 
38035
38037
  <symbol id="icon-trash" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -38080,7 +38082,7 @@ const prepareSvgIcons = builder => {
38080
38082
  </symbol>
38081
38083
 
38082
38084
  <symbol id="icon-pagesize" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
38083
- <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" />
38085
+ <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" />
38084
38086
  </symbol>
38085
38087
  <symbol id="icon-print" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
38086
38088
  <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" />
@@ -89950,7 +89952,7 @@ class Rte {
89950
89952
  var btn = builder.opts.buttonsMore[j].toLowerCase();
89951
89953
  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>`;
89952
89954
  // 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>`;
89953
- 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 === '|') {
89955
+ 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 === '|') {
89954
89956
  html_rtemore += '<div class="rte-separator"></div>';
89955
89957
  } else {
89956
89958
  html_rtemore += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -89960,7 +89962,7 @@ class Rte {
89960
89962
  let html_rte = '';
89961
89963
  for (j = 0; j < builder.opts.buttons.length; j++) {
89962
89964
  btn = builder.opts.buttons[j].toLowerCase();
89963
- 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 === '|') {
89965
+ 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 === '|') {
89964
89966
  html_rte += '<div class="rte-separator"></div>';
89965
89967
  } else {
89966
89968
  html_rte += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -89978,7 +89980,7 @@ class Rte {
89978
89980
  let html_elementrtemore = '';
89979
89981
  for (j = 0; j < builder.opts.elementButtonsMore.length; j++) {
89980
89982
  btn = builder.opts.elementButtonsMore[j].toLowerCase();
89981
- 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 === '|') {
89983
+ 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 === '|') {
89982
89984
  html_elementrtemore += '<div class="rte-separator"></div>';
89983
89985
  } else {
89984
89986
  html_elementrtemore += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -89988,7 +89990,7 @@ class Rte {
89988
89990
  let html_elementrte = '';
89989
89991
  for (j = 0; j < builder.opts.elementButtons.length; j++) {
89990
89992
  btn = builder.opts.elementButtons[j].toLowerCase();
89991
- 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 === '|') {
89993
+ 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 === '|') {
89992
89994
  html_elementrte += '<div class="rte-separator"></div>';
89993
89995
  } else {
89994
89996
  html_elementrte += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -90008,7 +90010,7 @@ class Rte {
90008
90010
  let html_iconrte = '';
90009
90011
  for (j = 0; j < builder.opts.iconButtonsMore.length; j++) {
90010
90012
  btn = builder.opts.iconButtonsMore[j].toLowerCase();
90011
- 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 === '|') {
90013
+ 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 === '|') {
90012
90014
  html_iconrtemore += '<div class="rte-separator"></div>';
90013
90015
  } else {
90014
90016
  html_iconrtemore += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -90017,7 +90019,7 @@ class Rte {
90017
90019
 
90018
90020
  for (j = 0; j < builder.opts.iconButtons.length; j++) {
90019
90021
  btn = builder.opts.iconButtons[j].toLowerCase();
90020
- 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 === '|') {
90022
+ 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 === '|') {
90021
90023
  html_iconrte += '<div class="rte-separator"></div>';
90022
90024
  } else {
90023
90025
  html_iconrte += `<button tabindex="-1" title="button not found" data-plugin="${btn}"></button>`; //temporary (later will be replaced with plugin button)
@@ -90164,6 +90166,9 @@ class Rte {
90164
90166
  <div style="padding-top:4px">
90165
90167
  <input type="range" min="50" max="${zoomMax}" value="1" class="rte-zoom-slider is-rangeslider">
90166
90168
  </div>
90169
+ <div style="display:flex;justify-content:flex-end">
90170
+ <button title="${util.out('Reset')}" class="reset-zoom" style="background:transparent;padding:0;height:27px;text-decoration:underline">${util.out('Reset')}</button>
90171
+ </div>
90167
90172
  </div>
90168
90173
  </div>
90169
90174
 
@@ -91342,6 +91347,16 @@ class Rte {
91342
91347
  showTools();
91343
91348
  });
91344
91349
 
91350
+ // Reset Zoom
91351
+ const btnResetZoom = builderStuff.querySelector('.reset-zoom');
91352
+ btnResetZoom.addEventListener('click', () => {
91353
+ this.builder.opts.zoom = 1;
91354
+ localStorage.setItem('_zoom', 1); // Save
91355
+
91356
+ // setZoomOnArea
91357
+ this.builder.setZoomOnArea();
91358
+ });
91359
+
91345
91360
  // Zoom Modal
91346
91361
  this.inpZoomSlider.onfocus = () => {
91347
91362
  if (this.builder.onZoomStart) {
@@ -98860,7 +98875,6 @@ class ContentStuff$1 {
98860
98875
  <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>
98861
98876
  </div>
98862
98877
 
98863
-
98864
98878
  <div class="is-locked-indicator">
98865
98879
  <svg class="is-icon-flex"><use xlink:href="#icon-lock"></use></svg>
98866
98880
  </div>
@@ -99354,6 +99368,35 @@ class ContentStuff$1 {
99354
99368
  }
99355
99369
  .is-tool.is-element-tool .elm-settings { display: none; }
99356
99370
 
99371
+ /* is-block-tool
99372
+
99373
+ .is-tool.is-block-tool {
99374
+ background: rgba(243, 243, 243, 0.9);
99375
+ border-radius: 3px;
99376
+ overflow: hidden;
99377
+ top: 3px;
99378
+ right: 3px;
99379
+ left: auto;
99380
+ width: 25px;
99381
+ }
99382
+ .is-tool.is-block-tool button {
99383
+ width: 25px;
99384
+ height: 25px;
99385
+ background: transparent;
99386
+ display: flex;
99387
+ align-items: center;
99388
+ justify-content: center;
99389
+ }
99390
+ .is-tool.is-block-tool svg {
99391
+ width: 14px;
99392
+ height: 14px;
99393
+ fill: #000;
99394
+ }
99395
+ .is-block.active:not(.multi):not(.editable) .is-block-tool {
99396
+ display:flex;
99397
+ }
99398
+ */
99399
+
99357
99400
  /* is-column-tool */
99358
99401
 
99359
99402
  .is-tool.is-column-tool {
@@ -100450,7 +100493,7 @@ class LivePreview {
100450
100493
  // ContentBuilder
100451
100494
 
100452
100495
  if (this.builder.previewURL) {
100453
- if (this.builder.livePreviewAlwaysReload) {
100496
+ if (this.builder.livePreviewAlwaysReload || hardReload) {
100454
100497
  iframe.src = this.builder.previewURL + '?' + Math.floor(Date.now() / 1000);
100455
100498
  } else {
100456
100499
  let iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
@@ -107222,7 +107265,25 @@ class Common {
107222
107265
  applyPercentage(block) {
107223
107266
  const zoom = this.zoom;
107224
107267
  const rect = this.getRect(block);
107225
- const container = block.parentNode;
107268
+ const container = block.closest('.box-canvas');
107269
+ const containerRect = this.getRect(container); // if container has top/left
107270
+
107271
+ this.horizontalRulerTop = container.querySelector('.h-ruler-top');
107272
+ this.horizontalRulerBottom = container.querySelector('.h-ruler-bottom');
107273
+ this.horizontalRulerMiddle = container.querySelector('.h-ruler-middle');
107274
+ this.verticalRulerLeft = container.querySelector('.v-ruler-left');
107275
+ this.verticalRulerRight = container.querySelector('.v-ruler-right');
107276
+ this.verticalRulerCenter = container.querySelector('.v-ruler-center');
107277
+
107278
+ // Check Edges
107279
+ let topTouched = false;
107280
+ let bottomTouched = false;
107281
+ let leftTouched = false;
107282
+ let rightTouched = false;
107283
+ if (this.horizontalRulerTop.hasAttribute('data-topTouched')) topTouched = true;
107284
+ if (this.horizontalRulerBottom.hasAttribute('data-bottomTouched')) bottomTouched = true;
107285
+ if (this.verticalRulerLeft.hasAttribute('data-leftTouched')) leftTouched = true;
107286
+ if (this.verticalRulerRight.hasAttribute('data-rightTouched')) rightTouched = true;
107226
107287
  let isChildBlock = false;
107227
107288
  if (block.parentNode.matches(this.selector)) {
107228
107289
  // child block
@@ -107230,7 +107291,7 @@ class Common {
107230
107291
  }
107231
107292
 
107232
107293
  // const containerRect = container.getBoundingClientRect(); // if container has top/left
107233
- const containerRect = this.getRect(container); // if container has top/left
107294
+ // const containerRect = this.getRect(container); // if container has top/left
107234
107295
  let left = (rect.left - containerRect.left) / container.offsetWidth * 100;
107235
107296
  let top = (rect.top - containerRect.top) / container.offsetHeight * 100;
107236
107297
  let isBlockFixed = block.classList.contains('block-steady');
@@ -107269,6 +107330,35 @@ class Common {
107269
107330
  block.style.left = left / zoom + '%';
107270
107331
  if (block.classList.contains('height-auto')) block.style.height = '';
107271
107332
  }
107333
+
107334
+ // Check
107335
+
107336
+ block.style.right = ''; //reset
107337
+ block.style.bottom = ''; //reset
107338
+
107339
+ if (topTouched) block.style.top = 0;
107340
+ // if(topTouched && bottomTouched) block.style.height = '100%';
107341
+ if (leftTouched) block.style.left = 0;
107342
+ // if(leftTouched && rightTouched) block.style.width = '100%';
107343
+
107344
+ if (topTouched && bottomTouched) {
107345
+ block.style.top = 0;
107346
+ block.style.bottom = 0;
107347
+ block.style.height = '';
107348
+ }
107349
+ if (leftTouched && rightTouched) {
107350
+ block.style.left = 0;
107351
+ block.style.right = 0;
107352
+ block.style.width = '';
107353
+ }
107354
+ if (bottomTouched && !topTouched) {
107355
+ block.style.bottom = 0;
107356
+ block.style.height = '';
107357
+ }
107358
+ if (rightTouched && !leftTouched) {
107359
+ block.style.right = 0;
107360
+ block.style.width = '';
107361
+ }
107272
107362
  }
107273
107363
  applyPixels(block) {
107274
107364
  const zoom = this.zoom;
@@ -107423,15 +107513,16 @@ class Common {
107423
107513
  right = Math.max(right, blockLeft + blockWidth);
107424
107514
  }
107425
107515
  });
107516
+ const container = blocks[0].parentNode;
107517
+ const containerRect = this.getRect(container);
107426
107518
  const group = this.doc.createElement('div');
107427
107519
  group.classList.add(className);
107428
107520
  group.classList.add(groupClassName);
107429
107521
  group.classList.add('block-steady');
107430
- group.style.top = top + 'px';
107431
- group.style.left = left + 'px';
107522
+ group.style.top = top - containerRect.top + 'px';
107523
+ group.style.left = left - containerRect.left + 'px';
107432
107524
  group.style.width = right + 1 - left + 'px';
107433
107525
  group.style.height = bottom + 1 - top + 'px';
107434
- const container = blocks[0].parentNode;
107435
107526
  container.appendChild(group);
107436
107527
  blocks.forEach(block => {
107437
107528
  if (!block.parentNode.matches(this.selector)) {
@@ -107440,8 +107531,8 @@ class Common {
107440
107531
  let blockLeft = parseFloat(block.style.left) || 0;
107441
107532
 
107442
107533
  // Adjust position relative to the group div
107443
- block.style.top = blockTop - top + 'px';
107444
- block.style.left = blockLeft - left + 'px';
107534
+ block.style.top = blockTop - top + containerRect.top + 'px';
107535
+ block.style.left = blockLeft - left + containerRect.left + 'px';
107445
107536
  group.appendChild(block);
107446
107537
  this.applyPercentage(block);
107447
107538
  }
@@ -107496,14 +107587,15 @@ class Common {
107496
107587
  const top = rect.top;
107497
107588
  const left = rect.left;
107498
107589
  const container = group.parentNode;
107590
+ const containerRect = this.getRect(container);
107499
107591
  group.querySelectorAll(this.selector).forEach(block => {
107500
107592
  this.applyPixels(block);
107501
107593
  let blockTop = parseFloat(block.style.top) || 0;
107502
107594
  let blockLeft = parseFloat(block.style.left) || 0;
107503
107595
 
107504
107596
  // Adjust position relative to the group div
107505
- block.style.top = blockTop + top + 'px';
107506
- block.style.left = blockLeft + left + 'px';
107597
+ block.style.top = blockTop + top - containerRect.top + 'px';
107598
+ block.style.left = blockLeft + left - containerRect.left + 'px';
107507
107599
  container.appendChild(block);
107508
107600
 
107509
107601
  // Remove all breakpoints
@@ -107715,10 +107807,23 @@ class Ruler {
107715
107807
  this.zoom = scale;
107716
107808
  }
107717
107809
  setup() {
107718
- this.elements = this.doc.querySelectorAll(this.selector);
107810
+ // this.elements = this.doc.querySelectorAll(this.selector);
107811
+ this.refresh();
107719
107812
  }
107720
107813
  refresh() {
107721
107814
  this.elements = this.doc.querySelectorAll(this.selector);
107815
+ const rulerHTML = `
107816
+ <div class="ruler h-ruler h-ruler-top""></div>
107817
+ <div class="ruler h-ruler h-ruler-bottom"></div>
107818
+ <div class="ruler h-ruler h-ruler-middle"></div>
107819
+ <div class="ruler v-ruler v-ruler-left"></div>
107820
+ <div class="ruler v-ruler v-ruler-right"></div>
107821
+ <div class="ruler v-ruler v-ruler-center"></div>
107822
+ `;
107823
+ const containers = this.doc.querySelectorAll('.box-canvas');
107824
+ containers.forEach(container => {
107825
+ if (!container.querySelector('.h-ruler-top')) container.insertAdjacentHTML('beforeend', rulerHTML);
107826
+ });
107722
107827
  }
107723
107828
  destroy() {
107724
107829
  [this.horizontalRulerTop, this.horizontalRulerBottom, this.verticalRulerLeft, this.verticalRulerRight].forEach(elm => {
@@ -107726,6 +107831,18 @@ class Ruler {
107726
107831
  });
107727
107832
  }
107728
107833
  hideRulers() {
107834
+ this.horizontalRulerTop.classList.remove('active');
107835
+ this.horizontalRulerBottom.classList.remove('active');
107836
+ this.horizontalRulerMiddle.classList.remove('active');
107837
+ this.verticalRulerLeft.classList.remove('active');
107838
+ this.verticalRulerRight.classList.remove('active');
107839
+ this.verticalRulerCenter.classList.remove('active');
107840
+ this.rulerTop = null;
107841
+ this.rulerBottom = null; //new
107842
+ this.rulerLeft = null;
107843
+ this.rulerRight = null;
107844
+ }
107845
+ hideRulers_bak() {
107729
107846
  this.horizontalRulerTop.style.top = '-1000px';
107730
107847
  this.horizontalRulerBottom.style.top = '-1000px';
107731
107848
  this.horizontalRulerMiddle.style.top = '-1000px';
@@ -107733,10 +107850,207 @@ class Ruler {
107733
107850
  this.verticalRulerRight.style.left = '-1000px';
107734
107851
  this.verticalRulerCenter.style.left = '-1000px';
107735
107852
  this.rulerTop = null;
107853
+ this.rulerBottom = null; //new
107736
107854
  this.rulerLeft = null;
107737
107855
  this.rulerRight = null;
107738
107856
  }
107739
107857
  updateRulers(block) {
107858
+ const container = block.closest('.box-canvas');
107859
+ this.horizontalRulerTop = container.querySelector('.h-ruler-top');
107860
+ this.horizontalRulerBottom = container.querySelector('.h-ruler-bottom');
107861
+ this.horizontalRulerMiddle = container.querySelector('.h-ruler-middle');
107862
+ this.verticalRulerLeft = container.querySelector('.v-ruler-left');
107863
+ this.verticalRulerRight = container.querySelector('.v-ruler-right');
107864
+ this.verticalRulerCenter = container.querySelector('.v-ruler-center');
107865
+ let transform = block.style.transform;
107866
+ if (transform.includes('rotate') || transform.includes('matrix3d')) return;
107867
+ let parentTransform = block.parentNode.style.transform;
107868
+ if (parentTransform.includes('rotate')) return;
107869
+ this.hideRulers();
107870
+ const top = block.offsetTop;
107871
+ const bottom = top + block.offsetHeight;
107872
+ const left = block.offsetLeft;
107873
+ const right = left + block.offsetWidth;
107874
+ const center = left + block.offsetWidth / 2;
107875
+ const middle = top + block.offsetHeight / 2;
107876
+ this.rulerTop = null;
107877
+ this.rulerBottom = null; //new
107878
+ this.rulerLeft = null;
107879
+ this.rulerRight = null;
107880
+ this.elements = container.querySelectorAll(this.selector);
107881
+ this.elements.forEach(element => {
107882
+ if (!this.doc.body.contains(element)) return; // in case element removed (eg. unGroup, block deleted)
107883
+
107884
+ if (block.contains(element)) return; // In case of group moving
107885
+
107886
+ let transform = element.style.transform;
107887
+ let parentTransform = element.parentNode.style.transform;
107888
+ if (!transform.includes('rotate') && !parentTransform.includes('rotate') && !transform.includes('matrix3d') && !parentTransform.includes('matrix3d') && element !== block && !element.classList.contains('cloned')) {
107889
+ const otherTop = element.offsetTop;
107890
+ const otherBottom = otherTop + element.offsetHeight;
107891
+ const otherLeft = element.offsetLeft;
107892
+ const otherRight = otherLeft + element.offsetWidth;
107893
+ const otherMiddle = otherTop + element.offsetHeight / 2;
107894
+ const otherCenter = otherLeft + element.offsetWidth / 2;
107895
+
107896
+ // block top
107897
+ if (otherTop - 4 <= top && top <= otherTop + 4) {
107898
+ this.horizontalRulerTop.style.top = otherTop + 'px';
107899
+ this.horizontalRulerTop.classList.add('active');
107900
+ let val = otherTop;
107901
+ if (this.rulerTop === null) this.rulerTop = val;
107902
+ }
107903
+ if (otherBottom - 4 <= top && top <= otherBottom + 4) {
107904
+ this.horizontalRulerTop.style.top = otherBottom + 'px';
107905
+ this.horizontalRulerTop.classList.add('active');
107906
+ let val = otherBottom;
107907
+ if (this.rulerTop === null) this.rulerTop = val;
107908
+ }
107909
+
107910
+ // block bottom
107911
+ if (otherTop - 4 <= bottom && bottom <= otherTop + 4) {
107912
+ /*
107913
+ _____
107914
+ ___________________|__x__|__ rulerBottom
107915
+ | other |
107916
+ */
107917
+ this.horizontalRulerBottom.style.top = otherTop + 'px';
107918
+ this.horizontalRulerBottom.classList.add('active');
107919
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop; // new
107920
+ }
107921
+
107922
+ if (otherBottom - 4 <= bottom && bottom <= otherBottom + 4) {
107923
+ /*
107924
+ _____
107925
+ | other |__________|__x__|__ rulerBottom
107926
+
107927
+ */
107928
+ this.horizontalRulerBottom.style.top = otherBottom + 'px';
107929
+ this.horizontalRulerBottom.classList.add('active');
107930
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop + element.offsetHeight; // new
107931
+ }
107932
+
107933
+ // block middle
107934
+ if (this.rulerTop === null && this.rulerBottom === null) {
107935
+ if (otherMiddle - 4 <= middle && middle <= otherMiddle + 4) {
107936
+ this.horizontalRulerMiddle.style.top = otherTop + (element.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
107937
+ this.horizontalRulerMiddle.classList.add('active');
107938
+ let val = otherTop + (element.offsetHeight - block.offsetHeight) / 2;
107939
+ if (this.rulerTop === null) this.rulerTop = val;
107940
+ }
107941
+ }
107942
+
107943
+ // block left
107944
+ if (otherLeft - 4 <= left && left <= otherLeft + 4) {
107945
+ this.verticalRulerLeft.style.left = otherLeft + 'px';
107946
+ this.verticalRulerLeft.classList.add('active');
107947
+ let val = otherLeft;
107948
+ if (this.rulerLeft === null) this.rulerLeft = val;
107949
+ }
107950
+ if (otherRight - 4 <= left && left <= otherRight + 4) {
107951
+ this.verticalRulerLeft.style.left = otherRight + 'px';
107952
+ this.verticalRulerLeft.classList.add('active');
107953
+ let val = otherRight;
107954
+ if (this.rulerLeft === null) this.rulerLeft = val;
107955
+ }
107956
+
107957
+ // block right
107958
+ if (otherLeft - 4 <= right && right <= otherLeft + 4) {
107959
+ this.verticalRulerRight.style.left = otherLeft + 'px';
107960
+ this.verticalRulerRight.classList.add('active');
107961
+ let val = otherLeft;
107962
+ if (this.rulerRight === null) this.rulerRight = val;
107963
+ }
107964
+ if (otherRight - 4 <= right && right <= otherRight + 4) {
107965
+ this.verticalRulerRight.style.left = otherRight + 'px';
107966
+ this.verticalRulerRight.classList.add('active');
107967
+ let val = otherRight;
107968
+ if (this.rulerRight === null) this.rulerRight = val;
107969
+ }
107970
+
107971
+ // block center
107972
+ if (this.rulerLeft === null && this.rulerRight === null) {
107973
+ if (otherCenter - 4 <= center && center <= otherCenter + 4) {
107974
+ this.verticalRulerCenter.style.left = otherLeft + (element.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
107975
+ this.verticalRulerCenter.classList.add('active');
107976
+ let val = otherLeft + (element.offsetWidth - block.offsetWidth) / 2;
107977
+ if (this.rulerLeft === null) this.rulerLeft = val;
107978
+ }
107979
+ }
107980
+ }
107981
+ });
107982
+
107983
+ // Edges
107984
+ const conTop = 0;
107985
+ const conBottom = container.offsetHeight;
107986
+ const conLeft = 0;
107987
+ const conRight = container.offsetWidth;
107988
+ const conCenter = container.offsetWidth / 2;
107989
+ const conMiddle = container.offsetHeight / 2;
107990
+
107991
+ // block top
107992
+ this.horizontalRulerTop.removeAttribute('data-topTouched');
107993
+ if (conTop - 4 <= top && top <= conTop + 4) {
107994
+ this.horizontalRulerTop.style.top = conTop + 'px';
107995
+ this.horizontalRulerTop.classList.add('active');
107996
+ let val = conTop;
107997
+ if (this.rulerTop === null) this.rulerTop = val;
107998
+ this.topTouched = true;
107999
+ this.horizontalRulerTop.setAttribute('data-topTouched', 1);
108000
+ }
108001
+
108002
+ // block bottom
108003
+ this.horizontalRulerBottom.removeAttribute('data-bottomTouched');
108004
+ if (conBottom - 4 <= bottom && bottom <= conBottom + 4) {
108005
+ this.horizontalRulerBottom.style.top = conBottom - 2 + 'px'; // -2 is an adjustment to make the line visible
108006
+ this.horizontalRulerBottom.classList.add('active');
108007
+ if (this.rulerBottom === null) this.rulerBottom = conBottom; //conRect.height;// or block.parentNode.offsetHeight; // new
108008
+
108009
+ this.bottomTouched = true;
108010
+ this.horizontalRulerBottom.setAttribute('data-bottomTouched', 1);
108011
+ }
108012
+
108013
+ // block middle
108014
+ if (this.rulerTop === null && this.rulerBottom === null) {
108015
+ if (conMiddle - 4 <= middle && middle <= conMiddle + 4) {
108016
+ this.horizontalRulerMiddle.style.top = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
108017
+ this.horizontalRulerMiddle.classList.add('active');
108018
+ let val = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2;
108019
+ if (this.rulerTop === null) this.rulerTop = val;
108020
+ }
108021
+ }
108022
+
108023
+ // block left
108024
+ this.verticalRulerLeft.removeAttribute('data-leftTouched');
108025
+ if (conLeft - 4 <= left && left <= conLeft + 4) {
108026
+ this.verticalRulerLeft.style.left = conLeft + 0 + 'px'; // +0 is an adjustment
108027
+ this.verticalRulerLeft.classList.add('active');
108028
+ let val = conLeft;
108029
+ if (this.rulerLeft === null) this.rulerLeft = val;
108030
+ this.verticalRulerLeft.setAttribute('data-leftTouched', 1);
108031
+ }
108032
+
108033
+ // block right
108034
+ this.verticalRulerRight.removeAttribute('data-rightTouched');
108035
+ if (conRight - 4 <= right && right <= conRight + 4) {
108036
+ this.verticalRulerRight.style.left = conRight - 2 + 'px'; // -2 is an adjustment
108037
+ this.verticalRulerRight.classList.add('active');
108038
+ let val = conRight;
108039
+ if (this.rulerRight === null) this.rulerRight = val;
108040
+ this.verticalRulerRight.setAttribute('data-rightTouched', 1);
108041
+ }
108042
+
108043
+ // block center
108044
+ if (this.rulerLeft === null && this.rulerRight === null) {
108045
+ if (conCenter - 4 <= center && center <= conCenter + 4) {
108046
+ this.verticalRulerCenter.style.left = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
108047
+ this.verticalRulerCenter.classList.add('active');
108048
+ let val = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2;
108049
+ if (this.rulerLeft === null) this.rulerLeft = val;
108050
+ }
108051
+ }
108052
+ }
108053
+ updateRulers_bak(block) {
107740
108054
  // if(block.querySelector(this.selector)) return; // group (because updateRules also calls parent group if child block is dragged)
107741
108055
 
107742
108056
  let transform = block.style.transform;
@@ -107754,6 +108068,7 @@ class Ruler {
107754
108068
  const center = left + block.offsetWidth / 2;
107755
108069
  const middle = top + block.offsetHeight / 2;
107756
108070
  this.rulerTop = null;
108071
+ this.rulerBottom = null; //new
107757
108072
  this.rulerLeft = null;
107758
108073
  this.rulerRight = null;
107759
108074
  let containerTop = 0;
@@ -107777,18 +108092,6 @@ class Ruler {
107777
108092
  const otherRight = rect.left + element.offsetWidth;
107778
108093
  const otherMiddle = rect.top + element.offsetHeight / 2;
107779
108094
  const otherCenter = rect.left + element.offsetWidth / 2;
107780
- if (otherMiddle - 4 <= middle && middle <= otherMiddle + 4) {
107781
- this.horizontalRulerMiddle.style.top = containerTop + otherTop + (element.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
107782
- let val = otherTop + (element.offsetHeight - block.offsetHeight) / 2;
107783
- if (this.rulerTop === null) this.rulerTop = val;
107784
- }
107785
- if (otherCenter - 4 <= center && center <= otherCenter + 4) {
107786
- this.verticalRulerCenter.style.left = otherLeft + (element.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
107787
- this.verticalRulerCenter.style.top = containerTop + 'px'; // adj
107788
-
107789
- let val = otherLeft + (element.offsetWidth - block.offsetWidth) / 2;
107790
- if (this.rulerLeft === null) this.rulerLeft = val;
107791
- }
107792
108095
 
107793
108096
  // block top
107794
108097
  if (otherTop - 4 <= top && top <= otherTop + 4) {
@@ -107804,14 +108107,38 @@ class Ruler {
107804
108107
 
107805
108108
  // block bottom
107806
108109
  if (otherTop - 4 <= bottom && bottom <= otherTop + 4) {
108110
+ /*
108111
+ _____
108112
+ ___________________|__x__|__ rulerBottom
108113
+ | other |
108114
+ */
107807
108115
  this.horizontalRulerBottom.style.top = containerTop + otherTop + 'px';
107808
- let val = otherTop - block.offsetHeight;
107809
- if (this.rulerTop === null) this.rulerTop = val;
108116
+
108117
+ // let val = otherTop - block.offsetHeight;
108118
+ // if(this.rulerTop===null) this.rulerTop = val;
108119
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop; // new
107810
108120
  }
108121
+
107811
108122
  if (otherBottom - 4 <= bottom && bottom <= otherBottom + 4) {
108123
+ /*
108124
+ _____
108125
+ | other |__________|__x__|__ rulerBottom
108126
+
108127
+ */
107812
108128
  this.horizontalRulerBottom.style.top = containerTop + otherBottom + 'px';
107813
- let val = otherBottom - block.offsetHeight;
107814
- if (this.rulerTop === null) this.rulerTop = val;
108129
+
108130
+ // let val = otherBottom - block.offsetHeight;
108131
+ // if(this.rulerTop===null) this.rulerTop = val;
108132
+ if (this.rulerBottom === null) this.rulerBottom = element.offsetTop + element.offsetHeight; // new
108133
+ }
108134
+
108135
+ // block middle
108136
+ if (this.rulerTop === null && this.rulerBottom === null) {
108137
+ if (otherMiddle - 4 <= middle && middle <= otherMiddle + 4) {
108138
+ this.horizontalRulerMiddle.style.top = containerTop + otherTop + (element.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
108139
+ let val = otherTop + (element.offsetHeight - block.offsetHeight) / 2;
108140
+ if (this.rulerTop === null) this.rulerTop = val;
108141
+ }
107815
108142
  }
107816
108143
 
107817
108144
  // block left
@@ -107845,6 +108172,17 @@ class Ruler {
107845
108172
  let val = otherRight;
107846
108173
  if (this.rulerRight === null) this.rulerRight = val;
107847
108174
  }
108175
+
108176
+ // block center
108177
+ if (this.rulerLeft === null && this.rulerRight === null) {
108178
+ if (otherCenter - 4 <= center && center <= otherCenter + 4) {
108179
+ this.verticalRulerCenter.style.left = otherLeft + (element.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
108180
+ this.verticalRulerCenter.style.top = containerTop + 'px'; // adj
108181
+
108182
+ let val = otherLeft + (element.offsetWidth - block.offsetWidth) / 2;
108183
+ if (this.rulerLeft === null) this.rulerLeft = val;
108184
+ }
108185
+ }
107848
108186
  }
107849
108187
  });
107850
108188
 
@@ -107856,44 +108194,69 @@ class Ruler {
107856
108194
  const conRight = conRect.left + block.parentNode.offsetWidth;
107857
108195
  const conCenter = conRect.left + block.parentNode.offsetWidth / 2;
107858
108196
  const conMiddle = conRect.top + block.parentNode.offsetHeight / 2;
107859
- if (conMiddle - 4 <= middle && middle <= conMiddle + 4) {
107860
- this.horizontalRulerMiddle.style.top = containerTop + conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
107861
- let val = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2;
107862
- if (this.rulerTop === null) this.rulerTop = val;
107863
- }
107864
- if (conCenter - 4 <= center && center <= conCenter + 4) {
107865
- this.verticalRulerCenter.style.left = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
107866
- this.verticalRulerCenter.style.top = containerTop + 'px';
107867
- let val = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2;
107868
- if (this.rulerLeft === null) this.rulerLeft = val;
107869
- }
107870
108197
 
107871
108198
  // block top
108199
+ this.horizontalRulerTop.removeAttribute('data-topTouched');
107872
108200
  if (conTop - 4 <= top && top <= conTop + 4) {
107873
108201
  this.horizontalRulerTop.style.top = containerTop + conTop + 'px';
107874
108202
  let val = conTop;
107875
108203
  if (this.rulerTop === null) this.rulerTop = val;
108204
+ this.topTouched = true;
108205
+ this.horizontalRulerTop.setAttribute('data-topTouched', 1);
107876
108206
  }
108207
+
107877
108208
  // block bottom
108209
+ this.horizontalRulerBottom.removeAttribute('data-bottomTouched');
107878
108210
  if (conBottom - 4 <= bottom && bottom <= conBottom + 4) {
107879
- this.horizontalRulerBottom.style.top = containerTop + conBottom - 3 + 'px'; // -3 is an adjustment to make the line visible
108211
+ this.horizontalRulerBottom.style.top = containerTop + conBottom - 2 + 'px'; // -2 is an adjustment to make the line visible
107880
108212
 
107881
- let val = conBottom - block.offsetHeight;
107882
- if (this.rulerTop === null) this.rulerTop = val;
108213
+ // let val = conBottom - block.offsetHeight;
108214
+ // if(this.rulerTop===null) this.rulerTop = val;
108215
+ if (this.rulerBottom === null) this.rulerBottom = conRect.height; // or block.parentNode.offsetHeight; // new
108216
+
108217
+ this.bottomTouched = true;
108218
+ this.horizontalRulerBottom.setAttribute('data-bottomTouched', 1);
107883
108219
  }
108220
+
108221
+ // block middle
108222
+ if (this.rulerTop === null && this.rulerBottom === null) {
108223
+ if (conMiddle - 4 <= middle && middle <= conMiddle + 4) {
108224
+ this.horizontalRulerMiddle.style.top = containerTop + conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2 + block.offsetHeight / 2 + 'px';
108225
+ let val = conTop + (block.parentNode.offsetHeight - block.offsetHeight) / 2;
108226
+ if (this.rulerTop === null) this.rulerTop = val;
108227
+ }
108228
+ }
108229
+
107884
108230
  // block left
108231
+ this.verticalRulerLeft.removeAttribute('data-leftTouched');
107885
108232
  if (conLeft - 4 <= left && left <= conLeft + 4) {
107886
- this.verticalRulerLeft.style.left = conLeft + 2 + 'px'; // +3 is an adjustment
107887
- this.verticalRulerLeft.style.top = containerTop + 'px';
108233
+ this.verticalRulerLeft.style.left = conLeft + 0 + 'px'; // +0 is an adjustment
108234
+ this.verticalRulerLeft.style.top = containerTop + 'px'; // adj
108235
+
107888
108236
  let val = conLeft;
107889
108237
  if (this.rulerLeft === null) this.rulerLeft = val;
108238
+ this.verticalRulerLeft.setAttribute('data-leftTouched', 1);
107890
108239
  }
108240
+
107891
108241
  // block right
108242
+ this.verticalRulerRight.removeAttribute('data-rightTouched');
107892
108243
  if (conRight - 4 <= right && right <= conRight + 4) {
107893
108244
  this.verticalRulerRight.style.left = conRight - 2 + 'px'; // -2 is an adjustment
107894
- this.verticalRulerRight.style.top = containerTop + 'px';
108245
+ this.verticalRulerRight.style.top = containerTop + 'px'; // adj
108246
+
107895
108247
  let val = conRight;
107896
108248
  if (this.rulerRight === null) this.rulerRight = val;
108249
+ this.verticalRulerRight.setAttribute('data-rightTouched', 1);
108250
+ }
108251
+
108252
+ // block center
108253
+ if (this.rulerLeft === null && this.rulerRight === null) {
108254
+ if (conCenter - 4 <= center && center <= conCenter + 4) {
108255
+ this.verticalRulerCenter.style.left = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2 + block.offsetWidth / 2 + 'px';
108256
+ this.verticalRulerCenter.style.top = containerTop + 'px';
108257
+ let val = conLeft + (block.parentNode.offsetWidth - block.offsetWidth) / 2;
108258
+ if (this.rulerLeft === null) this.rulerLeft = val;
108259
+ }
107897
108260
  }
107898
108261
  }
107899
108262
  }
@@ -108368,38 +108731,129 @@ class Resizable {
108368
108731
  }
108369
108732
 
108370
108733
  // Replace with ruler's alignment
108371
- if (this.ruler.rulerTop !== null) {
108372
- target.style.top = this.ruler.rulerTop + 'px';
108373
- // if container has top/left
108374
- if (target.parentNode.matches(this.selector)) {
108375
- const containerRect = target.parentNode.getBoundingClientRect();
108376
- target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
108734
+
108735
+ if (this.resizeHandle.includes('top')) {
108736
+ if (this.ruler.rulerTop !== null) {
108737
+ //bottom fixed
108738
+ let targetBottom = target.offsetTop + target.offsetHeight;
108739
+ target.style.top = this.ruler.rulerTop + 'px';
108740
+ target.style.height = targetBottom - this.ruler.rulerTop + 'px';
108377
108741
  }
108378
108742
  }
108379
-
108380
- // If resizing by dragging the right corners (top or bottom)
108381
- if (this.resizeHandle === 'top-right' || this.resizeHandle === 'bottom-right' || this.resizeHandle === 'right') {
108382
- // Check if vertical right ruler visible (has value)
108743
+ if (this.resizeHandle.includes('bottom')) {
108744
+ if (this.ruler.rulerBottom !== null) {
108745
+ // top fixed
108746
+ target.style.height = this.ruler.rulerBottom - target.offsetTop + 'px';
108747
+ }
108748
+ }
108749
+ if (this.resizeHandle.includes('left')) {
108750
+ if (this.ruler.rulerLeft !== null) {
108751
+ //right fixed
108752
+ let targetRight = target.offsetLeft + target.offsetWidth;
108753
+ target.style.left = this.ruler.rulerLeft + 'px';
108754
+ target.style.width = targetRight - this.ruler.rulerLeft + 'px';
108755
+ }
108756
+ }
108757
+ if (this.resizeHandle.includes('right')) {
108383
108758
  if (this.ruler.rulerRight !== null) {
108384
- // If so, keep the left position
108385
- // target.style.left = newLeft + 'px';
108759
+ //left fixed
108760
+ target.style.width = this.ruler.rulerRight - target.offsetLeft + 'px';
108761
+ }
108762
+ }
108386
108763
 
108387
- // And update the width to align with vertical right ruler
108388
- const rect = target.getBoundingClientRect();
108389
- target.style.width = this.ruler.rulerRight - rect.left + 'px';
108764
+ // Convert px to %
108765
+ this.common.applyPercentage(target);
108766
+ setTimeout(() => {
108767
+ const breakpoint = this.doc.body.getAttribute('data-breakpoint');
108768
+
108769
+ // const screenWidth = window.innerWidth;
108770
+ // let defaultPoint;
108771
+ // if(screenWidth<=1920) {
108772
+ // defaultPoint = 1366;
108773
+ // } else {
108774
+ // defaultPoint = 1900;
108775
+ // }
108776
+
108777
+ let largeScreenBreakpoint = 1280; //1920
108778
+ largeScreenBreakpoint = window.innerWidth - 360; //351
108779
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
108780
+ let isPrint = false;
108781
+ let elmBox = target.closest('[data-pagesize]');
108782
+ if (elmBox) {
108783
+ if (elmBox.getAttribute('data-pagesize').includes('web')) ; else {
108784
+ isPrint = true;
108785
+ }
108390
108786
  }
108391
- } else if (this.resizeHandle === 'top-left' || this.resizeHandle === 'bottom-left' || this.resizeHandle === 'left') {
108392
- if (this.ruler.rulerLeft !== null) {
108393
- const currentRight = this.initialLeft + this.initialWidth;
108787
+ if (isPrint) {
108788
+ target.setAttribute('data--t', target.style.top);
108789
+ target.setAttribute('data--l', target.style.left);
108790
+ target.setAttribute('data--b', target.style.bottom);
108791
+ target.setAttribute('data--r', target.style.right);
108792
+ target.setAttribute('data--w', target.style.width);
108793
+ target.setAttribute('data--h', target.style.height);
108794
+ } else {
108795
+ if (breakpoint && breakpoint < largeScreenBreakpoint) {
108796
+ target.setAttribute('data--t-' + breakpoint, target.style.top);
108797
+ target.setAttribute('data--l-' + breakpoint, target.style.left);
108798
+ target.setAttribute('data--b-' + breakpoint, target.style.bottom);
108799
+ target.setAttribute('data--r-' + breakpoint, target.style.right);
108800
+ if (!target.classList.contains('fluid')) target.setAttribute('data--w-' + breakpoint, target.style.width);
108801
+ target.setAttribute('data--h-' + breakpoint, target.style.height);
108802
+ } else {
108803
+ target.setAttribute('data--t', target.style.top);
108804
+ target.setAttribute('data--l', target.style.left);
108805
+ target.setAttribute('data--b', target.style.bottom);
108806
+ target.setAttribute('data--r', target.style.right);
108807
+ target.setAttribute('data--w', target.style.width);
108808
+ target.setAttribute('data--h', target.style.height);
108809
+ }
108810
+ }
108811
+ target.removeAttribute('data-prev'); // reset
108812
+ target.removeAttribute('data-fluid');
108813
+ }, 30); // delay needed since we use updateHeight() previously that has 20ms process
108394
108814
 
108395
- // if container has top/left
108396
- const containerRect = target.parentNode.getBoundingClientRect();
108397
- this.ruler.rulerLeft = this.ruler.rulerLeft - containerRect.left;
108815
+ if (this.onChange) this.onChange();
108816
+ }
108817
+ updateBlockStyle_bak(target) {
108818
+ if (target.querySelector(this.selector)) ; else {
108819
+ // this.common.updateHeight(target);
108820
+ if (target.classList.contains('height-auto')) target.style.height = '';
108821
+ }
108398
108822
 
108399
- // And update the width to align with vertical left ruler
108400
- target.style.left = this.ruler.rulerLeft + 'px';
108401
- let newWidth = currentRight - this.ruler.rulerLeft;
108402
- target.style.width = newWidth + 'px';
108823
+ // Replace with ruler's alignment
108824
+ const containerRect = this.common.getRect(target.parentNode); // if container has top/left
108825
+
108826
+ if (this.resizeHandle.includes('top')) {
108827
+ if (this.ruler.rulerTop !== null) {
108828
+ //bottom fixed
108829
+ const rect = target.getBoundingClientRect();
108830
+ let targetBottom = rect.top + rect.height;
108831
+ target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
108832
+ target.style.height = targetBottom - this.ruler.rulerTop + 'px';
108833
+ }
108834
+ }
108835
+ if (this.resizeHandle.includes('bottom')) {
108836
+ if (this.ruler.rulerBottom !== null) {
108837
+ // top fixed
108838
+ // const rect = target.getBoundingClientRect();
108839
+ // target.style.height = this.ruler.rulerBottom - rect.top + containerRect.top + 'px';
108840
+ target.style.height = this.ruler.rulerBottom - target.offsetTop + 'px';
108841
+ }
108842
+ }
108843
+ if (this.resizeHandle.includes('left')) {
108844
+ if (this.ruler.rulerLeft !== null) {
108845
+ //right fixed
108846
+ const rect = target.getBoundingClientRect();
108847
+ let targetRight = rect.left + rect.width;
108848
+ target.style.left = this.ruler.rulerLeft - containerRect.left + 'px';
108849
+ target.style.width = targetRight - this.ruler.rulerLeft + 'px';
108850
+ }
108851
+ }
108852
+ if (this.resizeHandle.includes('right')) {
108853
+ if (this.ruler.rulerRight !== null) {
108854
+ //left fixed
108855
+ const rect = target.getBoundingClientRect();
108856
+ target.style.width = this.ruler.rulerRight - rect.left + 'px';
108403
108857
  }
108404
108858
  }
108405
108859
 
@@ -108416,8 +108870,9 @@ class Resizable {
108416
108870
  // defaultPoint = 1900;
108417
108871
  // }
108418
108872
 
108419
- const largeScreenBreakpoint = 1920; //1920
108420
-
108873
+ let largeScreenBreakpoint = 1280; //1920
108874
+ largeScreenBreakpoint = window.innerWidth - 360; //351
108875
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
108421
108876
  let isPrint = false;
108422
108877
  let elmBox = target.closest('[data-pagesize]');
108423
108878
  if (elmBox) {
@@ -108601,6 +109056,10 @@ class Draggable {
108601
109056
  const y = startY - rect.top + containerRect.top;
108602
109057
  target.setAttribute('data-startx', x);
108603
109058
  target.setAttribute('data-starty', y);
109059
+
109060
+ // reset (from applyPercentage bottomTouched)
109061
+ target.style.height = target.offsetHeight + 'px';
109062
+ target.style.bottom = '';
108604
109063
  this.common.applyPixels(target);
108605
109064
  });
108606
109065
  this.clickedBlock = this.common.getSelectedBlock();
@@ -108668,10 +109127,9 @@ class Draggable {
108668
109127
  }
108669
109128
  updateBlockStyle(target) {
108670
109129
  // Replace with ruler's alignment
108671
- const containerRect = this.common.getRect(target.parentNode); // if container has top/left
108672
- const initialWidth = parseFloat(getComputedStyle(target).width);
108673
- if (this.ruler.rulerTop !== null) target.style.top = this.ruler.rulerTop - containerRect.top + 'px';
108674
- 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';
109130
+ if (this.ruler.rulerTop !== null) target.style.top = this.ruler.rulerTop + 'px';
109131
+ if (this.ruler.rulerBottom !== null) target.style.top = this.ruler.rulerBottom - target.offsetHeight + 'px'; //new
109132
+ 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';
108675
109133
  this.doc.querySelectorAll('[data-startx]').forEach(elm => elm.removeAttribute('data-startx'));
108676
109134
  this.doc.querySelectorAll('[data-starty]').forEach(elm => elm.removeAttribute('data-starty'));
108677
109135
  this.common.applyPercentage(target);
@@ -108685,8 +109143,9 @@ class Draggable {
108685
109143
  // defaultPoint = 1900;
108686
109144
  // }
108687
109145
 
108688
- const largeScreenBreakpoint = 1920; //1920
108689
-
109146
+ let largeScreenBreakpoint = 1280; //1920
109147
+ largeScreenBreakpoint = window.innerWidth - 360; //351
109148
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
108690
109149
  let isPrint = false;
108691
109150
  let elmBox = target.closest('[data-pagesize]');
108692
109151
  if (elmBox) {
@@ -109361,6 +109820,9 @@ class EditableBlocks {
109361
109820
  win: this.win,
109362
109821
  onContentClick: this.onContentClick,
109363
109822
  onEditStart: (event, block) => {
109823
+ const container = block.querySelector('.is-container');
109824
+ if (!container) return; // if block is empty, no edit required
109825
+
109364
109826
  if (block.classList.contains('clone')) {
109365
109827
  const clonedTarget = this.doc.querySelector(this.selector + '.cloned');
109366
109828
  this.onEditStart(event, clonedTarget);
@@ -109531,133 +109993,181 @@ class BlockModal {
109531
109993
  </div>
109532
109994
  </div>
109533
109995
 
109996
+ <div class="label-page-grayscale label checkbox grayscale" style="padding:30px 0 10px;">
109997
+ <label class="label-checkbox" for="chkPageGrayscale"><input id="chkPageGrayscale" class="chk-grayscale" type="checkbox" /> ${util.out('Grayscale')}</label>
109998
+ </div>
109999
+
110000
+ <div style="padding-top:30px;padding-bottom:3px;">${util.out('Auto layout on mobile')}:</div>
110001
+
110002
+ <label class="switch"><input id="inpAutoLayout" type="checkbox" checked=""><span class="slider round"></span></label>
110003
+
109534
110004
  </div>
109535
110005
 
109536
- <div class="modal-content">
110006
+ <div class="modal-content" style="padding:0">
109537
110007
 
109538
- <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
109539
- <div style="display:flex;">
109540
- <button title="${util.out('Background Color')}" class="input-block-bgcolor is-btn-color" style="margin-right:15px"></button>
109541
- <button title="${util.out('Gradient')}" class="btn-block-gradient classic" data-value="+"> ${util.out('Gradient')} </button>
110008
+ <div class="is-tabs" data-group="blocksettings" style="background-color:transparent">
110009
+ <a title="${util.out('General')}" id="tabBlockGeneral" href="#" data-content="divBlockGeneral" class="active">${util.out('General')}</a>
110010
+ <a title="${util.out('More')}" id="tabBlockMore" href="#" data-content="divBlockMore">${util.out('More')}</a>
109542
110011
  </div>
109543
110012
 
109544
- <div style="padding-top:20px;padding-bottom: 3px;">${util.out('Background Image')}:</div>
109545
- <div>
109546
- <div class="asset-block-preview" style="display:none"></div>
109547
- <div style="display: flex">
109548
- <button title="${util.out('Image')}" class="btn-block-bgimage">
109549
- <svg class="is-icon-flex"><use xlink:href="#ion-image"></use></svg>
109550
- <span>${util.out('Image')}</span>
110013
+ <div id="divBlockMore" class="is-tab-content" data-group="blocksettings" tabindex="-1" style="padding:25px 25px 28px">
110014
+
110015
+ <div class="div-target" style="display: flex;justify-content: flex-end;padding: 5px 0 0;">
110016
+ <button title="${util.out('Desktop')}" class="input-device on" data-value="" style="width:40px;height:25px;">
110017
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-device-desktop"></use></svg>
110018
+ </button>
110019
+ <button title="${util.out('Laptop/Tablet (Landscape)')}" class="input-device" data-value="md" style="width:40px;height:25px;">
110020
+ <svg class="is-icon-flex" style="width:16px;height:16px;transform:rotate(-90deg)"><use xlink:href="#icon-device-tablet"></use></svg>
110021
+ </button>
110022
+ <button title="${util.out('Tablet (Portrait)')}" class="input-device" data-value="sm" style="width:40px;height:25px;">
110023
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-device-tablet"></use></svg>
110024
+ </button>
110025
+ <button title="${util.out('Mobile')}" class="input-device" data-value="xs" style="width:40px;height:25px;">
110026
+ <svg class="is-icon-flex" style="width:13px;height:13px"><use xlink:href="#icon-device-mobile"></use></svg>
109551
110027
  </button>
109552
- <button title="${util.out('Select')}" class="btn-block-asset">${this.builder.opts.selectIcon}</button>
109553
- <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>
109554
- <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>
109555
110028
  </div>
109556
- </div>
109557
110029
 
109558
- <div class="div-content-textcolor flex flex-col">
109559
- <div style="padding-top:20px;padding-bottom:3px;">${util.out('Text Color')}:</div>
109560
- <div class="flex flex-row">
109561
- <button title="0" data-textcolor="dark">${util.out('Dark')}</button>
109562
- <button title="10" data-textcolor="light">${util.out('Light')}</button>
109563
-
109564
- <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>
110030
+ <div style="padding-top:0;padding-bottom:3px;">${util.out('Visibility')}:</div>
110031
+ <div class="div-visibility" style="display:flex;">
110032
+ <button title="${util.out('Visible')}" class="input-visible on" data-value="sm" style="width:100px;height:34px;">
110033
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-eye"></use></svg>
110034
+ <span>${util.out('Visible')}</span>
110035
+ </button>
110036
+ <button title="${util.out('Hidden')}" class="input-hidden" data-value="xs" style="width:100px;height:34px;">
110037
+ <svg class="is-icon-flex" style="width:16px;height:16px"><use xlink:href="#icon-eye-off"></use></svg>
110038
+ <span>${util.out('Hidden')}</span>
110039
+ </button>
109565
110040
  </div>
110041
+
109566
110042
  </div>
109567
110043
 
109568
- <div class="label checkbox grayscale" style="padding:30px 0 10px;">
109569
- <label class="label-block-grayscale label-checkbox" for="chkBlockGrayscale"><input id="chkBlockGrayscale" class="chk-grayscale" type="checkbox" /> ${util.out('Grayscale')}</label>
109570
- </div>
110044
+ <div id="divBlockGeneral" class="is-tab-content active" data-group="blocksettings" style="display:flex" tabindex="-1" style="padding:25px 25px 28px">
109571
110045
 
109572
- <button title="${util.out('Remove Content/Text')}" class="btn-clear-text" style="margin-top:20px">
109573
- <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
109574
- <span>${util.out('Remove Content/Text')}</span>
109575
- </button>
110046
+ <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
110047
+ <div style="display:flex;">
110048
+ <button title="${util.out('Background Color')}" class="input-block-bgcolor is-btn-color" style="margin-right:15px"></button>
110049
+ <button title="${util.out('Gradient')}" class="btn-block-gradient classic" data-value="+"> ${util.out('Gradient')} </button>
110050
+ </div>
109576
110051
 
109577
- <button title="${util.out('Clear Breakpoints')}" class="btn-clear-breakpoint" style="margin-top:20px">
109578
- <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
109579
- <span>${util.out('Clear Breakpoints')}</span>
109580
- </button>
110052
+ <div style="padding-top:20px;padding-bottom: 3px;">${util.out('Background Image')}:</div>
110053
+ <div>
110054
+ <div class="asset-block-preview" style="display:none"></div>
110055
+ <div style="display: flex">
110056
+ <button title="${util.out('Image')}" class="btn-block-bgimage">
110057
+ <svg class="is-icon-flex"><use xlink:href="#ion-image"></use></svg>
110058
+ <span>${util.out('Image')}</span>
110059
+ </button>
110060
+ <button title="${util.out('Select')}" class="btn-block-asset">${this.builder.opts.selectIcon}</button>
110061
+ <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>
110062
+ <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>
110063
+ </div>
110064
+ </div>
109581
110065
 
109582
- <div style="padding-top:23px;padding-bottom:3px;">${util.out('Lock')}:</div>
110066
+ <div class="div-content-textcolor flex flex-col">
110067
+ <div style="padding-top:20px;padding-bottom:3px;">${util.out('Text Color')}:</div>
110068
+ <div class="flex flex-row">
110069
+ <button title="0" data-textcolor="dark">${util.out('Dark')}</button>
110070
+ <button title="10" data-textcolor="light">${util.out('Light')}</button>
110071
+
110072
+ <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>
110073
+ </div>
110074
+ </div>
109583
110075
 
109584
- <label class="switch"><input id="inpLockBlock" type="checkbox" checked=""><span class="slider round"></span></label>
110076
+ <div class="label-block-grayscale label checkbox grayscale" style="padding:30px 0 10px;">
110077
+ <label class="label-checkbox" for="chkBlockGrayscale"><input id="chkBlockGrayscale" class="chk-grayscale" type="checkbox" /> ${util.out('Grayscale')}</label>
110078
+ </div>
109585
110079
 
109586
- <div id="divBlockPos">
110080
+ <button title="${util.out('Remove Content/Text')}" class="btn-clear-text" style="margin-top:20px">
110081
+ <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
110082
+ <span>${util.out('Remove Content/Text')}</span>
110083
+ </button>
109587
110084
 
109588
- <div class="flex" style="gap:10px">
109589
- <div>
109590
- <label for="inpBlockTop" class="flex" style="padding:10px 0 3px;">${util.out('Top')}:</label>
109591
- <div style="display:flex">
109592
- <input id="inpBlockTop" class="inp-block-top" type="text" style="width:74px;height:35px">
109593
- <select id="inpBlockTopUnit">
109594
- <option></option>
109595
- <option>px</option>
109596
- <option>%</option>
109597
- </select>
110085
+ <button title="${util.out('Clear Breakpoints')}" class="btn-clear-breakpoint" style="margin-top:20px">
110086
+ <svg class="is-icon-flex"><use xlink:href="#icon-trash"></use></svg>
110087
+ <span>${util.out('Clear Breakpoints')}</span>
110088
+ </button>
110089
+
110090
+ <div style="padding-top:23px;padding-bottom:3px;">${util.out('Lock')}:</div>
110091
+
110092
+ <label class="switch"><input id="inpLockBlock" type="checkbox" checked=""><span class="slider round"></span></label>
110093
+
110094
+ <div id="divBlockPos">
110095
+
110096
+ <div class="flex" style="gap:10px">
110097
+ <div>
110098
+ <label for="inpBlockTop" class="flex" style="padding:10px 0 3px;">${util.out('Top')}:</label>
110099
+ <div style="display:flex">
110100
+ <input id="inpBlockTop" class="inp-block-top" type="text" style="width:74px;height:35px">
110101
+ <select id="inpBlockTopUnit">
110102
+ <option></option>
110103
+ <option>px</option>
110104
+ <option>%</option>
110105
+ </select>
110106
+ </div>
109598
110107
  </div>
109599
- </div>
109600
- <div>
109601
- <label for="inpBlockBottom" class="flex" style="padding:10px 0 3px;">${util.out('Bottom')}:</label>
109602
- <div style="display:flex">
109603
- <input id="inpBlockBottom" class="inp-block-top" type="text" style="width:74px;height:35px">
109604
- <select id="inpBlockBottomUnit">
109605
- <option></option>
109606
- <option>px</option>
109607
- <option>%</option>
109608
- </select>
110108
+ <div>
110109
+ <label for="inpBlockBottom" class="flex" style="padding:10px 0 3px;">${util.out('Bottom')}:</label>
110110
+ <div style="display:flex">
110111
+ <input id="inpBlockBottom" class="inp-block-top" type="text" style="width:74px;height:35px">
110112
+ <select id="inpBlockBottomUnit">
110113
+ <option></option>
110114
+ <option>px</option>
110115
+ <option>%</option>
110116
+ </select>
110117
+ </div>
109609
110118
  </div>
109610
110119
  </div>
109611
- </div>
109612
110120
 
109613
- <div class="flex" style="gap:10px">
109614
- <div>
109615
- <label for="inpBlockLeft" class="flex" style="padding:10px 0 3px;">${util.out('Left')}:</label>
109616
- <div style="display:flex">
109617
- <input id="inpBlockLeft" class="inp-block-left" type="text" style="width:74px;height:35px">
109618
- <select id="inpBlockLeftUnit">
109619
- <option></option>
109620
- <option>px</option>
109621
- <option>%</option>
109622
- </select>
110121
+ <div class="flex" style="gap:10px">
110122
+ <div>
110123
+ <label for="inpBlockLeft" class="flex" style="padding:10px 0 3px;">${util.out('Left')}:</label>
110124
+ <div style="display:flex">
110125
+ <input id="inpBlockLeft" class="inp-block-left" type="text" style="width:74px;height:35px">
110126
+ <select id="inpBlockLeftUnit">
110127
+ <option></option>
110128
+ <option>px</option>
110129
+ <option>%</option>
110130
+ </select>
110131
+ </div>
109623
110132
  </div>
109624
- </div>
109625
- <div>
109626
- <label for="inpBlockRight" class="flex" style="padding:10px 0 3px;">${util.out('Right')}:</label>
109627
- <div style="display:flex">
109628
- <input id="inpBlockRight" class="inp-block-left" type="text" style="width:74px;height:35px">
109629
- <select id="inpBlockRightUnit">
109630
- <option></option>
109631
- <option>px</option>
109632
- <option>%</option>
109633
- </select>
110133
+ <div>
110134
+ <label for="inpBlockRight" class="flex" style="padding:10px 0 3px;">${util.out('Right')}:</label>
110135
+ <div style="display:flex">
110136
+ <input id="inpBlockRight" class="inp-block-left" type="text" style="width:74px;height:35px">
110137
+ <select id="inpBlockRightUnit">
110138
+ <option></option>
110139
+ <option>px</option>
110140
+ <option>%</option>
110141
+ </select>
110142
+ </div>
109634
110143
  </div>
109635
110144
  </div>
109636
- </div>
109637
110145
 
109638
- <div class="flex" style="gap:10px">
109639
- <div>
109640
- <label for="inpBlockWidth" class="flex" style="padding:10px 0 3px;">${util.out('Width')}:</label>
109641
- <div style="display:flex">
109642
- <input id="inpBlockWidth" class="inp-block-left" type="text" style="width:74px;height:35px">
109643
- <select id="inpBlockWidthUnit">
109644
- <option></option>
109645
- <option>px</option>
109646
- <option>%</option>
109647
- </select>
110146
+ <div class="flex" style="gap:10px">
110147
+ <div>
110148
+ <label for="inpBlockWidth" class="flex" style="padding:10px 0 3px;">${util.out('Width')}:</label>
110149
+ <div style="display:flex">
110150
+ <input id="inpBlockWidth" class="inp-block-left" type="text" style="width:74px;height:35px">
110151
+ <select id="inpBlockWidthUnit">
110152
+ <option></option>
110153
+ <option>px</option>
110154
+ <option>%</option>
110155
+ </select>
110156
+ </div>
109648
110157
  </div>
109649
- </div>
109650
- <div>
109651
- <label for="inpBlockHeight" class="flex" style="padding:10px 0 3px;">${util.out('Height')}:</label>
109652
- <div style="display:flex">
109653
- <input id="inpBlockHeight" class="inp-block-left" type="text" style="width:74px;height:35px">
109654
- <select id="inpBlockHeightUnit">
109655
- <option></option>
109656
- <option>px</option>
109657
- <option>%</option>
109658
- </select>
110158
+ <div>
110159
+ <label for="inpBlockHeight" class="flex" style="padding:10px 0 3px;">${util.out('Height')}:</label>
110160
+ <div style="display:flex">
110161
+ <input id="inpBlockHeight" class="inp-block-left" type="text" style="width:74px;height:35px">
110162
+ <select id="inpBlockHeightUnit">
110163
+ <option></option>
110164
+ <option>px</option>
110165
+ <option>%</option>
110166
+ </select>
110167
+ </div>
109659
110168
  </div>
109660
110169
  </div>
110170
+
109661
110171
  </div>
109662
110172
 
109663
110173
  </div>
@@ -109759,19 +110269,19 @@ class BlockModal {
109759
110269
  const btnPageBgImage = modal.querySelector('.btn-page-bgimage');
109760
110270
  if (btnPageBgImage) dom.addEventListener(btnPageBgImage, 'click', () => {
109761
110271
  // Background image
109762
- const page = this.getPage();
110272
+ let pageOverlay = this.pageOverlay();
109763
110273
  let src = '';
109764
- if (page) if (page.style.backgroundImage) {
109765
- if (page.style.backgroundImage.indexOf('url(') !== -1) {
109766
- src = page.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
110274
+ if (pageOverlay) if (pageOverlay.style.backgroundImage) {
110275
+ if (pageOverlay.style.backgroundImage.indexOf('url(') !== -1) {
110276
+ src = pageOverlay.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
109767
110277
  }
109768
110278
  }
109769
110279
  this.openImagePicker(src, url => {
109770
- const page = this.getPage();
110280
+ let pageOverlay = this.pageOverlay();
109771
110281
  this.builder.uo.saveForUndo();
109772
- page.style.backgroundImage = `url("${url}")`;
109773
- page.style.backgroundSize = 'cover';
109774
- page.style.backgroundRepeat = 'no-repeat';
110282
+ pageOverlay.style.backgroundImage = `url("${url}")`;
110283
+ pageOverlay.style.backgroundSize = 'cover';
110284
+ pageOverlay.style.backgroundRepeat = 'no-repeat';
109775
110285
  const div = this.pageImagePreview;
109776
110286
  const btnPageAdjust = modal.querySelector('.btn-page-adjust');
109777
110287
  const btnPageClear = modal.querySelector('.btn-page-clear');
@@ -109802,10 +110312,44 @@ class BlockModal {
109802
110312
  });
109803
110313
  const btnPageAdjust = modal.querySelector('.btn-page-adjust');
109804
110314
  btnPageAdjust.addEventListener('click', () => {
109805
- let page = this.getPage();
109806
- this.builder.colTool.openImageAdjust(page, btnPageAdjust);
110315
+ let pageOverlay = this.pageOverlay();
110316
+ this.builder.colTool.openImageAdjust(pageOverlay, btnPageAdjust);
110317
+ });
110318
+ const chkPageGrayscale = modal.querySelector('#chkPageGrayscale');
110319
+ chkPageGrayscale.addEventListener('click', () => {
110320
+ this.builder.uo.saveForUndo();
110321
+ let pageOverlay = this.pageOverlay();
110322
+ const checked = chkPageGrayscale.checked;
110323
+ if (checked) {
110324
+ pageOverlay.style.filter = 'grayscale(1)';
110325
+ } else {
110326
+ if (pageOverlay.style.filter) pageOverlay.style.filter = pageOverlay.style.filter.replace('grayscale(1)', '');
110327
+ }
110328
+ this.builder.onChange();
109807
110329
  });
109808
110330
 
110331
+ // Page Auto Layout
110332
+ const chkAutoLayout = modal.querySelector('#inpAutoLayout');
110333
+ chkAutoLayout.addEventListener(this.builder.isTouchSupport ? 'touchstart' : 'click', () => {
110334
+ const page = this.getPage();
110335
+ if (chkAutoLayout.checked) {
110336
+ page.classList.add('autolayout');
110337
+ } else {
110338
+ page.classList.remove('autolayout');
110339
+ }
110340
+ });
110341
+ if (this.builder.isTouchSupport) {
110342
+ let chkAutoLayoutLabel = chkAutoLayout.parentNode;
110343
+ chkAutoLayoutLabel.addEventListener('touchstart', () => {
110344
+ const page = this.getPage();
110345
+ if (chkAutoLayout.checked) {
110346
+ page.classList.add('autolayout');
110347
+ } else {
110348
+ page.classList.remove('autolayout');
110349
+ }
110350
+ });
110351
+ }
110352
+
109809
110353
  // Block Background Image
109810
110354
 
109811
110355
  this.imagePreview = modal.querySelector('.asset-block-preview');
@@ -109858,7 +110402,7 @@ class BlockModal {
109858
110402
  let blockOverlay = this.blockOverlay();
109859
110403
  this.builder.colTool.openImageAdjust(blockOverlay, btnAdjust);
109860
110404
  });
109861
- const chkGrayscale = modal.querySelector('.chk-grayscale');
110405
+ const chkGrayscale = modal.querySelector('#chkBlockGrayscale');
109862
110406
  chkGrayscale.addEventListener('click', () => {
109863
110407
  this.builder.uo.saveForUndo();
109864
110408
  let blockOverlay = this.blockOverlay();
@@ -110085,6 +110629,62 @@ class BlockModal {
110085
110629
  }
110086
110630
  });
110087
110631
  }
110632
+
110633
+ // Responsive Visibility
110634
+
110635
+ let btns = modal.querySelectorAll('.input-device');
110636
+ btns.forEach(btn => {
110637
+ btn.addEventListener('click', () => {
110638
+ const block = this.blockSelected();
110639
+ let elms = modal.querySelectorAll('.input-device');
110640
+ elms.forEach(elm => {
110641
+ elm.classList.remove('on');
110642
+ });
110643
+ btn.classList.add('on');
110644
+ this.realtimeVisibility(block);
110645
+ });
110646
+ });
110647
+ let btnVisible = modal.querySelector('.input-visible');
110648
+ let btnHidden = modal.querySelector('.input-hidden');
110649
+ btnVisible.addEventListener('click', () => {
110650
+ const block = this.blockSelected();
110651
+ this.builder.uo.saveForUndo();
110652
+ let divTarget = modal.querySelector('.div-target');
110653
+ let target = this.builder.responsive.readTarget(divTarget);
110654
+ if (target === 'xs') {
110655
+ block.classList.remove('xs-hidden');
110656
+ } else if (target === 'sm') {
110657
+ block.classList.remove('sm-hidden');
110658
+ } else if (target === 'md') {
110659
+ block.classList.remove('md-hidden');
110660
+ } else if (target === '') {
110661
+ block.classList.remove('desktop-hidden');
110662
+ }
110663
+ btnVisible.classList.add('on');
110664
+ btnHidden.classList.remove('on');
110665
+ this.builder.opts.onChange();
110666
+ });
110667
+ btnHidden.addEventListener('click', () => {
110668
+ const block = this.blockSelected();
110669
+ this.builder.uo.saveForUndo();
110670
+ let divTarget = modal.querySelector('.div-target');
110671
+ let target = this.builder.responsive.readTarget(divTarget);
110672
+ if (target === 'xs') {
110673
+ block.classList.add('xs-hidden');
110674
+ } else if (target === 'sm') {
110675
+ block.classList.add('sm-hidden');
110676
+ } else if (target === 'md') {
110677
+ block.classList.add('md-hidden');
110678
+ } else if (target === '') {
110679
+ block.classList.add('desktop-hidden');
110680
+ }
110681
+ btnVisible.classList.remove('on');
110682
+ btnHidden.classList.add('on');
110683
+ this.builder.opts.onChange();
110684
+ });
110685
+ new Tabs({
110686
+ element: modal
110687
+ });
110088
110688
  } // constructor
110089
110689
 
110090
110690
  getPage() {
@@ -110116,6 +110716,16 @@ class BlockModal {
110116
110716
  // this.builder.eb.common.applyPercentage(target);
110117
110717
  }
110118
110718
 
110719
+ pageOverlay() {
110720
+ const page = this.getPage();
110721
+ if (!page) return false;
110722
+ let pageOverlay = page.querySelector('.is-page-overlay');
110723
+ if (!pageOverlay) {
110724
+ page.insertAdjacentHTML('afterbegin', '<div class="is-page-overlay"></div>');
110725
+ pageOverlay = page.querySelector('.is-page-overlay');
110726
+ }
110727
+ return pageOverlay;
110728
+ }
110119
110729
  blockOverlay() {
110120
110730
  const block = this.builder.doc.querySelector('.is-block.active:not(.multi)');
110121
110731
  if (!block) return false;
@@ -110132,6 +110742,7 @@ class BlockModal {
110132
110742
  }
110133
110743
  realtime() {
110134
110744
  const modal = this.modal;
110745
+ if (!modal.classList.contains('active')) return;
110135
110746
  const page = this.getPage();
110136
110747
  const block = this.blockSelected();
110137
110748
  if (block) {
@@ -110174,7 +110785,7 @@ class BlockModal {
110174
110785
  }
110175
110786
 
110176
110787
  // Grayscale
110177
- const chkGrayscale = modal.querySelector('.chk-grayscale');
110788
+ const chkGrayscale = modal.querySelector('#chkBlockGrayscale');
110178
110789
  chkGrayscale.checked = false;
110179
110790
  if (blockOverlay) {
110180
110791
  if (blockOverlay.style.filter) {
@@ -110325,23 +110936,38 @@ class BlockModal {
110325
110936
  inpHeight.value = '';
110326
110937
  inpHeightUnit.value = '%';
110327
110938
  }
110939
+ this.realtimeVisibility(block);
110328
110940
  } else if (page) {
110941
+ let pageOverlay = this.pageOverlay();
110942
+
110329
110943
  // Background image
110330
110944
  let src = '';
110331
- if (page) if (page.style.backgroundImage) {
110332
- if (page.style.backgroundImage.indexOf('url(') !== -1) {
110333
- src = page.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
110945
+ if (pageOverlay) if (pageOverlay.style.backgroundImage) {
110946
+ if (pageOverlay.style.backgroundImage.indexOf('url(') !== -1) {
110947
+ src = pageOverlay.style.backgroundImage.slice(4, -1).replace(/["']/g, '');
110334
110948
  }
110335
110949
  }
110336
110950
 
110337
110951
  // Update preview
110338
110952
  this.updatePanelPageImage(src);
110339
110953
 
110340
- // Show/hide
110954
+ // Show/hide grayscale
110955
+ const divPageGrayscale = modal.querySelector('.label-page-grayscale');
110341
110956
  if (src === '') {
110342
110957
  this.pageImagePreview.style.display = 'none';
110958
+ divPageGrayscale.style.display = 'none';
110343
110959
  } else {
110344
110960
  this.pageImagePreview.style.display = '';
110961
+ divPageGrayscale.style.display = '';
110962
+ }
110963
+
110964
+ // Grayscale
110965
+ const chkPageGrayscale = modal.querySelector('#chkPageGrayscale');
110966
+ chkPageGrayscale.checked = false;
110967
+ if (pageOverlay.style.filter) {
110968
+ if (pageOverlay.style.filter.indexOf('grayscale') !== -1) {
110969
+ chkPageGrayscale.checked = true;
110970
+ }
110345
110971
  }
110346
110972
 
110347
110973
  // Background color
@@ -110364,6 +110990,58 @@ class BlockModal {
110364
110990
  } else {
110365
110991
  btnPageGradient.style.backgroundImage = '';
110366
110992
  }
110993
+
110994
+ // Page Auto Layout
110995
+ const chkAutoLayout = modal.querySelector('#inpAutoLayout');
110996
+ if (page.classList.contains('autolayout')) {
110997
+ chkAutoLayout.checked = true;
110998
+ } else {
110999
+ chkAutoLayout.checked = false;
111000
+ }
111001
+ }
111002
+ }
111003
+ realtimeVisibility(row, initialOpen) {
111004
+ if (!this.modal) return;
111005
+ if (initialOpen) {
111006
+ const builderStuff = this.builder.builderStuff;
111007
+ const modal = builderStuff.querySelector('.is-modal.content-preview.active');
111008
+ if (modal) {
111009
+ let elms = this.modal.querySelectorAll('.input-device');
111010
+ elms.forEach(elm => {
111011
+ elm.classList.remove('on');
111012
+ });
111013
+ if (modal.classList.contains('is-screen-1920')) {
111014
+ this.modal.querySelector('.input-device[data-value=""]').classList.add('on');
111015
+ } else if (modal.classList.contains('is-screen-1440')) {
111016
+ this.modal.querySelector('.input-device[data-value=""]').classList.add('on');
111017
+ } else if (modal.classList.contains('is-screen-1024')) {
111018
+ this.modal.querySelector('.input-device[data-value="md"]').classList.add('on');
111019
+ } else if (modal.classList.contains('is-screen-768')) {
111020
+ this.modal.querySelector('.input-device[data-value="sm"]').classList.add('on');
111021
+ } else if (modal.classList.contains('is-screen-375')) {
111022
+ this.modal.querySelector('.input-device[data-value="xs"]').classList.add('on');
111023
+ }
111024
+ }
111025
+ }
111026
+ let divTarget = this.modal.querySelector('.div-target');
111027
+ let divVisibility = this.modal.querySelector('.div-visibility');
111028
+ let target = this.builder.responsive.readTarget(divTarget);
111029
+ let valVisibility = this.builder.responsive.getVisibility(row, target);
111030
+ this.builder.responsive.showVisibility(divVisibility, valVisibility);
111031
+
111032
+ // const divColsPerLine = this.modal.querySelector('.div-colsperline');
111033
+ let btns = this.modal.querySelectorAll('.input-colsperline');
111034
+ btns.forEach(btn => {
111035
+ btn.classList.remove('on');
111036
+ });
111037
+ if (target === 'xs') {
111038
+ if (!initialOpen) this.builder.livePreview.resizePreview(375);
111039
+ } else if (target === 'sm') {
111040
+ if (!initialOpen) this.builder.livePreview.resizePreview(768);
111041
+ } else if (target === 'md') {
111042
+ if (!initialOpen) this.builder.livePreview.resizePreview(1024);
111043
+ } else {
111044
+ if (!initialOpen) this.builder.livePreview.resizePreview(1920);
110367
111045
  }
110368
111046
  }
110369
111047
  openImagePicker(currentUrl, callback, btn) {
@@ -110387,17 +111065,17 @@ class BlockModal {
110387
111065
  }
110388
111066
  updatePageImage(src) {
110389
111067
  this.builder.uo.saveForUndo();
110390
- let page = this.getPage();
110391
- page.style.backgroundImage = 'url(\'' + src + '\')';
111068
+ let pageOverlay = this.pageOverlay();
111069
+ pageOverlay.style.backgroundImage = 'url(\'' + src + '\')';
110392
111070
 
110393
111071
  // Reset position & filter (grayscale)
110394
- page.style.filter = '';
110395
- page.style.backgroundSize = '';
110396
- page.style.backgroundPosition = '50% 60%';
110397
- page.removeAttribute('data-bg-xs');
110398
- page.removeAttribute('data-bg-sm');
110399
- page.removeAttribute('data-bg-md');
110400
- page.removeAttribute('data-bg-lg');
111072
+ pageOverlay.style.filter = '';
111073
+ pageOverlay.style.backgroundSize = '';
111074
+ pageOverlay.style.backgroundPosition = '50% 60%';
111075
+ pageOverlay.removeAttribute('data-bg-xs');
111076
+ pageOverlay.removeAttribute('data-bg-sm');
111077
+ pageOverlay.removeAttribute('data-bg-md');
111078
+ pageOverlay.removeAttribute('data-bg-lg');
110401
111079
  this.updatePanelPageImage(src);
110402
111080
  this.builder.onChange();
110403
111081
  }
@@ -110421,6 +111099,16 @@ class BlockModal {
110421
111099
  }
110422
111100
  const btnPageGradient = modal.querySelector('.btn-page-gradient');
110423
111101
  btnPageGradient.style.backgroundImage = '';
111102
+
111103
+ // Show/hide grayscale
111104
+ const divPageGrayscale = modal.querySelector('.label-page-grayscale');
111105
+ if (src === '') {
111106
+ this.pageImagePreview.style.display = 'none';
111107
+ divPageGrayscale.style.display = 'none';
111108
+ } else {
111109
+ this.pageImagePreview.style.display = '';
111110
+ divPageGrayscale.style.display = '';
111111
+ }
110424
111112
  }
110425
111113
  updateImage(src) {
110426
111114
  this.builder.uo.saveForUndo();
@@ -110436,6 +111124,7 @@ class BlockModal {
110436
111124
  blockOverlay.removeAttribute('data-bg-md');
110437
111125
  blockOverlay.removeAttribute('data-bg-lg');
110438
111126
  this.updatePanelImage(src);
111127
+ this.realtime();
110439
111128
  this.builder.onChange();
110440
111129
  }
110441
111130
  updatePanelImage(src) {
@@ -110458,6 +111147,16 @@ class BlockModal {
110458
111147
  }
110459
111148
  const btnGradient = modal.querySelector('.btn-block-gradient');
110460
111149
  btnGradient.style.backgroundImage = '';
111150
+
111151
+ // Show/hide grayscale
111152
+ const divGrayscale = modal.querySelector('.label-block-grayscale');
111153
+ if (src === '') {
111154
+ this.imagePreview.style.display = 'none';
111155
+ divGrayscale.style.display = 'none';
111156
+ } else {
111157
+ this.imagePreview.style.display = '';
111158
+ divGrayscale.style.display = '';
111159
+ }
110461
111160
  }
110462
111161
  show() {
110463
111162
  const modal = this.modal;
@@ -110488,6 +111187,7 @@ class BlockModal {
110488
111187
  }
110489
111188
  showHideControls() {
110490
111189
  const modal = this.modal;
111190
+ if (!modal.classList.contains('active')) return;
110491
111191
  const content1 = modal.querySelector('.modal-none');
110492
111192
  const content2 = modal.querySelector('.modal-content');
110493
111193
  const content3 = modal.querySelector('.modal-page-content');
@@ -110528,6 +111228,60 @@ class BlockModal {
110528
111228
  this.builder.doc.removeEventListener('click', this.handleBlockClick);
110529
111229
  }
110530
111230
  }
111231
+ position() {
111232
+ const dom = this.dom;
111233
+ let elementTool = this.elementTool;
111234
+ let elementMore = this.elementMore;
111235
+ dom.addClass(elementMore, 'transition1');
111236
+ let elmMore = elementTool.querySelector('.elm-more');
111237
+ const viewportHeight = window.innerHeight;
111238
+
111239
+ /*
111240
+ let top, left;
111241
+ if(!this.builder.iframe) {
111242
+ top = elmMore.getBoundingClientRect().top;
111243
+ left = elmMore.getBoundingClientRect().left;
111244
+ } else {
111245
+ let adjY = this.builder.iframe.getBoundingClientRect().top;
111246
+ let adjX = this.builder.iframe.getBoundingClientRect().left;
111247
+ top = elmMore.getBoundingClientRect().top;
111248
+ left = elmMore.getBoundingClientRect().left;
111249
+ top = top + adjY;
111250
+ left = left + adjX;
111251
+ }
111252
+ */
111253
+ const newPos = this.builder.util.getElementPosition(elmMore);
111254
+ let top = newPos.top;
111255
+ let left = newPos.left;
111256
+
111257
+ // elementMore.style.display = 'flex';
111258
+ const btnMore = elementTool.querySelector('.elm-more');
111259
+ this.util.showPop(elementMore, false, btnMore);
111260
+ const w = elementMore.offsetWidth; //to get value, element must not hidden (display:none). So set display:flex before this.
111261
+ const h = elementMore.offsetHeight;
111262
+ if (viewportHeight - top > h) {
111263
+ elementMore.style.top = top + window.pageYOffset + 27 + 'px';
111264
+ elementMore.style.left = left - w / 2 + 10 + 'px';
111265
+ dom.removeClass(elementMore, 'arrow-bottom');
111266
+ dom.removeClass(elementMore, 'arrow-right');
111267
+ dom.removeClass(elementMore, 'arrow-left');
111268
+ dom.removeClass(elementMore, 'center');
111269
+ dom.addClass(elementMore, 'arrow-top');
111270
+ dom.addClass(elementMore, 'center');
111271
+ } else {
111272
+ elementMore.style.top = top + window.pageYOffset - h - 8 + 'px';
111273
+ elementMore.style.left = left - w / 2 + 10 + 'px';
111274
+ dom.removeClass(elementMore, 'arrow-top');
111275
+ dom.removeClass(elementMore, 'arrow-right');
111276
+ dom.removeClass(elementMore, 'arrow-left');
111277
+ dom.removeClass(elementMore, 'center');
111278
+ dom.addClass(elementMore, 'arrow-bottom');
111279
+ dom.addClass(elementMore, 'center');
111280
+ }
111281
+ setTimeout(() => {
111282
+ dom.removeClass(elementMore, 'transition1');
111283
+ }, 300);
111284
+ }
110531
111285
  }
110532
111286
 
110533
111287
  class PageSize {
@@ -110660,12 +111414,19 @@ class PageSize {
110660
111414
  // let h = arr[1].trim();
110661
111415
  if (arr.length === 3) {
110662
111416
  // web
110663
- const docWidth = docContainer.offsetWidth;
110664
- const viewportWidth = this.builder.win.innerWidth;
110665
- if (docWidth < viewportWidth - 50) {
110666
- // web (container)
110667
- docContainer.classList.remove('page-web');
110668
- docContainer.classList.add('page-web-container');
111417
+ let box = docContainer.querySelector('.is-box');
111418
+ if (box) {
111419
+ const boxWidth = box.offsetWidth;
111420
+ const viewportWidth = this.builder.win.innerWidth;
111421
+ if (boxWidth < viewportWidth - 50) {
111422
+ // web (container)
111423
+ docContainer.classList.remove('page-web');
111424
+ docContainer.classList.add('page-web-container');
111425
+ } else {
111426
+ // web (full)
111427
+ docContainer.classList.remove('page-web-container');
111428
+ docContainer.classList.add('page-web');
111429
+ }
110669
111430
  } else {
110670
111431
  // web (full)
110671
111432
  docContainer.classList.remove('page-web-container');
@@ -110754,18 +111515,53 @@ class PageSize {
110754
111515
  position: relative;
110755
111516
  flex:none;
110756
111517
  background: #fff;
110757
- overflow: hidden;
111518
+ /* overflow: hidden;*/
110758
111519
  box-shadow: none;
110759
111520
  }
110760
111521
  ${css}
110761
111522
  </style>
111523
+
111524
+ ${html.includes('data-module="codeview"') ? `
111525
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism.min.css" rel="stylesheet">
111526
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-coy.min.css" rel="stylesheet">
111527
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/prism.min.js"></script>
111528
+ <style>
111529
+ :not(pre)>code[class*=language-], pre[class*=language-] {
111530
+ background-color: #f4f4f4 !important;
111531
+ padding: 12px 16px !important;
111532
+ }
111533
+ pre[class*=language-]:after, pre[class*=language-]:before {
111534
+ box-shadow: none;
111535
+ }
111536
+ :not(pre)>code[class*=language-], pre[class*=language-] {
111537
+ margin-bottom: 1.2rem;
111538
+ }
111539
+ div[data-html] {
111540
+ min-height: 40px;
111541
+ }
111542
+ code[class*=language-], pre[class*=language-] {
111543
+ text-shadow: none;
111544
+ }
111545
+ </style>
111546
+ ` : ''}
110762
111547
  </head>
110763
111548
  <body class="print">
110764
111549
 
110765
111550
  <div class="is-page">${html}</div>
110766
111551
 
110767
111552
  <script>
110768
- window.print();
111553
+ var docReady = function(fn) {
111554
+ var stateCheck = setInterval(function() {
111555
+ if (document.readyState !== "complete") return;
111556
+ clearInterval(stateCheck);
111557
+ try {
111558
+ fn()
111559
+ } catch (e) {}
111560
+ }, 1);
111561
+ };
111562
+ docReady(function() {
111563
+ window.print();
111564
+ });
110769
111565
  </script>
110770
111566
  </body>
110771
111567
  </html>
@@ -110850,6 +111646,9 @@ class PageSize {
110850
111646
  width: ${docWidth};
110851
111647
  height: ${docHeight};
110852
111648
  }
111649
+ .hide-on-print {
111650
+ display: none !important;
111651
+ }
110853
111652
  }
110854
111653
  @page {
110855
111654
  size:${docWidth} ${docHeight};;
@@ -110870,6 +111669,9 @@ class PageSize {
110870
111669
  width: ${w};
110871
111670
  height: ${h};
110872
111671
  }
111672
+ .hide-on-print {
111673
+ display: none !important;
111674
+ }
110873
111675
  }
110874
111676
  @page {
110875
111677
  size:${w} ${h};
@@ -111139,7 +111941,7 @@ class ContentBuilder {
111139
111941
  style: 'width:180px;height:112.5px'
111140
111942
  }, {
111141
111943
  title: 'Web (container)',
111142
- pagesize: '800px,1000px,web',
111944
+ pagesize: '1000px,1000px,web',
111143
111945
  style: 'width:180px;height:112.5px'
111144
111946
  }, {
111145
111947
  title: '8.27x5.52',
@@ -111980,6 +112782,12 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
111980
112782
  if (window.data_basic) {
111981
112783
  // if snippet file included
111982
112784
  this.opts.snippetJSON = window.data_basic;
112785
+ if (!this.canvas) for (let i = this.opts.snippetJSON.snippets.length - 1; i >= 0; i--) {
112786
+ if (this.opts.snippetJSON.snippets[i].mode === 'canvas') {
112787
+ this.opts.snippetJSON.snippets.splice(i, 1);
112788
+ }
112789
+ }
112790
+
111983
112791
  // if snippetPath is specified (not empty), then use the specified. Otherwise, use the one generated from snippet file (_snippets_path)
111984
112792
  if (this.opts.snippetPath === '') {
111985
112793
  this.opts.snippetPath = window._snippets_path;
@@ -112020,12 +112828,19 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
112020
112828
  this.blockContainer = '.is-box';
112021
112829
  this.imageResizeOnBlock = false;
112022
112830
  this.toolbarDisplay = 'always';
112023
- this.buttons = ['bold', 'italic', 'underline', 'formatting', 'color', 'align', 'textsettings', 'createLink', 'tags', '|', 'undo', 'redo', 'aiassistant', 'snippets', 'zoom', 'pageoptions', 'print', 'html', 'more'];
112024
- this.buttonsMore = ['icon', 'image', '|', 'list', 'font', 'formatPara'];
112025
- this.elementButtons = ['front', 'backward', 'moveup', 'movedown', 'group', 'ungroup', 'duplicate', 'delete', 'left', 'center', 'right', 'full', 'undo', 'redo', 'aiassistant', 'snippets', 'blocksettings', 'zoom', 'pageoptions', 'print', 'html'];
112026
- this.elementButtonsMore = [];
112027
- this.iconButtons = ['icon', 'color', 'textsettings', 'createLink', '|', 'undo', 'redo', 'aiassistant', 'snippets', 'zoom', 'pageoptions', 'print', 'html'];
112028
- this.iconButtonsMore = [];
112831
+ // this.buttons = ['bold', 'italic', 'underline', 'formatting', 'color', 'align', 'textsettings', 'createLink', 'tags', '|', 'undo', 'redo', 'aiassistant', 'snippets','pageoptions', 'print', 'html', 'zoom', 'more'];
112832
+ // this.buttonsMore = ['icon', 'image', '|', 'list', 'font', 'formatPara'];
112833
+ // this.elementButtons = ['front', 'backward', 'moveup', 'movedown', 'group', 'ungroup', 'duplicate', 'delete','left', 'center', 'right', 'full' , 'undo', 'redo', 'aiassistant', 'snippets', 'blocksettings', 'pageoptions', 'print', 'zoom', 'html'];
112834
+ // this.elementButtonsMore = [];
112835
+ // this.iconButtons = ['icon', 'color','textsettings', 'createLink','|', 'undo', 'redo', 'aiassistant', 'snippets', 'pageoptions', 'print', 'zoom', 'html'];
112836
+ // this.iconButtonsMore = [];
112837
+
112838
+ this.buttons = ['bold', 'italic', 'underline', 'formatting', 'color', 'align', 'textsettings', 'createLink', 'tags', '|', 'undo', 'redo', 'zoom', 'pageoptions', 'print', 'html', 'more'];
112839
+ this.buttonsMore = ['icon', 'image', '|', 'list', 'font', 'formatPara', '|', 'aiassistant', 'snippets', 'preferences'];
112840
+ this.elementButtons = ['front', 'backward', 'moveup', 'movedown', 'group', 'ungroup', 'duplicate', 'delete', 'left', 'center', 'right', 'full', 'undo', 'redo', 'blocksettings', 'zoom', 'pageoptions', 'print', 'html', 'more'];
112841
+ this.elementButtonsMore = ['aiassistant', 'snippets', 'preferences'];
112842
+ this.iconButtons = ['icon', 'color', 'textsettings', 'createLink', '|', 'undo', 'redo', 'zoom', 'pageoptions', 'print', 'html', 'more'];
112843
+ this.iconButtonsMore = ['aiassistant', 'snippets', 'preferences'];
112029
112844
  if (!this.docContainer && this.container !== '.is-container') {
112030
112845
  this.docContainer = this.container;
112031
112846
  this.container = '.is-container';
@@ -112537,6 +113352,11 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
112537
113352
  this.rte.hideBlockButtons();
112538
113353
  this.rte.positionToolbar();
112539
113354
  }
113355
+ if (this.blockmodal) {
113356
+ setTimeout(() => {
113357
+ this.blockmodal.showHideControls();
113358
+ }, 30);
113359
+ }
112540
113360
  },
112541
113361
  onSelectBlock: block => {
112542
113362
  if (this.onSelectBlock) this.onSelectBlock(block);
@@ -112692,6 +113512,57 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
112692
113512
  }
112693
113513
  }
112694
113514
  });
113515
+
113516
+ // Copy & Paste Block
113517
+ document.addEventListener('keydown', e => {
113518
+ if ((e.ctrlKey || e.metaKey) && e.which === 67) {
113519
+ //CTRL-C
113520
+ const activeBlock = docContainer.querySelector('.is-block.active'); // always get .cloned
113521
+ if (activeBlock) {
113522
+ this.copyBlock = activeBlock;
113523
+ }
113524
+ }
113525
+ });
113526
+ document.addEventListener('keydown', e => {
113527
+ if ((e.ctrlKey || e.metaKey) && e.which === 86) {
113528
+ //CTRL-V
113529
+
113530
+ const box = docContainer.querySelector('.is-box.box-select'); // always get .cloned
113531
+ let block = this.copyBlock;
113532
+ if (box && block) {
113533
+ if (document.querySelector('.is-modal.active:not(.is-modal-content)')) return;
113534
+ const focusedElement = e.target;
113535
+ const isEditable = focusedElement.tagName === 'INPUT' || focusedElement.tagName === 'TEXTAREA' || focusedElement.hasAttribute('contenteditable');
113536
+ if (isEditable) return;
113537
+ this.uo.saveForUndo();
113538
+ let block = this.copyBlock;
113539
+ const builder = block.querySelector(this.container);
113540
+ let html = '';
113541
+ if (builder) {
113542
+ html = this.readHtml(builder);
113543
+ }
113544
+ let clonedDiv = block.cloneNode(true);
113545
+ clonedDiv.style.top = '20%';
113546
+ clonedDiv.style.left = '20%';
113547
+ if (builder) {
113548
+ const cloneBuilder = clonedDiv.querySelector(this.container);
113549
+ cloneBuilder.innerHTML = '';
113550
+ box.appendChild(clonedDiv);
113551
+ const range = document.createRange();
113552
+ cloneBuilder.appendChild(range.createContextualFragment(html));
113553
+ this.applyBehaviorOn(cloneBuilder);
113554
+ cloneBuilder.click();
113555
+ } else {
113556
+ block.parentNode.appendChild(clonedDiv);
113557
+ }
113558
+ block.classList.remove('active');
113559
+ this.doc.querySelectorAll('.clone').forEach(elm => elm.parentNode.removeChild(elm));
113560
+ this.doc.querySelectorAll('.cloned').forEach(elm => elm.classList.remove('cloned'));
113561
+ this.eb.refresh();
113562
+ this.opts.onChange();
113563
+ }
113564
+ }
113565
+ });
112695
113566
  }
112696
113567
  let previousWidth = this.win.innerWidth;
112697
113568
  let timer;
@@ -113030,6 +113901,15 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
113030
113901
  }
113031
113902
  }
113032
113903
  }, 300);
113904
+
113905
+ // info
113906
+ let largeScreenBreakpoint = 1280; //1920
113907
+ largeScreenBreakpoint = window.innerWidth - 360; //351
113908
+ if (largeScreenBreakpoint < 1280) largeScreenBreakpoint = 1280;
113909
+ if (this.consoleLog) {
113910
+ console.log('vw: ' + window.innerWidth);
113911
+ console.log('lg: ' + largeScreenBreakpoint);
113912
+ }
113033
113913
  } // constructor
113034
113914
 
113035
113915
  // Convenience constructor, so that the plugin can be called directly using: ContentBuilder.run({ ... });
@@ -113112,6 +113992,22 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
113112
113992
  top: 0;
113113
113993
  left: -1000px;
113114
113994
  }
113995
+ .h-ruler {
113996
+ top:0;
113997
+ left:-100vw;
113998
+ width: 300vw;
113999
+ height:2px;
114000
+ display:none;
114001
+ }
114002
+ .h-ruler.active { display: block }
114003
+ .v-ruler {
114004
+ top:0;
114005
+ left:0;
114006
+ width:2px;
114007
+ height: 100%;
114008
+ display:none;
114009
+ }
114010
+ .v-ruler.active { display: block }
113115
114011
 
113116
114012
  /* Resize Handles */
113117
114013
  .handle {
@@ -113286,16 +114182,19 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
113286
114182
  @media (max-width: 760px) {
113287
114183
  .is-box.autolayout .is-block > .rotate-handle,
113288
114184
  .is-box.autolayout .is-block > .handle {
113289
- display: none;
114185
+ display: none;
113290
114186
  }
113291
114187
 
113292
114188
  /* NEW */
113293
- .is-block.clone {
114189
+ .is-box.autolayout .is-block.clone {
113294
114190
  display:none;
113295
114191
  }
113296
- .is-block.cloned {
114192
+ .is-box.autolayout .is-block.cloned {
113297
114193
  outline: var(--is-outline);
113298
114194
  }
114195
+ .is-box.box-select {
114196
+ outline: none !important;
114197
+ }
113299
114198
  }
113300
114199
 
113301
114200
  .is-block.locked .handle,
@@ -113962,7 +114861,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
113962
114861
  this.setZoomOnControl(builder);
113963
114862
  }
113964
114863
  html(area) {
113965
- if (this.docContainer) {
114864
+ if (this.docContainer && !area) {
113966
114865
  // freeform
113967
114866
 
113968
114867
  const docContainer = this.doc.querySelector(this.docContainer);
@@ -114070,7 +114969,33 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
114070
114969
  }
114071
114970
  refresh() {
114072
114971
  if (this.eb) this.eb.refresh();
114972
+
114973
+ /*
114974
+ // Add block tool
114975
+ let html = `
114976
+ <div class="is-tool is-block-tool">
114977
+ <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>
114978
+ </div>
114979
+ `;
114980
+ let blocks = this.doc.querySelectorAll('.is-block');
114981
+ blocks.forEach(block => {
114982
+ let tool = block.querySelector('.is-block-tool');
114983
+ if(tool) tool.remove();
114984
+ block.insertAdjacentHTML('beforeend', html);
114985
+ tool = block.querySelector('.is-block-tool');
114986
+ tool.addEventListener('click',(e)=>{
114987
+ if(document.querySelector('.is-modal.editblock.active')) {
114988
+ this.blockmodal.hide();
114989
+ } else {
114990
+ this.blockmodal.show();
114991
+ }
114992
+ e.preventDefault();
114993
+ e.stopImmediatePropagation();
114994
+ });
114995
+ });
114996
+ */
114073
114997
  }
114998
+
114074
114999
  group() {
114075
115000
  if (!this.eb) return;
114076
115001
  this.uo.saveForUndo();
@@ -114225,6 +115150,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
114225
115150
  <!--
114226
115151
  <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>
114227
115152
  -->
115153
+ <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>
114228
115154
  <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>
114229
115155
  </div>
114230
115156
  <div class="is-tool is-canvasadd-tool" style="transform: scale(1); transform-origin: center top;">
@@ -114275,6 +115201,57 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
114275
115201
  });
114276
115202
  this.opts.onChange();
114277
115203
  });
115204
+ const btnDuplicate = box.querySelector('.is-canvas-tool .box-duplicate');
115205
+ btnDuplicate.addEventListener('click', e => {
115206
+ this.eb.selectClear(); // clear clone
115207
+
115208
+ // clear active
115209
+ const box = e.target.closest('.is-box');
115210
+ const block = box.querySelector('.is-block.active');
115211
+ if (block) block.classList.remove('active');
115212
+ this.uo.saveForUndo();
115213
+ let copiedBox = box.cloneNode(true);
115214
+ copiedBox.setAttribute('data-box-copied', '1');
115215
+ let parent = box.parentNode;
115216
+ parent.insertBefore(copiedBox, box.nextElementSibling);
115217
+ let newBox = docContainer.querySelector('[data-box-copied]');
115218
+ newBox.removeAttribute('data-box-copied');
115219
+
115220
+ // Code Blocks Handling
115221
+ let codeBlocks = newBox.querySelectorAll('[data-module]');
115222
+ codeBlocks.forEach(element => {
115223
+ let html = decodeURIComponent(element.getAttribute('data-html')); // Original code is stored in data-html attribute
115224
+ html = html.replace(/{id}/g, this.util.makeId());
115225
+ //Fill the block with original code
115226
+ this.html(element, html);
115227
+ });
115228
+ newBox.scrollIntoView({
115229
+ behavior: 'smooth',
115230
+ block: 'center'
115231
+ });
115232
+ this.applyBehaviorCanvas();
115233
+
115234
+ // ContentBuilder Handling
115235
+ let containers = newBox.querySelectorAll('.is-builder');
115236
+ containers.forEach(container => {
115237
+ let containerHtml = this.html(container);
115238
+ let range = document.createRange();
115239
+ container.innerHTML = '';
115240
+ container.appendChild(range.createContextualFragment(containerHtml));
115241
+ container.removeAttribute('data-sort'); //important (ContentBuilder cleanup for the container)
115242
+ this.applyBehaviorOn(container);
115243
+ });
115244
+ this.eb.refresh();
115245
+ this.opts.onChange();
115246
+
115247
+ // Change selection
115248
+ setTimeout(() => {
115249
+ box.classList.remove('box-select');
115250
+ const prevBox = docContainer.querySelector('.box-select');
115251
+ if (prevBox) prevBox.classList.remove('box-select');
115252
+ newBox.classList.add('box-select');
115253
+ }, 30);
115254
+ });
114278
115255
  const btnRemove = box.querySelector('.is-canvas-tool .box-remove');
114279
115256
  btnRemove.addEventListener('click', e => {
114280
115257
  const box = e.target.closest('.is-box');
@@ -115341,6 +116318,12 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
115341
116318
  script.async = true;
115342
116319
  script.onload = () => {
115343
116320
  this.opts.snippetJSON = window.data_basic;
116321
+ if (!this.canvas) for (let i = this.opts.snippetJSON.snippets.length - 1; i >= 0; i--) {
116322
+ if (this.opts.snippetJSON.snippets[i].mode === 'canvas') {
116323
+ this.opts.snippetJSON.snippets.splice(i, 1);
116324
+ }
116325
+ }
116326
+
115344
116327
  // if snippetPath is specified (not empty), then use the specified. Otherwise, use the one generated from snippet file (_snippets_path)
115345
116328
  if (this.opts.snippetPath === '') {
115346
116329
  this.opts.snippetPath = window._snippets_path;
@@ -115367,7 +116350,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
115367
116350
  html = `
115368
116351
  <div class="is-box box-canvas autolayout">
115369
116352
  <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="">
115370
- <div class="is-container leading-12 size-17">
116353
+ <div class="is-container">
115371
116354
  ${html}
115372
116355
  </div>
115373
116356
  <div class="is-block-overlay"></div>
@@ -116939,6 +117922,13 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
116939
117922
 
116940
117923
  if (this.opts.emailMode) bSnippet = false;
116941
117924
 
117925
+ // check if is block
117926
+ let isBlock = false;
117927
+ if (html.includes('"is-block')) {
117928
+ isBlock = true;
117929
+ bSnippet = false;
117930
+ }
117931
+
116942
117932
  // Convert snippet into your defined 12 columns grid
116943
117933
  var rowClass = this.opts.row; //row
116944
117934
  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']
@@ -116985,24 +117975,26 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
116985
117975
  this.dom.removeClass(itemEl, 'snippet-item');
116986
117976
  let bw = '';
116987
117977
  if (this.page && this.page === '.is-wrapper') {
116988
- bw = '800px';
117978
+ bw = '760px';
116989
117979
  } else {
116990
117980
  if (occurrences === 2) {
116991
- bw = '800px';
117981
+ bw = '760px';
116992
117982
  } else if (occurrences >= 3) {
116993
- bw = '800px';
117983
+ bw = '760px';
116994
117984
  } else {
116995
117985
  bw = '540px';
116996
117986
  }
116997
117987
  }
116998
117988
  const blockTemplate = `
116999
117989
  <div class="is-block block-steady height-auto" data-new-dummy="1" style="top: 20%; left: 20%; width: ${bw};">
117000
- <div class="is-container container-new leading-12 size-17">
117990
+ <div class="is-container container-new">
117001
117991
  [%CONTENT%]
117002
117992
  </div>
117003
117993
  </div>
117004
117994
  `; // data-new-dummy will be used by onSort to apply top/left position (snippetpanel.js)
117005
117995
  itemEl.outerHTML = blockTemplate.replace('[%CONTENT%]', html);
117996
+ } else if (isBlock) {
117997
+ itemEl.outerHTML = html;
117006
117998
  } else {
117007
117999
  // Snippet is wrapped in row/colum (may contain custom code or has [data-html] attribute)
117008
118000
  // Can only be inserted after current row or last row (not on column or element).
@@ -117035,19 +118027,19 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
117035
118027
  itemEl.appendChild(range.createContextualFragment(html));
117036
118028
  let bw = '';
117037
118029
  if (this.page && this.page === '.is-wrapper') {
117038
- bw = '800px';
118030
+ bw = '760px';
117039
118031
  } else {
117040
118032
  if (occurrences === 2) {
117041
- bw = '800px';
118033
+ bw = '760px';
117042
118034
  } else if (occurrences >= 3) {
117043
- bw = '800px';
118035
+ bw = '760px';
117044
118036
  } else {
117045
118037
  bw = '540px';
117046
118038
  }
117047
118039
  }
117048
118040
  const blockTemplate = `
117049
118041
  <div class="is-block block-steady height-auto" data-new-dummy="1" style="top: 20%; left: 20%; width: ${bw};">
117050
- <div class="is-container container-new leading-12 size-17">
118042
+ <div class="is-container container-new">
117051
118043
  [%CONTENT%]
117052
118044
  </div>
117053
118045
  </div>
@@ -147823,6 +148815,7 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
147823
148815
  this.editor = new ContentBuilder({
147824
148816
  controlPanel: this.settings.controlPanel,
147825
148817
  canvas: this.settings.canvas,
148818
+ consoleLog: this.settings.consoleLog,
147826
148819
  isContentBox: true,
147827
148820
  speechTranscribeUrl: this.settings.speechTranscribeUrl,
147828
148821
  autoSendDelay: this.settings.autoSendDelay,
@@ -148803,14 +149796,19 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
148803
149796
  .is-box.autolayout .is-block > .handle {
148804
149797
  display: none;
148805
149798
  }
148806
-
149799
+
148807
149800
  /* NEW */
148808
- .is-block.clone {
149801
+ .is-box.autolayout .is-block.clone {
148809
149802
  display:none;
148810
149803
  }
148811
- .is-block.cloned {
149804
+ .is-box.autolayout .is-block.cloned {
148812
149805
  outline: var(--is-outline);
148813
149806
  }
149807
+ /*
149808
+ .is-box.box-select {
149809
+ outline: none !important;
149810
+ }
149811
+ */
148814
149812
  }
148815
149813
 
148816
149814
  .is-block.locked .handle,