@innovastudio/contentbuilder 1.5.15 → 1.5.17

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