@innovastudio/contentbuilder 1.5.60 → 1.5.62

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.
Files changed (61) hide show
  1. package/package.json +1 -1
  2. package/public/contentbuilder/contentbuilder.css +241 -79
  3. package/public/contentbuilder/contentbuilder.esm.js +592 -767
  4. package/public/contentbuilder/contentbuilder.min.js +3 -3
  5. package/public/contentbuilder/lang/en.js +2 -2
  6. package/public/contentbuilder/lang/fr.js +2 -2
  7. package/public/contentbuilder/themes/colored-blue.css +31 -16
  8. package/public/contentbuilder/themes/colored-blue2.css +31 -16
  9. package/public/contentbuilder/themes/colored-blue3.css +31 -16
  10. package/public/contentbuilder/themes/colored-blue4.css +31 -16
  11. package/public/contentbuilder/themes/colored-blue5.css +31 -16
  12. package/public/contentbuilder/themes/colored-blue6.css +31 -16
  13. package/public/contentbuilder/themes/colored-blue7.css +31 -16
  14. package/public/contentbuilder/themes/colored-blue8.css +31 -16
  15. package/public/contentbuilder/themes/colored-darkblue.css +31 -16
  16. package/public/contentbuilder/themes/colored-gray.css +31 -16
  17. package/public/contentbuilder/themes/colored-green.css +31 -16
  18. package/public/contentbuilder/themes/colored-green2.css +31 -16
  19. package/public/contentbuilder/themes/colored-green3.css +31 -16
  20. package/public/contentbuilder/themes/colored-green4.css +31 -16
  21. package/public/contentbuilder/themes/colored-green5.css +31 -16
  22. package/public/contentbuilder/themes/colored-magenta.css +31 -16
  23. package/public/contentbuilder/themes/colored-orange.css +31 -16
  24. package/public/contentbuilder/themes/colored-orange2.css +31 -16
  25. package/public/contentbuilder/themes/colored-orange3.css +31 -16
  26. package/public/contentbuilder/themes/colored-pink.css +31 -16
  27. package/public/contentbuilder/themes/colored-pink2.css +31 -16
  28. package/public/contentbuilder/themes/colored-pink3.css +31 -16
  29. package/public/contentbuilder/themes/colored-pink4.css +31 -16
  30. package/public/contentbuilder/themes/colored-purple.css +31 -16
  31. package/public/contentbuilder/themes/colored-purple2.css +31 -16
  32. package/public/contentbuilder/themes/colored-red.css +31 -16
  33. package/public/contentbuilder/themes/colored-red2.css +31 -16
  34. package/public/contentbuilder/themes/colored-red3.css +31 -16
  35. package/public/contentbuilder/themes/colored-red4.css +31 -16
  36. package/public/contentbuilder/themes/colored-red5.css +31 -16
  37. package/public/contentbuilder/themes/colored-yellow.css +31 -16
  38. package/public/contentbuilder/themes/colored-yellow2.css +31 -16
  39. package/public/contentbuilder/themes/dark-blue.css +19 -15
  40. package/public/contentbuilder/themes/dark-blue2.css +19 -15
  41. package/public/contentbuilder/themes/dark-blue3.css +19 -15
  42. package/public/contentbuilder/themes/dark-gray.css +19 -15
  43. package/public/contentbuilder/themes/dark-pink.css +19 -15
  44. package/public/contentbuilder/themes/dark-purple.css +19 -15
  45. package/public/contentbuilder/themes/dark-red.css +19 -15
  46. package/public/contentbuilder/themes/dark.css +19 -15
  47. package/public/contentbuilder/themes/light-blue.css +30 -15
  48. package/public/contentbuilder/themes/light-blue2.css +30 -15
  49. package/public/contentbuilder/themes/light-blue3.css +30 -15
  50. package/public/contentbuilder/themes/light-cyan.css +30 -15
  51. package/public/contentbuilder/themes/light-gray.css +30 -15
  52. package/public/contentbuilder/themes/light-gray2.css +30 -15
  53. package/public/contentbuilder/themes/light-gray3.css +30 -15
  54. package/public/contentbuilder/themes/light-green.css +30 -15
  55. package/public/contentbuilder/themes/light-pink.css +30 -15
  56. package/public/contentbuilder/themes/light-pink2.css +30 -15
  57. package/public/contentbuilder/themes/light-purple.css +30 -15
  58. package/public/contentbuilder/themes/light-purple2.css +30 -15
  59. package/public/contentbuilder/themes/light-red.css +30 -15
  60. package/public/contentbuilder/themes/light-yellow.css +30 -15
  61. package/public/contentbuilder/themes/light-yellow2.css +30 -15
@@ -4599,27 +4599,7 @@ class Util {
4599
4599
  pop.classList.add('pop4');
4600
4600
  overlay.classList.add('pop4');
4601
4601
  }
4602
- const handlePopKeyDown = e => {
4603
- if (e.keyCode === 27) {
4604
- // escape key
4605
- overlay.remove();
4606
- pop.style.display = '';
4607
- pop.classList.remove('active');
4608
- pop.setAttribute('aria-hidden', true);
4609
- overlay.classList.remove('pop1');
4610
- overlay.classList.remove('pop2');
4611
- overlay.classList.remove('pop3');
4612
- overlay.classList.remove('pop4');
4613
- pop.classList.remove('pop1');
4614
- pop.classList.remove('pop2');
4615
- pop.classList.remove('pop3');
4616
- pop.classList.remove('pop4');
4617
- pop.removeEventListener('keydown', handlePopKeyDown);
4618
- if (cancelCallback) cancelCallback();
4619
- if (btn) btn.focus();
4620
- }
4621
- };
4622
- overlay.addEventListener('click', e => {
4602
+ const close = () => {
4623
4603
  overlay.remove();
4624
4604
  pop.style.display = '';
4625
4605
  pop.classList.remove('active');
@@ -4635,6 +4615,17 @@ class Util {
4635
4615
  pop.removeEventListener('keydown', handlePopKeyDown);
4636
4616
  if (cancelCallback) cancelCallback();
4637
4617
  if (btn) btn.focus();
4618
+ };
4619
+ this.hidePopOverlay = close; // so that the close() can be called programmatically (used by gradientpicker.js 411)
4620
+
4621
+ const handlePopKeyDown = e => {
4622
+ if (e.keyCode === 27) {
4623
+ // escape key
4624
+ close();
4625
+ }
4626
+ };
4627
+ overlay.addEventListener('click', e => {
4628
+ close();
4638
4629
  e.preventDefault();
4639
4630
  e.stopImmediatePropagation();
4640
4631
  });
@@ -15799,6 +15790,11 @@ const prepareSvgIcons = builder => {
15799
15790
  <path d="M12 5l0 14"></path>
15800
15791
  <path d="M5 12l14 0"></path>
15801
15792
  </symbol>
15793
+
15794
+ <symbol id="icon-minus" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
15795
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
15796
+ <path d="M5 12l14 0"></path>
15797
+ </symbol>
15802
15798
  </svg>`;
15803
15799
  builder.dom.appendHtml(builder.builderStuff, html);
15804
15800
  };
@@ -51828,11 +51824,16 @@ class RowTool {
51828
51824
  <a title="${util.out('More')}" id="tabRowMore" href="#" data-content="divRowMore">${util.out('More')}</a>
51829
51825
  </div>
51830
51826
  <div id="divRowGeneral" class="is-tab-content active" data-group="rowsettings" style="display:flex" tabindex="-1">
51831
-
51832
- <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
51833
- <div style="display:flex;">
51834
- <button title="${util.out('Background Color')}" class="input-row-bgcolor is-btn-color" style="margin-right:15px"></button>
51835
- <button title="${util.out('Gradient')}" class="input-row-gradient classic" data-value="+"> ${util.out('Gradient')} </button>
51827
+
51828
+ <div style="display:flex;gap:40px">
51829
+ <div>
51830
+ <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
51831
+ <button title="${util.out('Background Color')}" class="input-row-bgcolor is-btn-color" style="margin-right:15px"></button>
51832
+ </div>
51833
+ <div>
51834
+ <div style="padding-bottom: 3px;">${util.out('Gradient')}:</div>
51835
+ <button title="${util.out('Gradient')}" class="input-row-gradient is-btn-color"></button>
51836
+ </div>
51836
51837
  </div>
51837
51838
 
51838
51839
  <div style="padding-top:20px;padding-bottom: 3px;">${util.out('Background Image')}:</div>
@@ -52079,11 +52080,6 @@ class RowTool {
52079
52080
  });
52080
52081
 
52081
52082
  // Background gradient
52082
- // const gradientPicker = new GradientPicker({
52083
- // colors: this.builder.colors,
52084
- // gradientcolors: this.builder.opts.gradientcolors,
52085
- // lang: this.builder.opts.lang
52086
- // }, this.builder);
52087
52083
  const gradientPicker = this.builder.gradientpicker();
52088
52084
  let btnRowGradient = rowSettings.querySelector('.input-row-gradient');
52089
52085
  btnRowGradient.addEventListener('click', () => {
@@ -52479,6 +52475,16 @@ class RowTool {
52479
52475
  } else {
52480
52476
  div.innerHTML = '';
52481
52477
  }
52478
+
52479
+ // Gradient
52480
+ let btnGradient = this.rowSettings.querySelector('.input-row-gradient');
52481
+ btnGradient.style.backgroundImage = '';
52482
+ if (row.style.backgroundImage) {
52483
+ if (row.style.backgroundImage.includes('linear')) {
52484
+ let cssGradient = row.style.backgroundImage;
52485
+ btnGradient.style.backgroundImage = cssGradient;
52486
+ }
52487
+ }
52482
52488
  const chkRowGrayscale = this.rowSettings.querySelector('.chk-row-grayscale');
52483
52489
  chkRowGrayscale.checked = false;
52484
52490
  if (row.style.filter) {
@@ -52637,7 +52643,6 @@ class RowAddTool {
52637
52643
  }
52638
52644
  }
52639
52645
 
52640
- // import GradientPicker from './gradientpicker.js';
52641
52646
  class ColumnTool {
52642
52647
  constructor(builder) {
52643
52648
  this.builder = builder;
@@ -53411,10 +53416,15 @@ class ColumnTool {
53411
53416
  </div>
53412
53417
  <div id="divCellGeneral" class="is-tab-content active" data-group="cellsettings" style="display:flex" tabindex="-1">
53413
53418
 
53414
- <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
53415
- <div style="display:flex;">
53416
- <button title="${util.out('Background Color')}" class="input-cell-bgcolor is-btn-color" style="margin-right:15px"></button>
53417
- <button title="${util.out('Gradient')}" class="input-cell-gradient classic" data-value="+"> ${util.out('Gradient')} </button>
53419
+ <div style="display:flex;gap:40px">
53420
+ <div>
53421
+ <div style="padding-bottom: 3px;">${util.out('Background Color')}:</div>
53422
+ <button title="${util.out('Background Color')}" class="input-cell-bgcolor is-btn-color" style="margin-right:15px"></button>
53423
+ </div>
53424
+ <div>
53425
+ <div style="padding-bottom: 3px;">${util.out('Gradient')}:</div>
53426
+ <button title="${util.out('Gradient')}" class="input-cell-gradient is-btn-color"></button>
53427
+ </div>
53418
53428
  </div>
53419
53429
 
53420
53430
  <div style="padding-top:20px;padding-bottom: 3px;">${util.out('Background Image')}:</div>
@@ -53806,12 +53816,6 @@ class ColumnTool {
53806
53816
  });
53807
53817
 
53808
53818
  // Background gradient
53809
- // const gradientPicker = new GradientPicker({
53810
- // colors: this.builder.colors,
53811
- // gradientcolors: this.builder.opts.gradientcolors,
53812
- // lang: this.builder.opts.lang
53813
- // }, this.builder);
53814
-
53815
53819
  const gradientPicker = this.builder.gradientpicker();
53816
53820
  let btnCellGradient = cellSettings.querySelector('.input-cell-gradient');
53817
53821
  btnCellGradient.addEventListener('click', () => {
@@ -54583,6 +54587,16 @@ class ColumnTool {
54583
54587
  } else {
54584
54588
  div.innerHTML = '';
54585
54589
  }
54590
+
54591
+ // Gradient
54592
+ let btnGradient = this.cellSettings.querySelector('.input-cell-gradient');
54593
+ btnGradient.style.backgroundImage = '';
54594
+ if (cell.style.backgroundImage) {
54595
+ if (cell.style.backgroundImage.includes('linear')) {
54596
+ let cssGradient = cell.style.backgroundImage;
54597
+ btnGradient.style.backgroundImage = cssGradient;
54598
+ }
54599
+ }
54586
54600
  const inpClickSrc = this.cellSettings.querySelector('.input-src');
54587
54601
  inpClickSrc.value = '';
54588
54602
  let clickUrl = cell.getAttribute('data-modal-url');
@@ -55419,11 +55433,14 @@ class ElementGeneralStyles {
55419
55433
  let panelStuff = builderStuff.querySelector('#divElementGeneral');
55420
55434
  this.panelStuff = panelStuff;
55421
55435
  const html = `
55422
- <div class="is-settings" style="width: 100%">
55423
- <div class="is-label" style="margin:0 0 3px">${util.out('Background Color')}:</div>
55424
- <div>
55436
+ <div class="is-settings" style="width: 100%;display:flex;gap:40px">
55437
+ <div style="display:flex;flex-direction:column;align-items:flex-start;">
55438
+ <div style="padding-bottom: 7px;">${util.out('Background Color')}:</div>
55425
55439
  <button title="${util.out('Background Color')}" class="input-elm-bgcolor is-btn-color" style="margin-right:15px"></button>
55426
- <button title="${util.out('Gradient')}" class="input-elm-gradient classic" data-value="+"> ${util.out('Gradient')} </button>
55440
+ </div>
55441
+ <div style="display:flex;flex-direction:column;align-items:flex-start;">
55442
+ <div style="padding-bottom: 7px;">${util.out('Gradient')}:</div>
55443
+ <button title="${util.out('Gradient')}" class="input-elm-gradient is-btn-color"></button>
55427
55444
  </div>
55428
55445
  </div>
55429
55446
 
@@ -55508,12 +55525,6 @@ class ElementGeneralStyles {
55508
55525
  });
55509
55526
 
55510
55527
  // Background gradient
55511
- // const gradientPicker = new GradientPicker({
55512
- // colors: this.builder.colors,
55513
- // gradientcolors: this.builder.opts.gradientcolors,
55514
- // lang: this.builder.opts.lang
55515
- // }, this.builder);
55516
-
55517
55528
  const gradientPicker = this.builder.gradientpicker();
55518
55529
  let btnElmGradient = panelStuff.querySelector('.input-elm-gradient');
55519
55530
  btnElmGradient.addEventListener('click', () => {
@@ -55712,6 +55723,16 @@ class ElementGeneralStyles {
55712
55723
  let btn = panelStuff.querySelector('.input-elm-bgcolor');
55713
55724
  if (s) btn.style.backgroundColor = s;else btn.style.backgroundColor = 'transparent';
55714
55725
 
55726
+ // Gradient
55727
+ let btnGradient = panelStuff.querySelector('.input-elm-gradient');
55728
+ btnGradient.style.backgroundImage = '';
55729
+ if (elm.style.backgroundImage) {
55730
+ if (elm.style.backgroundImage.includes('linear')) {
55731
+ let cssGradient = elm.style.backgroundImage;
55732
+ btnGradient.style.backgroundImage = cssGradient;
55733
+ }
55734
+ }
55735
+
55715
55736
  // Background image
55716
55737
  let imgUrl = '';
55717
55738
  const div = panelStuff.querySelector('.elm-bgimage-preview');
@@ -63443,7 +63464,8 @@ class ColorPicker {
63443
63464
  pickr.on('change', color => {
63444
63465
  if (poppicker.style.display !== 'flex') return;
63445
63466
  let s = color.toRGBA().toString(0);
63446
- this.opts.onPick(s);
63467
+ if (!this.noCallback) this.opts.onPick(s);
63468
+ this.noCallback = false; //just in case
63447
63469
  }).on('clear', () => {
63448
63470
  this.opts.onPick('');
63449
63471
  poppicker.querySelector('.pcr-result').value = ''; //clear
@@ -63602,6 +63624,7 @@ class ColorPicker {
63602
63624
  this.opts.color = color;
63603
63625
  this.setColor(color, true);
63604
63626
  }
63627
+ this.noCallback = false;
63605
63628
  }
63606
63629
  openByTab(color) {
63607
63630
  // Rte
@@ -63617,9 +63640,10 @@ class ColorPicker {
63617
63640
  setColorRte(color) {
63618
63641
  this.pickrRte.setColor(color);
63619
63642
  }
63620
- setColor(color) {
63643
+ setColor(color, noCallback) {
63621
63644
  //, noCallback
63622
63645
 
63646
+ if (noCallback) this.noCallback = true; // will be passed to onChange, since the onChanhe calls onPick(color)
63623
63647
  this.pickr.setColor(color);
63624
63648
 
63625
63649
  // if(!noCallback) this.opts.onPick(color);
@@ -63649,587 +63673,539 @@ class ColorPicker {
63649
63673
  }
63650
63674
  }
63651
63675
 
63652
- class Modal {
63653
- constructor(opts = {}) {
63654
- let defaults = {
63655
- animateModal: false,
63656
- elementToAnimate: '',
63657
- stuffPlacement: '#_cbhtml'
63676
+ class RoundedSlider {
63677
+ constructor(element, settings = {}) {
63678
+ const defaults = {
63679
+ selector: '.myslider',
63680
+ onStart: () => {}
63658
63681
  };
63659
- this.opts = Object.assign(this, defaults, opts);
63660
- this.id = this.makeId();
63661
- let builderStuff = document.querySelector(this.opts.stuffPlacement);
63662
- if (!builderStuff) {
63663
- builderStuff = document.createElement('div');
63664
- builderStuff.id = '_cbhtml';
63665
- document.body.appendChild(builderStuff);
63666
- }
63667
- this.builderStuff = builderStuff;
63682
+ this.opts = Object.assign(this, defaults, settings);
63683
+ this.startDrag = this.startDrag.bind(this);
63684
+ this.onDrag = this.onDrag.bind(this);
63685
+ this.endDrag = this.endDrag.bind(this);
63686
+ this.handleTouchMove = this.handleTouchMove.bind(this);
63687
+ this.element = element; //document.querySelector(this.opts.selector);
63668
63688
 
63669
- // Stuff placement for this (single) instance
63670
- const objStuff = document.createElement('div');
63671
- objStuff.id = this.id;
63672
- builderStuff.appendChild(objStuff);
63673
- this.objStuff = objStuff;
63689
+ this.created = false;
63674
63690
  }
63675
- confirm(message, callback, animated) {
63676
- let html = `<div class="is-modal is-confirm" tabindex="-1" role="dialog" aria-modal="true" aria-hidden="true">
63677
- <div class="is-modal-content" style="padding-bottom:20px;">
63678
- <div style="margin: 20px 0 30px;font-size: 14px;">${message}</div>
63679
- <button title="${this.out('Delete')}" class="input-ok classic">${this.out('Delete')}</button>
63680
- </div>
63681
- </div>`;
63682
- let confirmModal = this.objStuff.querySelector('.is-confirm');
63683
- if (!confirmModal) {
63684
- this.objStuff.insertAdjacentHTML('beforeend', html);
63685
- confirmModal = this.builderStuff.querySelector('.is-confirm');
63686
- }
63687
- this.show(confirmModal, false, () => {
63688
- //this function runs when overlay is clicked. Remove modal.
63689
- confirmModal.parentNode.removeChild(confirmModal);
63690
-
63691
- //do task
63692
- callback(false);
63693
- }, animated);
63694
- let buttonok = confirmModal.querySelector('.is-confirm .input-ok');
63695
- this.addEventListener(buttonok, 'click', () => {
63696
- this.hide(confirmModal);
63697
- confirmModal.parentNode.removeChild(confirmModal); //remove modal
63698
-
63699
- //do task
63700
- callback(true);
63691
+ create() {
63692
+ if (this.created === true) return; // so that it is saved to call multiple times
63693
+ this.created = true;
63694
+ const element = this.element;
63695
+ const container = document.createElement('div');
63696
+ container.classList.add('roundslider-container');
63697
+ container.innerHTML = `
63698
+ <div class="roundslider">
63699
+ <div class="knob"></div>
63700
+ </div>
63701
+ `;
63702
+ element.insertAdjacentElement('afterend', container);
63703
+ this.container = container;
63704
+ const knob = container.querySelector('.knob');
63705
+ const roundslider = container.querySelector('.roundslider');
63706
+ const angleValue = element;
63707
+ this.knob = knob;
63708
+ this.roundslider = roundslider;
63709
+ this.angleValue = angleValue;
63710
+ this.isDragging = false;
63711
+ this.angleOffset = 0;
63712
+ knob.addEventListener('mousedown', this.startDrag);
63713
+ document.addEventListener('mousemove', this.onDrag);
63714
+ document.addEventListener('mouseup', this.endDrag);
63715
+ knob.addEventListener('touchstart', this.startDrag, {
63716
+ passive: false
63701
63717
  });
63718
+ // document.addEventListener('touchmove', e => this.onDrag(e.touches[0]));
63719
+ document.addEventListener('touchmove', this.handleTouchMove);
63720
+ document.addEventListener('touchend', this.endDrag);
63721
+ this.setKnobPosition(angleValue.value, true); // no trigger for initial create
63722
+
63723
+ element.style.display = 'none';
63724
+ }
63725
+ setValue(val, noTrigger = false) {
63726
+ // true = no trigger only for setting angle position (gradientpicker.js 500)
63727
+ this.setKnobPosition(val, noTrigger);
63702
63728
  }
63703
- show(modal, overlayStay, cancelCallback, animated) {
63704
- this.addClass(modal, 'active');
63729
+ setKnobPosition(angle, noTrigger = false) {
63730
+ const knob = this.knob;
63731
+ const roundslider = this.roundslider;
63732
+ const angleValue = this.angleValue;
63733
+ const degToRad = deg => deg * Math.PI / 180;
63734
+ const radius = roundslider.offsetWidth / 2;
63735
+ const x = radius + radius * Math.cos(degToRad(angle - 90));
63736
+ const y = radius + radius * Math.sin(degToRad(angle - 90));
63737
+ knob.style.left = `${x - knob.offsetWidth / 2}px`;
63738
+ knob.style.top = `${y - knob.offsetHeight / 2}px`;
63739
+ angle = angle % 360;
63705
63740
 
63706
- // animated param (if set) will overide global setting
63707
- let animate = false;
63708
- if (!(typeof animated === 'undefined' || animated === null)) {
63709
- // animated param is set
63710
- animate = animated;
63711
- } else {
63712
- // if animated param is not set
63713
- animate = this.opts.animateModal; // use global setting
63714
- }
63741
+ // angleValue.value = `${Math.round(angle)}°`;
63742
+ angleValue.value = `${Math.round(angle)}`;
63743
+ knob.dataset.angle = angle.toString(); // Update the internal state with the new angle
63715
63744
 
63716
- if (animate) {
63717
- const buildercontainers = document.querySelectorAll(this.opts.elementToAnimate);
63718
- Array.prototype.forEach.call(buildercontainers, buildercontainer => {
63719
- // buildercontainer.style.transform = 'scale(0.98)';
63720
- // buildercontainer.style.WebkitTransform= 'scale(0.98)';
63721
- // buildercontainer.style.MozTransform= 'scale(0.98)';
63722
- buildercontainer.style.transform = `scale(${this.builder.opts.zoom - 0.02})`;
63723
- buildercontainer.style.WebkitTransform = `scale(${this.builder.opts.zoom - 0.02})`;
63724
- buildercontainer.style.MozTransform = `scale(${this.builder.opts.zoom - 0.02})`;
63725
- buildercontainer.setAttribute('scaled-down', '1');
63745
+ if (!noTrigger) {
63746
+ const event = new Event('input', {
63747
+ bubbles: true
63726
63748
  });
63727
- }
63728
- if (!modal.querySelector('.is-modal-overlay')) {
63729
- let html;
63730
- if (overlayStay) {
63731
- html = '<div class="is-modal-overlay overlay-stay"></div>';
63732
- } else {
63733
- html = '<div class="is-modal-overlay"></div>';
63734
- }
63735
- modal.insertAdjacentHTML('afterbegin', html);
63736
- if (!overlayStay) {
63737
- let overlay = modal.querySelector('.is-modal-overlay');
63738
- this.addEventListener(overlay, 'click', () => {
63739
- //cancelCallback
63740
- if (cancelCallback) cancelCallback();
63741
- this.hide(modal);
63742
- });
63743
- }
63749
+ angleValue.dispatchEvent(event);
63744
63750
  }
63745
63751
  }
63746
- hide(modal) {
63747
- if (this.opts.elementToAnimate !== '') {
63748
- const buildercontainers = document.querySelectorAll(this.opts.elementToAnimate);
63749
- Array.prototype.forEach.call(buildercontainers, buildercontainer => {
63750
- // buildercontainer.style.transform = '';
63751
- // buildercontainer.style.WebkitTransform= '';
63752
- // buildercontainer.style.MozTransform= '';
63753
- if (buildercontainer.getAttribute('scaled-down')) {
63754
- buildercontainer.style.transform = `scale(${this.builder.opts.zoom})`;
63755
- buildercontainer.style.WebkitTransform = `scale(${this.builder.opts.zoom})`;
63756
- buildercontainer.style.MozTransform = `scale(${this.builder.opts.zoom})`;
63757
- buildercontainer.removeAttribute('scaled-down');
63758
- }
63759
- });
63760
- }
63761
- this.removeClass(modal, 'active');
63762
- }
63763
-
63764
- // http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript
63765
- makeId() {
63766
- let text = '';
63767
- let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
63768
- for (let i = 0; i < 2; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
63769
- let text2 = '';
63770
- let possible2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
63771
- for (let i = 0; i < 5; i++) text2 += possible2.charAt(Math.floor(Math.random() * possible2.length));
63772
- return text + text2;
63773
- }
63774
- addClass(element, classname) {
63775
- if (!element) return;
63776
- if (this.hasClass(element, classname)) return;
63777
- if (element.classList.length === 0) element.className = classname;else element.className = element.className + ' ' + classname;
63752
+ startDrag(e) {
63753
+ e.preventDefault();
63754
+ const radToDeg = rad => rad * 180 / Math.PI;
63755
+ const knob = this.knob;
63756
+ const roundslider = this.roundslider;
63757
+ const angleValue = this.angleValue;
63758
+ const rect = roundslider.getBoundingClientRect();
63759
+ const centerX = rect.left + rect.width / 2;
63760
+ const centerY = rect.top + rect.height / 2;
63761
+ const mouseX = e.clientX || e.touches[0].clientX;
63762
+ const mouseY = e.clientY || e.touches[0].clientY;
63763
+ const startAngle = radToDeg(Math.atan2(mouseY - centerY, mouseX - centerX)) + 180;
63764
+ const knobAngle = parseInt(knob.dataset.angle || `${angleValue.value}`, 10);
63765
+ this.angleOffset = knobAngle - startAngle;
63766
+ this.isDragging = true;
63767
+ this.onStart();
63778
63768
  }
63779
- removeClass(element, classname) {
63780
- if (!element) return;
63781
- if (element.classList.length > 0) {
63782
- element.className = element.className.replace(classname, '');
63769
+ handleTouchMove(e) {
63770
+ if (e.touches && e.touches.length > 0) {
63771
+ this.onDrag(e.touches[0]);
63783
63772
  }
63784
63773
  }
63785
- hasClass(element, classname) {
63786
- if (!element) return false;
63787
- return element.classList ? element.classList.contains(classname) : new RegExp('\\b' + classname + '\\b').test(element.className);
63774
+ onDrag(e) {
63775
+ if (!this.isDragging) return;
63776
+ const radToDeg = rad => rad * 180 / Math.PI;
63777
+ const knob = this.knob;
63778
+ const roundslider = this.roundslider;
63779
+ const rect = roundslider.getBoundingClientRect();
63780
+ const centerX = rect.left + rect.width / 2;
63781
+ const centerY = rect.top + rect.height / 2;
63782
+ const mouseX = e.clientX || e.touches[0].clientX;
63783
+ const mouseY = e.clientY || e.touches[0].clientY;
63784
+ let angle = radToDeg(Math.atan2(mouseY - centerY, mouseX - centerX)) + 180;
63785
+ angle += this.angleOffset;
63786
+ angle = angle % 360;
63787
+ angle = angle < 0 ? 359 + angle : angle;
63788
+ knob.dataset.angle = angle.toString();
63789
+ this.setKnobPosition(angle);
63790
+ }
63791
+ endDrag() {
63792
+ this.isDragging = false;
63788
63793
  }
63789
- addEventListener(parent, type, listener) {
63790
- parent.addEventListener(type, listener);
63794
+ destroy() {
63795
+ const element = this.element;
63796
+ const knob = this.knob;
63797
+ const container = this.container;
63798
+ knob.removeEventListener('mousedown', this.startDrag);
63799
+ document.removeEventListener('mousemove', this.onDrag);
63800
+ document.removeEventListener('mouseup', this.endDrag);
63801
+ knob.removeEventListener('touchstart', this.startDrag);
63802
+ // document.removeEventListener('touchmove', e => this.onDrag(e.touches[0]));
63803
+ document.removeEventListener('touchmove', this.handleTouchMove);
63804
+ document.removeEventListener('touchend', this.endDrag);
63805
+ container.remove();
63806
+ element.style.display = '';
63791
63807
  }
63792
63808
  }
63793
63809
 
63794
- // import ColorPicker from './colorpicker.js';
63795
-
63796
63810
  class GradientPicker {
63797
- constructor(opts = {}, builder) {
63811
+ constructor(builder) {
63798
63812
  this.builder = builder;
63799
- let defaults = {
63800
- colors: ['#ff9f01', '#f57c00', '#e64918', '#d32f2f', '#5d4038', '#37474f', '#353535', '#fbc02c', '#b0b42a', '#689f39', '#c21f5b', '#7b21a2', '#522da8', '#616161', '#01b8c9', '#009688', '#388d3c', '#0388d0', '#1465c0', '#2f3f9e', '#9e9e9e'],
63801
- gradientcolors: [['linear-gradient(0deg, rgb(255, 57, 25), rgb(249, 168, 37))'], ['linear-gradient(0deg, rgb(255, 57, 25), rgb(255, 104, 15))'], ['linear-gradient(0deg, #FF5722, #FF9800)'], ['linear-gradient(0deg, #613ca2, rgb(110, 123, 217))'], ['linear-gradient(0deg, rgb(65, 70, 206), rgb(236, 78, 130))'], ['linear-gradient(0deg, rgb(0, 150, 102), rgb(90, 103, 197))'], ['linear-gradient(30deg, rgb(249, 119, 148), rgb(98, 58, 162))'], ['linear-gradient(0deg, rgb(223, 70, 137), rgb(90, 103, 197))'], ['linear-gradient(0deg, rgb(40, 53, 147), rgb(90, 103, 197))'], ['linear-gradient(0deg, rgb(21, 101, 192), rgb(52, 169, 239))'], ['linear-gradient(0deg, rgb(32, 149, 219), rgb(139, 109, 230))'], ['linear-gradient(0deg, rgb(90, 103, 197), rgb(0, 184, 201))'], ['linear-gradient(0deg, rgb(0, 184, 201), rgb(253, 187, 45))'], ['linear-gradient(0deg, rgb(255, 208, 100), rgb(239, 98, 159))'], ['linear-gradient(0deg, rgb(0, 214, 223), rgb(130, 162, 253))'], ['linear-gradient(0deg, rgb(50, 234, 251), rgb(248, 247, 126))'], ['linear-gradient(0deg, rgb(141, 221, 255), rgb(255, 227, 255))'], ['linear-gradient(0deg, rgb(255, 170, 170), rgb(255, 255, 200))'], ['linear-gradient(0deg, rgb(239, 239, 239), rgb(252, 252, 252))']],
63802
- animateModal: false,
63803
- elementToAnimate: '',
63804
- stuffPlacement: '#_cbhtml',
63805
- lang: []
63806
- };
63807
- this.opts = Object.assign(this, defaults, opts);
63808
- this.id = makeid();
63809
- let builderStuff = document.querySelector(this.opts.stuffPlacement);
63810
- if (!builderStuff) {
63811
- builderStuff = document.createElement('div');
63812
- builderStuff.id = '_cbhtml';
63813
- builderStuff.className = 'is-ui';
63814
- document.body.appendChild(builderStuff);
63815
- }
63816
- this.builderStuff = builderStuff;
63817
-
63818
- // Stuff placement for this (single) instance
63819
- const objStuff = document.createElement('div');
63820
- objStuff.id = this.id;
63821
- builderStuff.appendChild(objStuff);
63822
- this.objStuff = objStuff;
63823
- const modal = new Modal({
63824
- animateModal: this.opts.animateModal,
63825
- elementToAnimate: this.opts.elementToAnimate,
63826
- stuffPlacement: this.opts.stuffPlacement
63827
- });
63828
- this.modal = modal;
63813
+ this.builderStuff = this.builder.builderStuff;
63814
+ this.util = this.builder.util;
63829
63815
  let html_gradcolors = '';
63830
- for (var i = 0; i < this.opts.gradientcolors.length; i++) {
63831
- html_gradcolors += `<button data-elmgradient="${this.opts.gradientcolors[i][0]}" data-textcolor="${this.opts.gradientcolors[i][1] ? this.opts.gradientcolors[i][1] : ''}" style="background-image:${this.opts.gradientcolors[i][0]};"></button>`;
63832
- }
63816
+ this.builder.gradientColors.forEach(s => {
63817
+ html_gradcolors += `
63818
+ <button
63819
+ title="${this.out('Select')}"
63820
+ class="btn-graditem" data-value="${s}"
63821
+ style="background-image:${s}"></button>
63822
+ `;
63823
+ });
63833
63824
  let html = `<div class="is-pop pickgradientcolor" style="z-index:10005" tabindex="-1" role="dialog" aria-modal="true" aria-hidden="true">
63834
- <div class="div-gradients" style="display: flex;flex-flow: wrap;margin-bottom:10px;">
63825
+ <div class="div-presets">
63835
63826
  ${html_gradcolors}
63836
- <button class="input-gradient-clear" title="${this.out('Clear')}" data-value="" style="width:35px;height:35px;"><svg class="is-icon-flex" style="width:23px;height:23px;"><use xlink:href="#ion-ios-close-empty"></use></svg></button>
63837
63827
  </div>
63838
- <div class="is-settings" style="margin-bottom:0">
63839
- <div class="is-label" style="margin-top:0">${this.out('Custom')}:</div>
63840
- <div class="div-custom-gradients" style="height:auto;display: flex;flex-flow: wrap;"></div>
63841
- <div style="display: flex;align-items: center;">
63842
- <button title="${this.out('Select Color')}" class="input-gradient-color1 is-btn-color" data-value="dark" style="width:36px;height:36px;"></button>
63843
- <button title="${this.out('Select Color')}" class="input-gradient-color2 is-btn-color" data-value="dark" style="width:36px;height:36px;"></button>
63844
- <input type="text" class="input-gradient-deg" id="{id}" value="0" style="width:60px;height:35px;margin-left:7px;margin-right:5px;font-size:14px;"/> deg
63845
- </div>
63828
+
63829
+ <div class="label-saved">${this.out('Saved')}:</div>
63830
+ <div class="div-saved"></div>
63831
+
63832
+ <div class="gradient-preview"></div>
63833
+
63834
+ <div class="label-saved">${this.out('Gradient Colors')}:</div>
63835
+ <div class="div-sort"></div>
63836
+
63837
+ <div class="div-add">
63838
+ <button title="${this.out('Clear')}" class="btn-clear">
63839
+ <svg><use xlink:href="#icon-eraser"></use></svg>
63840
+ </button>
63841
+ <input type="text" class="inp-angle" value="0">
63842
+ <button title="${this.out('Add')}" class="btn-addstop"><svg class="is-icon-flex"><use xlink:href="#icon-plus"></use></svg></button>
63846
63843
  </div>
63847
- <div class="is-settings" style="margin-bottom:0">
63848
- <button title="${this.out('Add')}" class="input-gradient-save classic" style="width:100%;border:none;"> ${this.out('Add')} </button>
63844
+
63845
+ <div class="div-save">
63846
+ <button title="${this.out('Save')}" class="btn-save">${this.out('Save')}</button>
63849
63847
  </div>
63850
- </div>
63851
63848
  `;
63852
- objStuff.insertAdjacentHTML('beforeend', html.replace(/{id}/g, this.makeId()));
63853
- const pickGradient = objStuff.querySelector('.is-pop.pickgradientcolor');
63849
+ this.builderStuff.insertAdjacentHTML('beforeend', html);
63850
+ const pickGradient = this.builderStuff.querySelector('.is-pop.pickgradientcolor');
63854
63851
  this.pickGradient = pickGradient;
63855
- const setupTabKeys = div => {
63856
- let inputs = div.querySelectorAll('a[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), *[tabindex]');
63857
- if (inputs.length === 0) return;
63858
- let firstInput = inputs[0];
63859
- let lastInput = inputs[inputs.length - 1];
63860
- // firstInput.focus();
63861
-
63862
- // console.log(lastInput)
63863
- // console.log(firstInput)
63864
-
63865
- // Redirect last tab to first input
63866
- lastInput.addEventListener('keydown', e => {
63867
- if (e.which === 9 && !e.shiftKey) {
63868
- e.preventDefault();
63869
- firstInput.focus();
63870
- }
63871
- });
63852
+ this.init();
63853
+ } //constructor
63872
63854
 
63873
- // Redirect first shift+tab to last input
63874
- firstInput.addEventListener('keydown', e => {
63875
- if (e.which === 9 && e.shiftKey) {
63876
- e.preventDefault();
63877
- lastInput.focus();
63878
- }
63879
- });
63855
+ out(s) {
63856
+ if (this.builder.lang) {
63857
+ let val = this.builder.lang[s];
63858
+ if (val) return val;else {
63859
+ return s;
63860
+ }
63861
+ } else {
63862
+ return s;
63863
+ }
63864
+ }
63865
+ init() {
63866
+ this.renderSavedGradients();
63867
+ const btnAddStop = this.pickGradient.querySelector('.btn-addstop');
63868
+ if (btnAddStop) btnAddStop.addEventListener('click', () => {
63869
+ this.builder.uo.saveForUndo();
63870
+ let lastColor = this.colorsArray[this.colorsArray.length - 1];
63871
+ this.colorsArray.push(lastColor);
63872
+ this.renderColorStops();
63873
+ this.applyGradient();
63874
+ if (this.onChange) this.onChange();
63875
+ this.builder.onChange();
63876
+ });
63877
+ const btnSave = this.pickGradient.querySelector('.btn-save');
63878
+ if (btnSave) btnSave.addEventListener('click', () => {
63879
+ this.saveGradient();
63880
+ this.renderSavedGradients();
63881
+ });
63882
+ const inpAngle = this.pickGradient.querySelector('.inp-angle');
63883
+ this.slider = new RoundedSlider(inpAngle, {
63884
+ onStart: () => {
63885
+ this.builder.uo.saveForUndo(true); // checkLater = true
63886
+ }
63887
+ });
63888
+
63889
+ inpAngle.oninput = () => {
63890
+ this.angle = inpAngle.value;
63891
+ this.applyGradient();
63892
+ if (this.onChange) this.onChange();
63893
+ this.builder.onChange();
63880
63894
  };
63881
- setupTabKeys(pickGradient);
63882
- new Draggable$2({
63883
- selector: '#' + this.id + ' .is-draggable'
63895
+ const btnClear = this.pickGradient.querySelector('.btn-clear');
63896
+ if (btnClear) btnClear.addEventListener('click', () => {
63897
+ this.builder.uo.saveForUndo();
63898
+ this.colorsArray = [];
63899
+ this.renderColorStops();
63900
+ this.angle = 0;
63901
+ this.renderAngle();
63902
+ this.applyGradient();
63903
+ if (this.onChange) this.onChange();
63904
+ this.builder.onChange();
63884
63905
  });
63885
63906
 
63886
- // const colorPicker = new ColorPicker({
63887
- // colors: this.opts.colors,
63888
- // animateModal: this.opts.animateModal,
63889
- // elementToAnimate: this.opts.container,
63890
- // lang: this.opts.lang
63891
- // });
63892
- const colorPicker = this.builder.colorPicker;
63893
- let btnColor1 = objStuff.querySelector('.input-gradient-color1');
63894
- btnColor1.addEventListener('click', () => {
63895
- colorPicker.open(color => {
63896
- if (color === '') color = 'transparent';
63897
-
63898
- // set element style
63899
- let color1 = color;
63900
- let color2 = objStuff.querySelector('.input-gradient-color2').style.backgroundColor;
63901
- let deg = objStuff.querySelector('.input-gradient-deg').value;
63902
- if (color2 === '') color2 = '#ffffff';
63903
- let css = `linear-gradient(${deg}deg, ${color1}, ${color2})`;
63904
- this.targetElement.style.backgroundImage = css;
63905
- if (this.opts.onChange) this.opts.onChange(css);
63906
-
63907
- // update preview
63908
- btnColor1.style.backgroundColor = color;
63909
- }, btnColor1.style.backgroundColor, () => {
63910
- btnColor1.removeAttribute('data-focus');
63911
- btnColor1.focus();
63912
- }, btnColor1, true); // overlay=true
63913
-
63914
- btnColor1.setAttribute('data-focus', true);
63915
- });
63916
- let btnColor2 = objStuff.querySelector('.input-gradient-color2');
63917
- btnColor2.addEventListener('click', () => {
63918
- colorPicker.open(color => {
63919
- if (color === '') color = 'transparent';
63920
-
63921
- // set element style
63922
- let color1 = objStuff.querySelector('.input-gradient-color1').style.backgroundColor;
63923
- let color2 = color;
63924
- let deg = objStuff.querySelector('.input-gradient-deg').value;
63925
- if (color1 === '') color1 = '#ffffff';
63926
- let css = `linear-gradient(${deg}deg, ${color1}, ${color2})`;
63927
- this.targetElement.style.backgroundImage = css;
63928
- if (this.opts.onChange) this.opts.onChange(css);
63929
-
63930
- // update preview
63931
- btnColor2.style.backgroundColor = color;
63932
- }, btnColor2.style.backgroundColor, () => {
63933
- btnColor2.removeAttribute('data-focus');
63934
- btnColor2.focus();
63935
- }, btnColor2, true); // overlay=true
63936
-
63937
- btnColor2.setAttribute('data-focus', true);
63938
- });
63939
-
63940
- // Apply default gradient
63941
- let btns = objStuff.querySelectorAll('.div-gradients [data-elmgradient]');
63942
- Array.prototype.forEach.call(btns, btn => {
63943
- let grad = btn.getAttribute('data-elmgradient');
63944
- let textcolor = btn.getAttribute('data-textcolor');
63907
+ // presets
63908
+ const divPreset = this.pickGradient.querySelector('.div-presets');
63909
+ const btnApply = divPreset.querySelectorAll('.btn-graditem');
63910
+ btnApply.forEach(btn => {
63945
63911
  btn.addEventListener('click', () => {
63946
- this.targetElement.style.backgroundImage = grad;
63947
- if (this.opts.onChange) this.opts.onChange(grad, textcolor);
63948
-
63949
- // Read gradient
63950
- const s = this.targetElement.style.backgroundImage;
63951
- if (s.indexOf('linear-gradient') !== -1) {
63952
- const result = getGradient(s);
63953
- if (result !== null) {
63954
- try {
63955
- let color1 = result.colorStopList[0].color;
63956
- let color2 = result.colorStopList[1].color;
63957
- let line = result.line;
63958
- this.objStuff.querySelector('.input-gradient-color1').style.backgroundColor = color1;
63959
- this.objStuff.querySelector('.input-gradient-color2').style.backgroundColor = color2;
63960
- if (line.indexOf('deg') !== -1) {
63961
- this.objStuff.querySelector('.input-gradient-deg').value = line.replace('deg', '');
63962
- }
63963
- } catch (e) {
63964
- // Do Nothing
63965
- }
63966
- }
63967
- }
63968
- let btns = objStuff.querySelectorAll('.div-gradients [data-elmgradient]');
63969
- Array.prototype.forEach.call(btns, btn => {
63970
- this.removeClass(btn, 'active');
63971
- });
63972
- this.addClass(btn, 'active');
63912
+ this.builder.uo.saveForUndo();
63913
+ let cssGradient = btn.getAttribute('data-value');
63914
+ this.element.style.backgroundImage = cssGradient;
63915
+ this.btn.style.backgroundImage = cssGradient;
63916
+ const colorsArray = this.extractColors(cssGradient);
63917
+ this.colorsArray = colorsArray;
63918
+ const angle = this.extractAngle(cssGradient);
63919
+ this.angle = angle;
63920
+ this.renderAngle();
63921
+ this.renderColorStops();
63922
+ if (this.onChange) this.onChange();
63923
+ this.builder.onChange();
63973
63924
  });
63974
63925
  });
63975
- let btnClear = objStuff.querySelector('.input-gradient-clear');
63976
- btnClear.addEventListener('click', () => {
63977
- this.targetElement.style.backgroundImage = '';
63978
- if (this.opts.onChange) this.opts.onChange('');
63979
- this.objStuff.querySelector('.input-gradient-color1').style.backgroundColor = '';
63980
- this.objStuff.querySelector('.input-gradient-color2').style.backgroundColor = '';
63981
- this.objStuff.querySelector('.input-gradient-deg').value = '0';
63982
- });
63983
- let inputDeg = objStuff.querySelector('.input-gradient-deg');
63984
- inputDeg.addEventListener('keyup', () => {
63985
- // set element style
63986
- let color1 = objStuff.querySelector('.input-gradient-color1').style.backgroundColor;
63987
- let color2 = objStuff.querySelector('.input-gradient-color2').style.backgroundColor;
63988
- let deg = inputDeg.value;
63926
+ }
63927
+ saveGradient() {
63928
+ let gradient = {
63929
+ angle: this.angle,
63930
+ colors: this.colorsArray
63931
+ };
63932
+ this.savedGrads.push(gradient);
63933
+ localStorage.setItem('_savedgrads', JSON.stringify(this.savedGrads));
63934
+ }
63935
+ renderSavedGradients() {
63936
+ let savedGrads = [];
63937
+ if (localStorage.getItem('_savedgrads') !== null) {
63938
+ savedGrads = JSON.parse(localStorage.getItem('_savedgrads'));
63939
+ }
63940
+ this.savedGrads = savedGrads;
63989
63941
 
63990
- // if(color1 === '') color1 = '#ffffff';
63991
- // if(color2 === '') color2 = '#ffffff';
63942
+ // backward (move old saved gradients to the new. Then delete the old)
63943
+ let oldGrads = [];
63944
+ let customgradcolors = [];
63945
+ if (localStorage.getItem('_customgradcolors') !== null) {
63946
+ customgradcolors = JSON.parse(localStorage.getItem('_customgradcolors'));
63947
+ customgradcolors.forEach(cssGradient => {
63948
+ const colorsArray = this.extractColors(cssGradient);
63949
+ const angle = this.extractAngle(cssGradient);
63950
+ let gradient = {
63951
+ angle: angle,
63952
+ colors: colorsArray
63953
+ };
63954
+ oldGrads.push(gradient);
63955
+ });
63956
+ Array.prototype.push.apply(this.savedGrads, oldGrads); // combine old with the new
63957
+ localStorage.setItem('_savedgrads', JSON.stringify(this.savedGrads));
63958
+ localStorage.removeItem('_customgradcolors');
63959
+ }
63960
+ // /backward
63992
63961
 
63993
- let css = `linear-gradient(${deg}deg, ${color1}, ${color2})`;
63994
- this.targetElement.style.backgroundImage = css;
63995
- if (this.opts.onChange) this.opts.onChange(css);
63962
+ const divSaved = this.pickGradient.querySelector('.div-saved');
63963
+ const labelSaved = this.pickGradient.querySelector('.label-saved');
63964
+ let html = '';
63965
+ savedGrads.forEach((gradient, index) => {
63966
+ let deg = gradient.angle;
63967
+ let colorsArray = gradient.colors;
63968
+ let s = this.convertColorsToGradient(colorsArray, deg);
63969
+ html += `
63970
+ <div>
63971
+ <button
63972
+ data-index="${index}"
63973
+ title="${this.out('Select')}"
63974
+ class="btn-graditem" data-value="${s}"
63975
+ style="background-image:${s}"></button>
63976
+
63977
+ <button title="${this.out('Remove')}" class="btn-remove">
63978
+ <svg class="is-icon-flex"><use xlink:href="#icon-minus"></use></svg>
63979
+ </button>
63980
+ </div>
63981
+ `;
63996
63982
  });
63997
- let btnSave = objStuff.querySelector('.input-gradient-save');
63998
- btnSave.addEventListener('click', () => {
63999
- let color1 = objStuff.querySelector('.input-gradient-color1').style.backgroundColor;
64000
- let color2 = objStuff.querySelector('.input-gradient-color2').style.backgroundColor;
64001
- let deg = inputDeg.value;
64002
-
64003
- // if(color1 === '') color1 = '#ffffff';
64004
- // if(color2 === '') color2 = '#ffffff';
64005
-
64006
- let css = `linear-gradient(${deg}deg, ${color1}, ${color2})`;
64007
-
64008
- // Save
64009
- let customgradcolors = [];
64010
- if (localStorage.getItem('_customgradcolors') !== null) {
64011
- customgradcolors = JSON.parse(localStorage.getItem('_customgradcolors'));
64012
- }
64013
- customgradcolors.push(css);
64014
- localStorage.setItem('_customgradcolors', JSON.stringify(customgradcolors));
64015
-
64016
- // Render custom gradients
64017
- if (localStorage.getItem('_customgradcolors') !== null) {
64018
- let customgradcolors = JSON.parse(localStorage.getItem('_customgradcolors'));
64019
- let html_gradcolors = '';
64020
- for (var i = 0; i < customgradcolors.length; i++) {
64021
- html_gradcolors += `<button class="is-elmgrad-item" data-elmgradient="${customgradcolors[i]}" style="background-image:${customgradcolors[i]};"><div class="is-elmgrad-remove"><svg class="is-icon-flex" style="fill:rgba(255, 255, 255, 1);width:20px;height:20px;"><use xlink:href="#ion-ios-close-empty"></use></svg></div></button>`;
64022
- }
64023
- this.objStuff.querySelector('.div-custom-gradients').innerHTML = html_gradcolors;
64024
- }
64025
-
64026
- // Apply custom gradient
64027
- let btns = this.objStuff.querySelectorAll('.div-custom-gradients [data-elmgradient]');
64028
- Array.prototype.forEach.call(btns, btn => {
64029
- let grad = btn.getAttribute('data-elmgradient');
64030
- btn.addEventListener('click', () => {
64031
- this.targetElement.style.backgroundImage = grad;
64032
- if (this.opts.onChange) this.opts.onChange(grad);
64033
-
64034
- // Read gradient
64035
- const s = this.targetElement.style.backgroundImage;
64036
- if (s.indexOf('linear-gradient') !== -1) {
64037
- const result = getGradient(s);
64038
- if (result !== null) {
64039
- try {
64040
- let color1 = result.colorStopList[0].color;
64041
- let color2 = result.colorStopList[1].color;
64042
- let line = result.line;
64043
- this.objStuff.querySelector('.input-gradient-color1').style.backgroundColor = color1;
64044
- this.objStuff.querySelector('.input-gradient-color2').style.backgroundColor = color2;
64045
- if (line.indexOf('deg') !== -1) {
64046
- this.objStuff.querySelector('.input-gradient-deg').value = line.replace('deg', '');
64047
- }
64048
- } catch (e) {
64049
- // Do Nothing
64050
- }
64051
- }
64052
- }
64053
- let btns = objStuff.querySelectorAll('.div-custom-gradients [data-elmgradient]');
64054
- Array.prototype.forEach.call(btns, btn => {
64055
- this.removeClass(btn, 'active');
64056
- });
64057
- this.addClass(btn, 'active');
64058
- });
63983
+ divSaved.innerHTML = html;
63984
+ if (savedGrads.length === 0) {
63985
+ divSaved.style.display = 'none';
63986
+ labelSaved.style.display = 'none';
63987
+ } else {
63988
+ divSaved.style.display = '';
63989
+ labelSaved.style.display = '';
63990
+ }
63991
+ const btnApply = divSaved.querySelectorAll('.btn-graditem');
63992
+ btnApply.forEach(btn => {
63993
+ btn.addEventListener('click', () => {
63994
+ this.builder.uo.saveForUndo();
63995
+ let cssGradient = btn.getAttribute('data-value');
63996
+ this.element.style.backgroundImage = cssGradient;
63997
+ this.btn.style.backgroundImage = cssGradient;
63998
+ const colorsArray = this.extractColors(cssGradient);
63999
+ this.colorsArray = colorsArray;
64000
+ const angle = this.extractAngle(cssGradient);
64001
+ this.angle = angle;
64002
+ this.renderAngle();
64003
+ this.renderColorStops();
64004
+ if (this.onChange) this.onChange();
64005
+ this.builder.onChange();
64059
64006
  });
64060
-
64061
- // Delete custom gradient
64062
- let btnsRemoveGrad = this.objStuff.querySelectorAll('.div-custom-gradients .is-elmgrad-remove');
64063
- Array.prototype.forEach.call(btnsRemoveGrad, btnRemoveGrad => {
64064
- btnRemoveGrad.addEventListener('click', e => {
64065
- //Custom grad colors
64066
- let customgradcolors = [];
64067
- if (localStorage.getItem('_customgradcolors') !== null) {
64068
- customgradcolors = JSON.parse(localStorage.getItem('_customgradcolors'));
64069
- }
64070
- var css = btnRemoveGrad.parentNode.getAttribute('data-elmgradient');
64071
- for (var i = 0; i < customgradcolors.length; i++) {
64072
- if (customgradcolors[i] === css) {
64073
- customgradcolors.splice(i, 1);
64074
- }
64075
- }
64076
- localStorage.setItem('_customgradcolors', JSON.stringify(customgradcolors));
64077
- btnRemoveGrad.closest('.is-elmgrad-item').remove();
64078
- e.preventDefault();
64079
- e.stopImmediatePropagation();
64080
- });
64007
+ });
64008
+ const btnRemove = divSaved.querySelectorAll('.btn-remove');
64009
+ btnRemove.forEach(btn => {
64010
+ btn.addEventListener('click', e => {
64011
+ let index = btn.getAttribute('data-index');
64012
+ btn.parentNode.remove();
64013
+ this.removeItemByIndex(this.savedGrads, index);
64014
+ localStorage.setItem('_savedgrads', JSON.stringify(this.savedGrads));
64015
+ if (this.savedGrads.length === 0) {
64016
+ divSaved.style.display = 'none';
64017
+ labelSaved.style.display = 'none';
64018
+ } else {
64019
+ divSaved.style.display = '';
64020
+ labelSaved.style.display = '';
64021
+ }
64022
+ e.preventDefault();
64023
+ e.stopImmediatePropagation();
64081
64024
  });
64082
64025
  });
64083
- } //constructor
64084
-
64085
- makeId() {
64086
- let text = '';
64087
- let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
64088
- for (let i = 0; i < 2; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
64089
- let text2 = '';
64090
- let possible2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
64091
- for (let i = 0; i < 5; i++) text2 += possible2.charAt(Math.floor(Math.random() * possible2.length));
64092
- return text + text2;
64093
64026
  }
64094
- out(s) {
64095
- if (this.opts.lang) {
64096
- let val = this.opts.lang[s];
64097
- if (val) return val;else {
64098
- return s;
64099
- }
64027
+ removeItemByIndex(arr, index) {
64028
+ if (index > -1 && index < arr.length) {
64029
+ arr.splice(index, 1);
64030
+ }
64031
+ return arr;
64032
+ }
64033
+ extractColors(gradientString) {
64034
+ // Regular expression to match rgb(a) colors and hex colors (with optional alpha)
64035
+ const colorRegex = /rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*\d*\.?\d+\s*)?\)|#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?/g;
64036
+ // Extract all color occurrences
64037
+ const colors = gradientString.match(colorRegex);
64038
+ return colors || [];
64039
+ }
64040
+ extractAngle(gradientString) {
64041
+ const anglePattern = /linear-gradient\((\d+)deg,/;
64042
+ const match = anglePattern.exec(gradientString);
64043
+ if (match && match[1]) {
64044
+ return parseInt(match[1], 10);
64100
64045
  } else {
64101
- return s;
64046
+ return 0;
64102
64047
  }
64103
64048
  }
64104
- open(elm, onChange, onFinish, btn, overlay) {
64105
- this.opts.onChange = onChange;
64106
- this.opts.onFinish = onFinish;
64107
- this.targetElement = elm;
64108
-
64109
- // Read gradient
64110
- this.objStuff.querySelector('.input-gradient-color1').style.backgroundColor = '';
64111
- this.objStuff.querySelector('.input-gradient-color2').style.backgroundColor = '';
64112
- this.objStuff.querySelector('.input-gradient-deg').value = '0';
64113
- const s = elm.style.backgroundImage;
64114
- if (s.indexOf('linear-gradient') !== -1) {
64115
- const result = getGradient(s);
64116
- if (result !== null) {
64117
- try {
64118
- let color1 = result.colorStopList[0].color;
64119
- let color2 = result.colorStopList[1].color;
64120
- let line = result.line;
64121
- this.objStuff.querySelector('.input-gradient-color1').style.backgroundColor = color1;
64122
- this.objStuff.querySelector('.input-gradient-color2').style.backgroundColor = color2;
64123
- if (line.indexOf('deg') !== -1) {
64124
- this.objStuff.querySelector('.input-gradient-deg').value = line.replace('deg', '');
64125
- }
64126
- } catch (e) {
64127
- // Do Nothing
64128
- }
64049
+ updateColorsArray() {
64050
+ let arr = [];
64051
+ const divSort = this.pickGradient.querySelector('.div-sort');
64052
+ divSort.querySelectorAll('button[data-color]').forEach(btn => {
64053
+ let s = btn.getAttribute('data-color');
64054
+ arr.push(s);
64055
+ });
64056
+ this.colorsArray = arr;
64057
+ }
64058
+ allowRemoveStop() {
64059
+ const divSort = this.pickGradient.querySelector('.div-sort');
64060
+ const btns = divSort.querySelectorAll('button[data-color]');
64061
+ if (btns.length === 2) {
64062
+ return false;
64063
+ } else {
64064
+ return true;
64065
+ }
64066
+ }
64067
+ convertColorsToGradient(colorsArray, deg = 0) {
64068
+ let gradientString = `linear-gradient(${deg}deg, `;
64069
+ colorsArray.forEach((color, index) => {
64070
+ gradientString += color;
64071
+ if (index < colorsArray.length - 1) {
64072
+ gradientString += ', ';
64129
64073
  }
64074
+ });
64075
+ gradientString += ')';
64076
+ return gradientString;
64077
+ }
64078
+ applyGradient() {
64079
+ let cssGradient;
64080
+ if (this.colorsArray.length === 0) {
64081
+ cssGradient = '';
64082
+ } else {
64083
+ cssGradient = this.convertColorsToGradient(this.colorsArray, this.angle);
64084
+ }
64085
+ this.element.style.backgroundImage = cssGradient;
64086
+ this.btn.style.backgroundImage = cssGradient;
64087
+ const divPreview = this.pickGradient.querySelector('.gradient-preview');
64088
+ divPreview.style.backgroundImage = cssGradient;
64089
+ }
64090
+ areArraysIdentical(arr1, arr2) {
64091
+ if (arr1.length !== arr2.length) {
64092
+ return false; // Arrays of different lengths cannot be identical
64130
64093
  }
64131
64094
 
64132
- // Save original style
64133
- this.original = s;
64134
-
64135
- // Render custom gradients
64136
- let customgradcolors = [];
64137
- if (localStorage.getItem('_customgradcolors') !== null) {
64138
- customgradcolors = JSON.parse(localStorage.getItem('_customgradcolors'));
64139
- let html_gradcolors = '';
64140
- for (var i = 0; i < customgradcolors.length; i++) {
64141
- html_gradcolors += `<button class="is-elmgrad-item" data-elmgradient="${customgradcolors[i]}" style="background-image:${customgradcolors[i]};"><div class="is-elmgrad-remove"><svg class="is-icon-flex" style="fill:rgba(255, 255, 255, 1);width:20px;height:20px;"><use xlink:href="#ion-ios-close-empty"></use></svg></div></button>`;
64095
+ for (let i = 0; i < arr1.length; i++) {
64096
+ if (arr1[i] !== arr2[i]) {
64097
+ return false; // Found elements that are not the same
64142
64098
  }
64143
- this.objStuff.querySelector('.div-custom-gradients').innerHTML = html_gradcolors;
64144
64099
  }
64145
64100
 
64146
- // Apply custom gradient
64147
- let btns = this.objStuff.querySelectorAll('.div-custom-gradients [data-elmgradient]');
64148
- Array.prototype.forEach.call(btns, btn => {
64149
- let grad = btn.getAttribute('data-elmgradient');
64101
+ return true; // All elements are the same and in the same order
64102
+ }
64103
+
64104
+ renderColorStops() {
64105
+ let colorsArray = this.colorsArray;
64106
+ if (colorsArray.length === 0) {
64107
+ colorsArray = ['rgba(255, 255, 255, 1)', 'rgba(255, 255, 255, 1)'];
64108
+ }
64109
+ let htmlStop = '';
64110
+ let n = 0;
64111
+ colorsArray.forEach(color => {
64112
+ htmlStop += `<div>
64113
+ <button data-color="${color}"
64114
+ data-index="${n}"
64115
+ title="${this.out('Select Color')}"
64116
+ class="btn-colorstop is-btn-color"
64117
+ data-value="${color}"
64118
+ style="background-color:${color}"></button>
64119
+
64120
+ <button title="${this.out('Remove')}" class="btn-remove">
64121
+ <svg class="is-icon-flex"><use xlink:href="#icon-minus"></use></svg>
64122
+ </button>
64123
+ </div>`;
64124
+ n++;
64125
+ });
64126
+ const divSort = this.pickGradient.querySelector('.div-sort');
64127
+ divSort.innerHTML = htmlStop;
64128
+ new Sortable(divSort, {
64129
+ animation: 600,
64130
+ dragClass: 'hide-drag-class',
64131
+ onStart: () => {},
64132
+ onSort: () => {
64133
+ this.updateColorsArray();
64134
+ this.applyGradient();
64135
+ }
64136
+ });
64137
+ const colorPicker = this.builder.colorPicker;
64138
+ const btnPicks = this.pickGradient.querySelectorAll('.btn-colorstop');
64139
+ btnPicks.forEach(btn => {
64150
64140
  btn.addEventListener('click', () => {
64151
- this.targetElement.style.backgroundImage = grad;
64152
- if (this.opts.onChange) this.opts.onChange(grad);
64153
-
64154
- // Read gradient
64155
- const s = this.targetElement.style.backgroundImage;
64156
- if (s.indexOf('linear-gradient') !== -1) {
64157
- const result = getGradient(s);
64158
- if (result !== null) {
64159
- try {
64160
- let color1 = result.colorStopList[0].color;
64161
- let color2 = result.colorStopList[1].color;
64162
- let line = result.line;
64163
- this.objStuff.querySelector('.input-gradient-color1').style.backgroundColor = color1;
64164
- this.objStuff.querySelector('.input-gradient-color2').style.backgroundColor = color2;
64165
- if (line.indexOf('deg') !== -1) {
64166
- this.objStuff.querySelector('.input-gradient-deg').value = line.replace('deg', '');
64167
- }
64168
- } catch (e) {
64169
- // Do Nothing
64141
+ this.builder.uo.saveForUndo(true);
64142
+ colorPicker.open(color => {
64143
+ if (color === '') {
64144
+ const allow = this.allowRemoveStop();
64145
+ if (allow) {
64146
+ // clear
64147
+ btn.parentNode.remove();
64148
+ this.updateColorsArray();
64149
+ this.applyGradient();
64150
+ if (this.onChange) this.onChange();
64151
+ this.builder.onChange();
64152
+ this.builder.util.hidePopOverlay(); // if pop is opened using overlay, to programmatically close, use this
64153
+ return;
64170
64154
  }
64171
64155
  }
64172
- }
64173
- let btns = this.objStuff.querySelectorAll('.div-custom-gradients [data-elmgradient]');
64174
- Array.prototype.forEach.call(btns, btn => {
64175
- this.removeClass(btn, 'active');
64176
- });
64177
- this.addClass(btn, 'active');
64156
+ if (color === '') color = 'rgba(255, 255, 255, 1)'; // gradient stop requires value
64157
+
64158
+ btn.setAttribute('data-color', color);
64159
+ btn.style.backgroundColor = color;
64160
+ this.updateColorsArray();
64161
+ if (this.areArraysIdentical(this.colorsArray, ['rgba(255, 255, 255, 1)', 'rgba(255, 255, 255, 1)'])) {
64162
+ console.log('Initial, no gradient');
64163
+ return;
64164
+ }
64165
+ this.applyGradient();
64166
+ if (this.onChange) this.onChange();
64167
+ this.builder.onChange();
64168
+ }, btn.style.backgroundColor, () => {
64169
+ btn.removeAttribute('data-focus');
64170
+ btn.focus();
64171
+ }, btn, true); // overlay=true
64172
+
64173
+ btn.setAttribute('data-focus', true);
64178
64174
  });
64179
64175
  });
64176
+ const btnRemove = divSort.querySelectorAll('.btn-remove');
64177
+ btnRemove.forEach(btn => {
64178
+ btn.addEventListener('click', e => {
64179
+ this.builder.uo.saveForUndo();
64180
+ const allow = this.allowRemoveStop();
64181
+ if (allow) {
64182
+ btn.parentNode.remove();
64183
+ } else {
64184
+ let color = 'rgba(255, 255, 255, 1)'; // gradient stop requires value
64180
64185
 
64181
- // Delete custom gradient
64182
- let btnsRemoveGrad = this.objStuff.querySelectorAll('.div-custom-gradients .is-elmgrad-remove');
64183
- Array.prototype.forEach.call(btnsRemoveGrad, btnRemoveGrad => {
64184
- btnRemoveGrad.addEventListener('click', e => {
64185
- //Custom grad colors
64186
- let customgradcolors = [];
64187
- if (localStorage.getItem('_customgradcolors') !== null) {
64188
- customgradcolors = JSON.parse(localStorage.getItem('_customgradcolors'));
64186
+ const btnColor = btn.parentNode.querySelector('.btn-colorstop');
64187
+ btnColor.setAttribute('data-color', color);
64188
+ btnColor.style.backgroundColor = color;
64189
64189
  }
64190
- var css = btnRemoveGrad.parentNode.getAttribute('data-elmgradient');
64191
- for (var i = 0; i < customgradcolors.length; i++) {
64192
- if (customgradcolors[i] === css) {
64193
- customgradcolors.splice(i, 1);
64194
- }
64195
- }
64196
- localStorage.setItem('_customgradcolors', JSON.stringify(customgradcolors));
64197
- btnRemoveGrad.closest('.is-elmgrad-item').remove();
64190
+ this.updateColorsArray();
64191
+ this.applyGradient();
64192
+ if (this.onChange) this.onChange();
64193
+ this.builder.onChange();
64198
64194
  e.preventDefault();
64199
64195
  e.stopImmediatePropagation();
64200
64196
  });
64201
64197
  });
64202
- const handleKeyDown = e => {
64203
- if (e.keyCode === 27) {
64204
- // escape key
64205
- this.pickGradient.classList.remove('active'); // hide
64206
-
64207
- this.pickGradient.removeEventListener('keydown', handleKeyDown);
64208
-
64209
- // no change
64210
- if (this.opts.onFinish) {
64211
- this.opts.onFinish(false);
64212
- }
64213
- }
64214
- };
64215
-
64216
- // this.modal.show(this.pickGradient, false, ()=>{
64217
-
64218
- // this.pickGradient.removeEventListener('keydown', handleKeyDown);
64198
+ }
64199
+ renderAngle() {
64200
+ const inpAngle = this.pickGradient.querySelector('.inp-angle');
64201
+ inpAngle.value = this.angle;
64202
+ if (this.slider.created) this.slider.setValue(this.angle, true); // use only after slider.create()
64203
+ // true = no trigger only for setting angle position
64204
+ }
64219
64205
 
64220
- // if(this.original === this.targetElement.style.backgroundImage) {
64221
- // // no change
64222
- // if(this.opts.onFinish) {
64223
- // this.opts.onFinish(false);
64224
- // }
64225
- // } else {
64226
- // // changed
64227
- // if(this.opts.onFinish) {
64228
- // this.opts.onFinish(true);
64229
- // }
64230
- // }
64206
+ open(elm, onChange, onFinish, btn, overlay) {
64207
+ // Pop Stuff first
64231
64208
 
64232
- // }, false);
64233
64209
  if (!btn) {
64234
64210
  const iframes = document.getElementsByTagName('iframe');
64235
64211
  for (let i = 0; i < iframes.length; i++) {
@@ -64246,7 +64222,7 @@ class GradientPicker {
64246
64222
  if (!btn) btn = document.activeElement;
64247
64223
  }
64248
64224
  let popGradient = this.pickGradient;
64249
- this.builder.util.showPop(popGradient, false, btn, overlay);
64225
+ this.builder.util.showPop(popGradient, onFinish, btn, overlay);
64250
64226
  const w = popGradient.offsetWidth;
64251
64227
  const h = popGradient.offsetHeight;
64252
64228
  const newPos = this.getElementPosition(btn);
@@ -64317,28 +64293,24 @@ class GradientPicker {
64317
64293
  };
64318
64294
  doc.addEventListener('click', handlePopClickOut);
64319
64295
  }
64320
- this.pickGradient.addEventListener('keydown', handleKeyDown);
64321
64296
 
64322
- // const btn = this.pickGradient.querySelector('button');
64323
- // btn.focus();
64324
- }
64297
+ // Gradient Stuff
64325
64298
 
64326
- addClass(element, classname) {
64327
- if (!element) return;
64328
- if (this.hasClass(element, classname)) return;
64329
- if (element.classList.length === 0) element.className = classname;else element.className = element.className + ' ' + classname;
64330
- //else element.classList.add(classname); //error if there is -
64331
- }
64299
+ this.element = elm;
64300
+ this.btn = btn;
64301
+ this.onChange = onChange;
64302
+ // this.onFinish = onFinish; // used in showPop below
64332
64303
 
64333
- removeClass(element, classname) {
64334
- if (!element) return;
64335
- if (element.classList.length > 0) {
64336
- element.className = element.className.replace(classname, '');
64337
- }
64338
- }
64339
- hasClass(element, classname) {
64340
- if (!element) return false;
64341
- return element.classList ? element.classList.contains(classname) : new RegExp('\\b' + classname + '\\b').test(element.className);
64304
+ let cssGradient = elm.style.backgroundImage;
64305
+ const colorsArray = this.extractColors(cssGradient);
64306
+ this.colorsArray = colorsArray;
64307
+ const angle = this.extractAngle(cssGradient);
64308
+ this.angle = angle;
64309
+ this.renderAngle();
64310
+ this.renderColorStops();
64311
+ setTimeout(() => {
64312
+ this.slider.create();
64313
+ }, 0);
64342
64314
  }
64343
64315
  getElementPosition(element) {
64344
64316
  const top = element.getBoundingClientRect().top;
@@ -64364,156 +64336,6 @@ class GradientPicker {
64364
64336
  }
64365
64337
  }
64366
64338
 
64367
- // source: http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript
64368
- function makeid() {
64369
- let text = '';
64370
- let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
64371
- for (let i = 0; i < 2; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
64372
- let text2 = '';
64373
- let possible2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
64374
- for (let i = 0; i < 5; i++) text2 += possible2.charAt(Math.floor(Math.random() * possible2.length));
64375
- return text + text2;
64376
- }
64377
-
64378
- // source: https://stackoverflow.com/questions/20215440/parse-css-gradient-rule-with-javascript-regex
64379
- function getGradient(input) {
64380
- var result,
64381
- regExpLib = generateRegExp(),
64382
- //rGradientEnclosedInBrackets = /.*gradient\s*\(((?:\([^\)]*\)|[^\)\(]*)*)\)/,// Captures inside brackets - max one additional inner set.
64383
- rGradientEnclosedInBrackets = /.*gradient\s*\(((?:\([^)]*\)|[^)(]*)*)\)/,
64384
- // Oct 29, 2019
64385
- match = rGradientEnclosedInBrackets.exec(input);
64386
- if (match !== null) {
64387
- // Get the parameters for the gradient
64388
- result = parseGradient(regExpLib, match[1]);
64389
- if (result.original.trim() !== match[1].trim()) {
64390
- // Did not match the input exactly - possible parsing error.
64391
- result.parseWarning = true;
64392
- }
64393
- } else {
64394
- result = 'Failed to find gradient';
64395
- }
64396
- return result;
64397
- }
64398
- var combineRegExp = function (regexpList, flags) {
64399
- var i,
64400
- source = '';
64401
- for (i = 0; i < regexpList.length; i++) {
64402
- if (typeof regexpList[i] === 'string') {
64403
- source += regexpList[i];
64404
- } else {
64405
- source += regexpList[i].source;
64406
- }
64407
- }
64408
- return new RegExp(source, flags);
64409
- };
64410
- var generateRegExp = function () {
64411
- // Note any variables with "Capture" in name include capturing bracket set(s).
64412
- var searchFlags = 'gi',
64413
- // ignore case for angles, "rgb" etc
64414
- rAngle = /(?:[+-]?\d*\.?\d+)(?:deg|grad|rad|turn)/,
64415
- // Angle +ive, -ive and angle types
64416
- rSideCornerCapture = /to\s+((?:(?:left|right)(?:\s+(?:top|bottom))?))/,
64417
- // optional 2nd part
64418
- rComma = /\s*,\s*/,
64419
- // Allow space around comma.
64420
- //rColorHex = /\#(?:[a-f0-9]{6}|[a-f0-9]{3})/, // 3 or 6 character form
64421
- rColorHex = /#(?:[a-f0-9]{6}|[a-f0-9]{3})/,
64422
- // 3 or 6 character form // Oct 29, 2019
64423
- rDigits3 = /\(\s*(?:\d{1,3}\s*,\s*){2}\d{1,3}\s*\)/,
64424
- // "(1, 2, 3)"
64425
- rDigits4 = /\(\s*(?:\d{1,3}\s*,\s*){2}\d{1,3}\s*,\s*\d*\.?\d+\)/,
64426
- // "(1, 2, 3, 4)"
64427
- rValue = /(?:[+-]?\d*\.?\d+)(?:%|[a-z]+)?/,
64428
- // ".9", "-5px", "100%".
64429
- rKeyword = /[_a-z-][_a-z0-9-]*/,
64430
- // "red", "transparent", "border-collapse".
64431
- rColor = combineRegExp(['(?:', rColorHex, '|', '(?:rgb|hsl)', rDigits3, '|', '(?:rgba|hsla)', rDigits4, '|', rKeyword, ')'], ''),
64432
- rColorStop = combineRegExp([rColor, '(?:\\s+', rValue, '(?:\\s+', rValue, ')?)?'], ''),
64433
- // Single Color Stop, optional %, optional length.
64434
- rColorStopList = combineRegExp(['(?:', rColorStop, rComma, ')*', rColorStop], ''),
64435
- // List of color stops min 1.
64436
- rLineCapture = combineRegExp(['(?:(', rAngle, ')|', rSideCornerCapture, ')'], ''),
64437
- // Angle or SideCorner
64438
- rGradientSearch = combineRegExp(['(?:(', rLineCapture, ')', rComma, ')?(', rColorStopList, ')'], searchFlags),
64439
- // Capture 1:"line", 2:"angle" (optional), 3:"side corner" (optional) and 4:"stop list".
64440
- rColorStopSearch = combineRegExp(['\\s*(', rColor, ')', '(?:\\s+', '(', rValue, '))?', '(?:', rComma, '\\s*)?'], searchFlags); // Capture 1:"color" and 2:"position" (optional).
64441
-
64442
- return {
64443
- gradientSearch: rGradientSearch,
64444
- colorStopSearch: rColorStopSearch
64445
- };
64446
- };
64447
- var parseGradient = function (regExpLib, input) {
64448
- var result, matchGradient, matchColorStop, stopResult;
64449
-
64450
- // reset search position, because we reuse regex.
64451
- regExpLib.gradientSearch.lastIndex = 0;
64452
- matchGradient = regExpLib.gradientSearch.exec(input);
64453
- if (matchGradient !== null) {
64454
- result = {
64455
- original: matchGradient[0],
64456
- colorStopList: []
64457
- };
64458
-
64459
- // // Line (Angle or Side-Corner).
64460
- // if (!!matchGradient[1]) {
64461
- // result.line = matchGradient[1];
64462
- // }
64463
- // // Angle or undefined if side-corner.
64464
- // if (!!matchGradient[2]) {
64465
- // result.angle = matchGradient[2];
64466
- // }
64467
- // // Side-corner or undefined if angle.
64468
- // if (!!matchGradient[3]) {
64469
- // result.sideCorner = matchGradient[3];
64470
- // }
64471
-
64472
- // Oct 29, 2019
64473
- // Line (Angle or Side-Corner).
64474
- if (matchGradient[1]) {
64475
- result.line = matchGradient[1];
64476
- }
64477
- // Angle or undefined if side-corner.
64478
- if (matchGradient[2]) {
64479
- result.angle = matchGradient[2];
64480
- }
64481
- // Side-corner or undefined if angle.
64482
- if (matchGradient[3]) {
64483
- result.sideCorner = matchGradient[3];
64484
- }
64485
-
64486
- // reset search position, because we reuse regex.
64487
- regExpLib.colorStopSearch.lastIndex = 0;
64488
-
64489
- // Loop though all the color-stops.
64490
- matchColorStop = regExpLib.colorStopSearch.exec(matchGradient[4]);
64491
- while (matchColorStop !== null) {
64492
- stopResult = {
64493
- color: matchColorStop[1]
64494
- };
64495
-
64496
- // // Position (optional).
64497
- // if (!!matchColorStop[2]) {
64498
- // stopResult.position = matchColorStop[2];
64499
- // }
64500
-
64501
- // Oct 29, 2019
64502
- // Position (optional).
64503
- if (matchColorStop[2]) {
64504
- stopResult.position = matchColorStop[2];
64505
- }
64506
- result.colorStopList.push(stopResult);
64507
-
64508
- // Continue searching from previous position.
64509
- matchColorStop = regExpLib.colorStopSearch.exec(matchGradient[4]);
64510
- }
64511
- }
64512
-
64513
- // Can be undefined if match not found.
64514
- return result;
64515
- };
64516
-
64517
64339
  const fontList = [{
64518
64340
  value: '',
64519
64341
  label: '',
@@ -81686,6 +81508,10 @@ class Dictation {
81686
81508
  this.builderStuff = builderStuff;
81687
81509
  const util = this.builder.util;
81688
81510
  this.util = util;
81511
+ let disclaimerText = util.out('AI-Disclaimer');
81512
+ if (disclaimerText === 'AI-Disclaimer') {
81513
+ disclaimerText = this.builder.disclaimerAI;
81514
+ }
81689
81515
 
81690
81516
  // const dom = this.builder.dom;
81691
81517
 
@@ -81895,7 +81721,7 @@ class Dictation {
81895
81721
  ${util.out('AI-Powered Features')}
81896
81722
  <button class="is-modal-close" tabindex="-1" title="${util.out('Close')}">&#10005;</button>
81897
81723
  </div>
81898
- ${util.out('AI-Disclaimer', this.builder.disclaimerAI)}
81724
+ ${disclaimerText}
81899
81725
  <div style="text-align:right;margin-top:20px;">
81900
81726
  <button title="${util.out('Ok')}" class="input-ok classic-primary" style="width:100%;text-transform: uppercase;
81901
81727
  font-size: 14px;">${util.out('Ok')}</button>
@@ -84600,22 +84426,25 @@ class Command {
84600
84426
  const builderStuff = this.builder.builderStuff;
84601
84427
  this.builderStuff = builderStuff;
84602
84428
  this.lib = new Lib(builder);
84603
- let html = `
84604
- <div class="is-modal ai-disclaimer" style="z-index:10005" tabindex="-1" role="dialog" aria-modal="true" aria-hidden="true">
84605
- <div class="is-modal-content" style="max-width:450px;padding:55px 40px 35px;font-size:16px;line-height:1.4;letter-spacing: 1px;">
84606
- <div class="is-modal-bar is-draggable">
84607
- ${util.out('AI-Powered Features')}
84608
- <button class="is-modal-close" tabindex="-1" title="${util.out('Close')}">&#10005;</button>
84609
- </div>
84610
- ${util.out('AI-Disclaimer', this.builder.disclaimerAI)}
84611
- <div style="text-align:right;margin-top:20px;">
84612
- <button title="${util.out('Ok')}" class="input-ok classic-primary" style="width:100%;text-transform: uppercase;
84613
- font-size: 14px;">${util.out('Ok')}</button>
84614
- </div>
84615
- </div>
84616
- </div>`;
84617
- builderStuff.insertAdjacentHTML('beforeend', html);
84618
- this.modalDisclaimer = builderStuff.querySelector('.ai-disclaimer');
84429
+ let html = '';
84430
+ // let html = `
84431
+ // <div class="is-modal ai-disclaimer" style="z-index:10005" tabindex="-1" role="dialog" aria-modal="true" aria-hidden="true">
84432
+ // <div class="is-modal-content" style="max-width:450px;padding:55px 40px 35px;font-size:16px;line-height:1.4;letter-spacing: 1px;">
84433
+ // <div class="is-modal-bar is-draggable">
84434
+ // ${util.out('AI-Powered Features')}
84435
+ // <button class="is-modal-close" tabindex="-1" title="${util.out('Close')}">&#10005;</button>
84436
+ // </div>
84437
+ // ${util.out('AI-Disclaimer', this.builder.disclaimerAI)}
84438
+ // <div style="text-align:right;margin-top:20px;">
84439
+ // <button title="${util.out('Ok')}" class="input-ok classic-primary" style="width:100%;text-transform: uppercase;
84440
+ // font-size: 14px;">${util.out('Ok')}</button>
84441
+ // </div>
84442
+ // </div>
84443
+ // </div>`;
84444
+ // builderStuff.insertAdjacentHTML('beforeend', html);
84445
+
84446
+ // this.modalDisclaimer = builderStuff.querySelector('.ai-disclaimer');
84447
+
84619
84448
  let cl = contextBlockList;
84620
84449
  if (this.builder.contextList) cl = this.builder.contextList;
84621
84450
  const localProcess = question => {
@@ -91140,7 +90969,9 @@ class ContentBuilder {
91140
90969
  defaultFontSizes: [16, 17, 18, 19, 21, 24, 32, 35, 42, 48, 54, 64 /*, 76, 96, 120, 200, 300*/],
91141
90970
  fontSizeClassValues: [12, 14, 15, 16, 17, 18, 19, 21, 24, 28, 32, 35, 38, 42, 46, 48, 50, 54, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316, 320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380, 384, 388, 392, 396, 400],
91142
90971
  /* If not empty, applying font size will apply class: size-12, size-14, and so on. All responsive, defined in content.css */
91143
- gradientcolors: [['linear-gradient(0deg, rgb(255, 57, 25), rgb(249, 168, 37))'], ['linear-gradient(0deg, rgb(255, 57, 25), rgb(255, 104, 15))'], ['linear-gradient(0deg, #FF5722, #FF9800)'], ['linear-gradient(0deg, #613ca2, rgb(110, 123, 217))'], ['linear-gradient(0deg, rgb(65, 70, 206), rgb(236, 78, 130))'], ['linear-gradient(0deg, rgb(0, 150, 102), rgb(90, 103, 197))'], ['linear-gradient(30deg, rgb(249, 119, 148), rgb(98, 58, 162))'], ['linear-gradient(0deg, rgb(223, 70, 137), rgb(90, 103, 197))'], ['linear-gradient(0deg, rgb(40, 53, 147), rgb(90, 103, 197))'], ['linear-gradient(0deg, rgb(21, 101, 192), rgb(52, 169, 239))'], ['linear-gradient(0deg, rgb(32, 149, 219), rgb(139, 109, 230))'], ['linear-gradient(0deg, rgb(90, 103, 197), rgb(0, 184, 201))'], ['linear-gradient(0deg, rgb(0, 184, 201), rgb(253, 187, 45))'], ['linear-gradient(0deg, rgb(255, 208, 100), rgb(239, 98, 159))'], ['linear-gradient(0deg, rgb(0, 214, 223), rgb(130, 162, 253))'], ['linear-gradient(0deg, rgb(50, 234, 251), rgb(248, 247, 126))'], ['linear-gradient(0deg, rgb(141, 221, 255), rgb(255, 227, 255))'], ['linear-gradient(0deg, rgb(255, 170, 170), rgb(255, 255, 200))'], ['linear-gradient(0deg, rgb(239, 239, 239), rgb(252, 252, 252))']],
90972
+ gradientColors: [
90973
+ // 'linear-gradient(234deg, rgba(255, 253, 185, 1), rgb(255, 208, 100), rgb(239, 98, 159), rgb(73, 88, 195), rgba(2, 20, 145, 1))',
90974
+ 'linear-gradient(234deg, rgba(255, 253, 193, 1), rgba(255, 211, 111, 1), rgba(246, 108, 168, 1), rgba(97, 110, 204, 1), rgba(4, 98, 183, 1))', 'linear-gradient(15deg, rgba(222, 90, 69, 1), rgba(255, 118, 96, 1), rgba(249, 214, 137, 1), rgba(255, 242, 172, 1))', 'linear-gradient(357deg, rgba(68, 85, 204, 1), rgba(4, 166, 240, 1), rgba(51, 241, 255, 1))', 'linear-gradient(26deg, rgba(41, 145, 255, 1), rgba(49, 103, 240, 1), rgba(67, 107, 208, 1), rgba(149, 115, 255, 1), rgba(159, 159, 255, 1))', 'linear-gradient(0deg, rgba(198, 233, 155, 1), rgba(97, 221, 180, 1), rgba(244, 255, 190, 1))', 'linear-gradient(342deg, rgb(189, 156, 219), rgb(163, 172, 240), rgba(154, 203, 253, 1))', 'linear-gradient(45deg, rgb(255, 225, 172), rgb(253, 194, 141), rgba(246, 150, 183, 1), rgba(221, 140, 207, 1))', 'linear-gradient(0deg, rgba(157, 172, 246, 1), rgba(129, 205, 255, 1), rgba(202, 255, 207, 1))'],
91144
90975
  elementEditor: true,
91145
90976
  customval: '',
91146
90977
  moduleConfig: [],
@@ -92483,13 +92314,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
92483
92314
  }, this);
92484
92315
 
92485
92316
  // Gradient Picker
92486
- this.gradpicker = new GradientPicker({
92487
- gradientcolors: this.opts.gradientcolors,
92488
- colors: this.opts.colors,
92489
- animateModal: this.opts.animateModal,
92490
- elementToAnimate: this.opts.container,
92491
- lang: this.opts.lang
92492
- }, this);
92317
+ this.gradpicker = new GradientPicker(this);
92493
92318
 
92494
92319
  // Shortcut Info
92495
92320
  this.ShortcutInfo = new ShortcutInfo(this);