Ditty News Ticker - Version 3.0

Version Description

  • Ditty News Ticker posts have been moved to legacy code.
  • Completely new Ditty post type and functionality.
  • New Ditty Layout post type.
  • New Ditty Display post type.
  • New Settings page.
  • Added global Ditty rendering.
  • Added Layout and Display templates.
  • New extensions page for licenses and extension settings.
Download this release

Release Info

Developer metaphorcreations
Plugin Icon 128x128 Ditty News Ticker
Version 3.0
Comparing to
See all releases

Code changes from version 2.3.14 to 3.0

Files changed (98) hide show
  1. blocks/ditty-block/editor.scss +43 -0
  2. blocks/ditty-block/icon.js +14 -0
  3. blocks/ditty-block/index.js +150 -0
  4. blocks/ditty-block/index.php +36 -0
  5. blocks/ditty-block/style.scss +0 -0
  6. blocks/frontend.js +0 -0
  7. blocks/i18n.js +1 -0
  8. blocks/index.js +2 -0
  9. composer.json +8 -0
  10. ditty-news-ticker.php +62 -144
  11. inc/hooks.php +0 -11
  12. {eddsl → includes/admin}/EDD_SL_Plugin_Updater.php +0 -0
  13. includes/admin/columns.php +249 -0
  14. includes/admin/info.php +106 -0
  15. includes/admin/settings.php +410 -0
  16. includes/class-ditty-activator.php +72 -0
  17. includes/class-ditty-db-item-meta.php +215 -0
  18. includes/class-ditty-db-items.php +172 -0
  19. includes/class-ditty-db.php +248 -0
  20. includes/class-ditty-deactivator.php +26 -0
  21. includes/class-ditty-display-item.php +282 -0
  22. includes/class-ditty-display-type-list.php +287 -0
  23. includes/class-ditty-display-type-ticker.php +217 -0
  24. includes/class-ditty-display-type.php +574 -0
  25. includes/class-ditty-display.php +289 -0
  26. includes/class-ditty-displays.php +913 -0
  27. includes/class-ditty-editor.php +75 -0
  28. includes/class-ditty-errors.php +45 -0
  29. includes/class-ditty-extensions.php +642 -0
  30. includes/class-ditty-i18n.php +47 -0
  31. includes/class-ditty-item-type-default.php +124 -0
  32. includes/class-ditty-item-type-posts-lite.php +119 -0
  33. includes/class-ditty-item-type-wp-editor.php +68 -0
  34. includes/class-ditty-item-type.php +238 -0
  35. includes/class-ditty-item.php +456 -0
  36. includes/class-ditty-items.php +486 -0
  37. includes/class-ditty-layout.php +444 -0
  38. includes/class-ditty-layouts.php +1039 -0
  39. includes/class-ditty-loader.php +129 -0
  40. includes/class-ditty-roles.php +133 -0
  41. includes/class-ditty-singles.php +718 -0
  42. includes/class-ditty.php +630 -0
  43. includes/css/blocks.editor-min.css +3 -0
  44. includes/css/blocks.editor.css +1 -0
  45. includes/css/blocks.style.css +0 -0
  46. includes/css/ditty-admin.css +1622 -0
  47. includes/css/ditty.css +1124 -0
  48. includes/fields/ditty-field-button.php +74 -0
  49. includes/fields/ditty-field-checkbox.php +47 -0
  50. includes/fields/ditty-field-checkboxes.php +54 -0
  51. includes/fields/ditty-field-code.php +60 -0
  52. includes/fields/ditty-field-color.php +28 -0
  53. includes/fields/ditty-field-date.php +58 -0
  54. includes/fields/ditty-field-divider.php +91 -0
  55. includes/fields/ditty-field-group.php +90 -0
  56. includes/fields/ditty-field-html.php +26 -0
  57. includes/fields/ditty-field-image.php +60 -0
  58. includes/fields/ditty-field-number.php +42 -0
  59. includes/fields/ditty-field-radio.php +84 -0
  60. includes/fields/ditty-field-radius.php +59 -0
  61. includes/fields/ditty-field-select.php +109 -0
  62. includes/fields/ditty-field-slider.php +56 -0
  63. includes/fields/ditty-field-spacing.php +60 -0
  64. includes/fields/ditty-field-text.php +14 -0
  65. includes/fields/ditty-field-textarea.php +43 -0
  66. includes/fields/ditty-field-wysiwyg.php +40 -0
  67. includes/fields/ditty-field.php +313 -0
  68. includes/fields/helpers.php +182 -0
  69. includes/fields/js/ditty-fields.js +12 -0
  70. includes/fields/js/ditty-fields.min.js +563 -0
  71. includes/fields/js/fields/clone.js +160 -0
  72. includes/fields/js/fields/code.js +38 -0
  73. includes/fields/js/fields/color.js +25 -0
  74. includes/fields/js/fields/date.js +24 -0
  75. includes/fields/js/fields/group.js +50 -0
  76. includes/fields/js/fields/image.js +88 -0
  77. includes/fields/js/fields/slider.js +22 -0
  78. includes/fields/js/fields/wysiwyg.js +136 -0
  79. includes/helpers.php +1442 -0
  80. includes/hooks.php +136 -0
  81. includes/img/d.svg +1 -0
  82. includes/img/ditty-logo-black.png +0 -0
  83. includes/index.php +1 -0
  84. includes/js/admin/class-ditty-extension.js +298 -0
  85. includes/js/admin/class-ditty-settings.js +453 -0
  86. includes/js/admin/ditty-displays.js +41 -0
  87. includes/js/admin/ditty-extensions.js +68 -0
  88. includes/js/class-ditty-display-list.js +862 -0
  89. includes/js/class-ditty-display-list.min.js +862 -0
  90. includes/js/class-ditty-display-ticker.js +1352 -0
  91. includes/js/class-ditty-display-ticker.min.js +1 -0
  92. includes/js/class-ditty-slider.js +1424 -0
  93. includes/js/class-ditty-slider.min.js +1 -0
  94. includes/js/ditty-admin.js +22 -0
  95. includes/js/ditty-admin.min.js +888 -0
  96. includes/js/ditty-editor.js +185 -0
  97. includes/js/ditty-editor.min.js +5784 -0
  98. includes/js/ditty-editor.min.min.js +6 -0
blocks/ditty-block/editor.scss ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $ditty_primary: #39b44a;
2
+ .ditty-logo--white,
3
+ .ditty-icon--white {
4
+ fill: #FFF !important;
5
+ }
6
+ .ditty-logo--green,
7
+ .ditty-icon--green {
8
+ fill: $ditty_primary !important;
9
+ }
10
+ .wp-block-metaphorcreations-ditty-block {
11
+ background: rgba( 255, 255, 255, .8 );
12
+ border: 2px solid $ditty_primary;
13
+ padding: 20px;
14
+ &__info {
15
+ display: flex;
16
+ flex-direction: row;
17
+ align-items: center;
18
+ justify-content: flex-start;
19
+ }
20
+ &__vals {
21
+ font-size: 14px;
22
+ color: #FFF;
23
+ background: $ditty_primary;
24
+ border-radius: 3px;
25
+ padding: 5px 10px;
26
+ margin-right: 5px;
27
+ }
28
+ &__controls {
29
+ margin-top: 15px;
30
+ label {
31
+ width: 60px;
32
+ font-weight: bold;
33
+ }
34
+ }
35
+ select {
36
+ padding-top: 0 !important;
37
+ padding-bottom: 0 !important;
38
+ }
39
+ svg {
40
+ max-height: 60px;
41
+ margin-right: 10px;
42
+ }
43
+ }
blocks/ditty-block/icon.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const icons = {}
2
+ icons.iconBlack = <svg class="ditty-logo ditty-icon--black" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69.8 71.1"><path d="M0 46.4c0-17.2 8.6-29.1 24.6-29.1a19.93 19.93 0 0 1 6.6 1V0H45v59.2l1 10.3H34.2l-.9-5.2h-.5a15.21 15.21 0 0 1-13 6.8C3.8 71.1 0 58.4 0 46.4Zm31.2 7.4V28.6a13.7 13.7 0 0 0-6-1.3c-8.7 0-11.3 8.7-11.3 17.8 0 8.5 1.9 15.8 8.9 15.8 5.1 0 8.4-3.8 8.4-7.1ZM54.7 63.7a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4Z"/></svg>;
3
+
4
+ icons.iconWhite= <svg class="ditty-logo ditty-icon--white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69.8 71.1"><path d="M0 46.4c0-17.2 8.6-29.1 24.6-29.1a19.93 19.93 0 0 1 6.6 1V0H45v59.2l1 10.3H34.2l-.9-5.2h-.5a15.21 15.21 0 0 1-13 6.8C3.8 71.1 0 58.4 0 46.4Zm31.2 7.4V28.6a13.7 13.7 0 0 0-6-1.3c-8.7 0-11.3 8.7-11.3 17.8 0 8.5 1.9 15.8 8.9 15.8 5.1 0 8.4-3.8 8.4-7.1ZM54.7 63.7a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4Z"/></svg>;
5
+
6
+ icons.iconGreen = <svg class="ditty-logo ditty-icon--green" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69.8 71.1"><path d="M0 46.4c0-17.2 8.6-29.1 24.6-29.1a19.93 19.93 0 0 1 6.6 1V0H45v59.2l1 10.3H34.2l-.9-5.2h-.5a15.21 15.21 0 0 1-13 6.8C3.8 71.1 0 58.4 0 46.4Zm31.2 7.4V28.6a13.7 13.7 0 0 0-6-1.3c-8.7 0-11.3 8.7-11.3 17.8 0 8.5 1.9 15.8 8.9 15.8 5.1 0 8.4-3.8 8.4-7.1ZM54.7 63.7a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4Z"/></svg>;
7
+
8
+ icons.logoBlack = <svg class="ditty-logo ditty-logo--black" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 258.8 99.21"><path d="M0 49.5c0-17.2 8.6-29.1 24.6-29.1a19.93 19.93 0 0 1 6.6 1V3.1H45v59.2l1 10.3H34.2l-.9-5.2h-.5a15.21 15.21 0 0 1-13 6.8C3.8 74.2 0 61.5 0 49.5Zm31.2 7.4V31.7a13.7 13.7 0 0 0-6-1.3c-8.7 0-11.3 8.7-11.3 17.8 0 8.5 1.9 15.8 8.9 15.8 5.1 0 8.4-3.8 8.4-7.1ZM55.7 7.4A7.33 7.33 0 0 1 63.4 0c4.6 0 7.8 3.3 7.8 7.4s-3.2 7.4-7.8 7.4-7.7-3.1-7.7-7.4Zm14.8 14.5v50.7H56.4V21.9ZM95.8 3.1v18.8H112V3.1h14.1v18.8h13v10.9h-13v23.1c0 5.9 2.6 7.6 6.4 7.6a11.9 11.9 0 0 0 6.1-1.9l3.2 9c-3 2-8.2 3.5-13.3 3.5-15.2 0-16.5-8.7-16.5-17.8V32.8H95.8v23.1c0 5.9 2 7.6 5.7 7.6a11.64 11.64 0 0 0 5.7-1.6l2.1 9.4c-2.6 1.7-7.4 2.8-11.1 2.8-15.1 0-16.4-8.7-16.4-17.8V3.1ZM149.6 85.81c0-7.21 4.4-12.81 10.3-17.11-8.4-1.3-13-5.9-13-16V21.9h14v29.7c0 5.4.5 9.1 7 9.1 4 0 7.7-3.2 7.7-8.3V21.9h14v42.3a108.13 108.13 0 0 1-.9 13.9c-1.5 13.5-8.9 21.11-22.4 21.11-11.1 0-16.7-5.21-16.7-13.4Zm26.3-9.11v-9.5c-7.4 3.5-14 8.5-14 16.11 0 3.9 2.2 5.79 6 5.79 5.9 0 8-4.7 8-12.4ZM198.7 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4ZM221.2 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4ZM243.7 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4Z"/></svg>;
9
+
10
+ icons.logoWhite = <svg class="ditty-logo ditty-logo--white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 258.8 99.21"><path d="M0 49.5c0-17.2 8.6-29.1 24.6-29.1a19.93 19.93 0 0 1 6.6 1V3.1H45v59.2l1 10.3H34.2l-.9-5.2h-.5a15.21 15.21 0 0 1-13 6.8C3.8 74.2 0 61.5 0 49.5Zm31.2 7.4V31.7a13.7 13.7 0 0 0-6-1.3c-8.7 0-11.3 8.7-11.3 17.8 0 8.5 1.9 15.8 8.9 15.8 5.1 0 8.4-3.8 8.4-7.1ZM55.7 7.4A7.33 7.33 0 0 1 63.4 0c4.6 0 7.8 3.3 7.8 7.4s-3.2 7.4-7.8 7.4-7.7-3.1-7.7-7.4Zm14.8 14.5v50.7H56.4V21.9ZM95.8 3.1v18.8H112V3.1h14.1v18.8h13v10.9h-13v23.1c0 5.9 2.6 7.6 6.4 7.6a11.9 11.9 0 0 0 6.1-1.9l3.2 9c-3 2-8.2 3.5-13.3 3.5-15.2 0-16.5-8.7-16.5-17.8V32.8H95.8v23.1c0 5.9 2 7.6 5.7 7.6a11.64 11.64 0 0 0 5.7-1.6l2.1 9.4c-2.6 1.7-7.4 2.8-11.1 2.8-15.1 0-16.4-8.7-16.4-17.8V3.1ZM149.6 85.81c0-7.21 4.4-12.81 10.3-17.11-8.4-1.3-13-5.9-13-16V21.9h14v29.7c0 5.4.5 9.1 7 9.1 4 0 7.7-3.2 7.7-8.3V21.9h14v42.3a108.13 108.13 0 0 1-.9 13.9c-1.5 13.5-8.9 21.11-22.4 21.11-11.1 0-16.7-5.21-16.7-13.4Zm26.3-9.11v-9.5c-7.4 3.5-14 8.5-14 16.11 0 3.9 2.2 5.79 6 5.79 5.9 0 8-4.7 8-12.4ZM198.7 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4ZM221.2 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4ZM243.7 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4Z"/></svg>;
11
+
12
+ icons.logoGreen = <svg class="ditty-logo ditty-logo--green" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 258.8 99.21"><path d="M0 49.5c0-17.2 8.6-29.1 24.6-29.1a19.93 19.93 0 0 1 6.6 1V3.1H45v59.2l1 10.3H34.2l-.9-5.2h-.5a15.21 15.21 0 0 1-13 6.8C3.8 74.2 0 61.5 0 49.5Zm31.2 7.4V31.7a13.7 13.7 0 0 0-6-1.3c-8.7 0-11.3 8.7-11.3 17.8 0 8.5 1.9 15.8 8.9 15.8 5.1 0 8.4-3.8 8.4-7.1ZM55.7 7.4A7.33 7.33 0 0 1 63.4 0c4.6 0 7.8 3.3 7.8 7.4s-3.2 7.4-7.8 7.4-7.7-3.1-7.7-7.4Zm14.8 14.5v50.7H56.4V21.9ZM95.8 3.1v18.8H112V3.1h14.1v18.8h13v10.9h-13v23.1c0 5.9 2.6 7.6 6.4 7.6a11.9 11.9 0 0 0 6.1-1.9l3.2 9c-3 2-8.2 3.5-13.3 3.5-15.2 0-16.5-8.7-16.5-17.8V32.8H95.8v23.1c0 5.9 2 7.6 5.7 7.6a11.64 11.64 0 0 0 5.7-1.6l2.1 9.4c-2.6 1.7-7.4 2.8-11.1 2.8-15.1 0-16.4-8.7-16.4-17.8V3.1ZM149.6 85.81c0-7.21 4.4-12.81 10.3-17.11-8.4-1.3-13-5.9-13-16V21.9h14v29.7c0 5.4.5 9.1 7 9.1 4 0 7.7-3.2 7.7-8.3V21.9h14v42.3a108.13 108.13 0 0 1-.9 13.9c-1.5 13.5-8.9 21.11-22.4 21.11-11.1 0-16.7-5.21-16.7-13.4Zm26.3-9.11v-9.5c-7.4 3.5-14 8.5-14 16.11 0 3.9 2.2 5.79 6 5.79 5.9 0 8-4.7 8-12.4ZM198.7 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4ZM221.2 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4ZM243.7 66.8a7 7 0 0 1 7.4-7.2c5 0 7.7 2.8 7.7 7.1s-2.6 7.5-7.4 7.5c-5.1 0-7.7-3.1-7.7-7.4Z"/></svg>;
13
+
14
+ export default icons;
blocks/ditty-block/index.js ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Block dependencies
3
+ */
4
+ import icons from './icon';
5
+ import './style.scss';
6
+ import './editor.scss';
7
+
8
+ /**
9
+ * Internal block libraries
10
+ */
11
+ const { __, sprintf } = wp.i18n;
12
+ const { registerBlockType } = wp.blocks;
13
+ const { InspectorControls } = wp.blockEditor;
14
+ const { Fragment } = wp.element;
15
+ const { PanelBody, PanelRow, SelectControl, Spinner } = wp.components;
16
+ const { withSelect } = wp.data;
17
+
18
+ /**
19
+ * Register block
20
+ */
21
+ export default registerBlockType(
22
+ 'metaphorcreations/ditty-block',
23
+ {
24
+ title: __( 'Ditty', 'ditty-news-ticker' ),
25
+ description: __( 'Display your Ditty within the content of the post.', 'ditty-news-ticker' ),
26
+ category: 'widgets',
27
+ icon: {
28
+ //background: '#39b44a',
29
+ src: icons.iconGreen,
30
+ },
31
+ keywords: [
32
+ __( 'Ticker', 'ditty-news-ticker' ),
33
+ __( 'Display', 'ditty-news-ticker' ),
34
+ __( 'Content', 'ditty-news-ticker' ),
35
+ ],
36
+ supports: {
37
+ html: false,
38
+ },
39
+ attributes: {
40
+ ditty: {
41
+ type: 'string',
42
+ },
43
+ display: {
44
+ type: 'string',
45
+ }
46
+ },
47
+ edit: withSelect( select => {
48
+ const { getEntityRecords } = select( 'core' );
49
+ return {
50
+ dittys: getEntityRecords( 'postType', 'ditty-news-ticker', { per_page: -1 } ),
51
+ };
52
+ } )( ( { attributes: { ditty, display }, dittys, className, isSelected, setAttributes } ) => {
53
+
54
+ let ditty_posts = null;
55
+ if ( dittys ) {
56
+ ditty_posts = dittys.map( ditty_post => {
57
+ return ( { key: ditty_post.id, value: ditty_post.id, label: ditty_post.title.raw } );
58
+ } );
59
+ ditty_posts.unshift( { key: 'selectDittyTicker', value: '', label: __( 'Select a Ticker', 'ditty-news-ticker' ) } );
60
+ }
61
+
62
+ const display_posts = dittyBlocksEditorVars.displays.map( data => {
63
+ const value = data.type_id + '--' + data.display_id;
64
+ const label = data.display_label + ' (' + data.type_label + ')';
65
+ return ( { key: value, value: value, label: label } );
66
+ } );
67
+ display_posts.unshift( { key: 'useDefaultDisplay', value: '', label: __( 'Use Default Display', 'ditty-news-ticker' ) } );
68
+
69
+ let currentDisplay = '';
70
+ if ( display ) {
71
+ for ( let i = 0; i < display_posts.length; i++ ) {
72
+ if ( display === display_posts[i].value ) {
73
+ currentDisplay = display_posts[i].label;
74
+ }
75
+ }
76
+ }
77
+ if ( '' === currentDisplay ) {
78
+ currentDisplay = 'Default Display';
79
+ }
80
+
81
+ return [
82
+ <InspectorControls key='dittySelectTicker'>
83
+ <PanelBody>
84
+ { ditty_posts
85
+ ?
86
+ <SelectControl
87
+ label={ __( 'Ditty', 'ditty-news-ticker' ) }
88
+ value={ ditty }
89
+ options={ ditty_posts }
90
+ onChange={ ditty => setAttributes( { ditty } ) }
91
+ />
92
+ :
93
+ <Fragment><Spinner />{ __( 'Loading Tickers', 'ditty-news-ticker' ) }</Fragment>
94
+ }
95
+ { display_posts
96
+ ?
97
+ <SelectControl
98
+ label={ __( 'Display', 'ditty-news-ticker' ) }
99
+ value={ display }
100
+ options={ display_posts }
101
+ onChange={ display => setAttributes( { display } ) }
102
+ />
103
+ :
104
+ <Fragment><Spinner />{ __( 'Loading Displays', 'ditty-news-ticker' ) }</Fragment>
105
+ }
106
+ </PanelBody>
107
+ </InspectorControls>,
108
+ <div key="dittyBlockViewTicker" className={ className }>
109
+ {
110
+ ( ! ditty || isSelected ) ?
111
+ <Fragment>
112
+ <div className="wp-block-metaphorcreations-ditty-block__info">
113
+ {icons.logoBlack}
114
+ <div className="wp-block-metaphorcreations-ditty-block__vals">{ __( 'ID:', 'ditty-news-ticker' ) } <strong>{ ditty }</strong></div>
115
+ <div className="wp-block-metaphorcreations-ditty-block__vals">{ __( 'Display:', 'ditty-news-ticker' ) } <strong>{ currentDisplay }</strong></div>
116
+ </div>
117
+ <div className="wp-block-metaphorcreations-ditty-block__controls">
118
+ <SelectControl
119
+ label={ __( 'ID:', 'ditty-news-ticker' ) }
120
+ labelPosition = 'side'
121
+ value={ ditty }
122
+ options={ ditty_posts }
123
+ onChange={ ditty => setAttributes( { ditty } ) }
124
+ />
125
+ <SelectControl
126
+ label={ __( 'Display:', 'ditty-news-ticker' ) }
127
+ labelPosition = 'side'
128
+ value={ display }
129
+ options={ display_posts }
130
+ onChange={ display => setAttributes( { display } ) }
131
+ />
132
+ </div>
133
+ </Fragment>
134
+ : (
135
+ <div className="wp-block-metaphorcreations-ditty-block__info">
136
+ {icons.logoBlack}
137
+ <div className="wp-block-metaphorcreations-ditty-block__vals">{ __( 'ID:', 'ditty-news-ticker' ) } <strong>{ ditty }</strong></div>
138
+ <div className="wp-block-metaphorcreations-ditty-block__vals">{ __( 'Display:', 'ditty-news-ticker' ) } <strong>{ currentDisplay }</strong></div>
139
+ </div>
140
+ )
141
+
142
+ }
143
+ </div>
144
+ ];
145
+ } ), // end edit
146
+ save: props => {
147
+ return null;
148
+ },
149
+ },
150
+ );
blocks/ditty-block/index.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Metaphor_Creations\Ditty\Blocks\Ditty_Block;
4
+
5
+ /**
6
+ * Register the dynamic block.
7
+ *
8
+ * @since 1.0
9
+ * @return void
10
+ */
11
+ function register_dynamic_block() {
12
+ if ( ! function_exists( 'register_block_type' ) ) {
13
+ return;
14
+ }
15
+
16
+ // Hook server side rendering into render callback
17
+ register_block_type( 'metaphorcreations/ditty-block', [
18
+ 'render_callback' => __NAMESPACE__ . '\render_dynamic_block',
19
+ ] );
20
+ }
21
+ add_action( 'plugins_loaded', __NAMESPACE__ . '\register_dynamic_block' );
22
+
23
+ /**
24
+ * Server rendering for /blocks/examples/12-dynamic
25
+ */
26
+ function render_dynamic_block( $atts ) {
27
+ if ( is_admin() ) {
28
+ return false;
29
+ }
30
+ $args = array(
31
+ 'id' => isset( $atts['ditty'] ) ? intval( $atts['ditty'] ) : false,
32
+ 'display' => isset( $atts['display'] ) ? sanitize_text_field( $atts['display'] ) : false,
33
+ 'class' => isset( $atts['className'] ) ? sanitize_text_field( $atts['className'] ) : false,
34
+ );
35
+ return ditty_render( $args );
36
+ }
blocks/ditty-block/style.scss ADDED
File without changes
blocks/frontend.js ADDED
File without changes
blocks/i18n.js ADDED
@@ -0,0 +1 @@
 
1
+ wp.i18n.setLocaleData( { '': {} }, 'ditty' );
blocks/index.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ import './i18n.js';
2
+ import './ditty-block';
composer.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "require": {
3
+ "padaliyajay/php-autoprefixer": "^1.2",
4
+ "composer/installers": "^1",
5
+ "thunderer/shortcode": "^0.7",
6
+ "scssphp/scssphp": "^1.8.1"
7
+ }
8
+ }
ditty-news-ticker.php CHANGED
@@ -1,162 +1,80 @@
1
  <?php
2
- /*
3
- Plugin Name: Ditty News Ticker
4
- Plugin URI: http://dittynewsticker.com/
5
- Description: Ditty News Ticker is a multi-functional data display plugin
6
- Text Domain: ditty-news-ticker
7
- Domain Path: languages
8
- Version: 2.3.14
9
- Author: Metaphor Creations
10
- Author URI: http://www.metaphorcreations.com
11
- Contributors: metaphorcreations
12
- License: GPL2
13
- */
14
-
15
-
16
- // Exit if accessed directly.
17
- if( ! defined( 'ABSPATH' ) ) exit;
18
-
19
- if( ! class_exists( 'Ditty_News_Ticker' ) ) :
20
-
21
 
22
  /**
23
- * Main Ditty_News_Ticker Class.
24
- * @since 3.0
 
 
 
 
 
 
 
 
25
  */
26
- final class Ditty_News_Ticker {
27
-
28
- /**
29
- * @var Ditty_News_Ticker The one true Ditty_News_Ticker
30
- * @since 3.0
31
- */
32
- private static $instance;
33
-
34
-
35
- /**
36
- * Main Ditty_News_Ticker Instance.
37
- * @since 1.0
38
- */
39
- public static function instance() {
40
-
41
- if( ! isset( self::$instance ) && ! ( self::$instance instanceof Ditty_News_Ticker ) ) {
42
-
43
- self::$instance = new Ditty_News_Ticker;
44
- self::$instance->setup_constants();
45
 
46
- add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
 
 
 
47
 
48
- self::$instance->includes();
49
- }
50
-
51
- do_action( 'dnt_init' );
52
 
53
- return self::$instance;
54
- }
55
-
56
-
57
- /**
58
- * Setup plugin constants.
59
- * @since 3.0
60
- */
61
- private function setup_constants() {
62
 
63
- // Plugin version
64
- if ( ! defined( 'MTPHR_DNT_VERSION' ) ) {
65
- define( 'MTPHR_DNT_VERSION', '2.3.14' );
66
- }
67
 
68
- // Plugin Folder Path
69
- if ( ! defined( 'MTPHR_DNT_DIR') ) {
70
- define( 'MTPHR_DNT_DIR', trailingslashit( plugin_dir_path( __FILE__ ) ) );
71
- }
72
 
73
- // Plugin Folder URL
74
- if ( ! defined( 'MTPHR_DNT_URL') ) {
75
- define( 'MTPHR_DNT_URL', trailingslashit( plugin_dir_url( __FILE__ ) ) );
76
- }
77
-
78
- // Plugin Root File
79
- if ( ! defined( 'MTPHR_DNT_FILE') ) {
80
- define( 'MTPHR_DNT_FILE', __FILE__ );
81
- }
82
-
83
- // Store URL
84
- if ( ! defined( 'MTPHR_DNT_STORE_URL') ) {
85
- define( 'MTPHR_DNT_STORE_URL', 'https://www.metaphorcreations.com' );
86
- }
87
- }
88
-
89
-
90
- /**
91
- * Include required files
92
- * @since 3.0
93
- */
94
- private function includes() {
95
-
96
- // Load the general functions
97
- require_once MTPHR_DNT_DIR . 'eddsl/eddsl.php';
98
- // if ( defined( 'WP_DEBUG' ) && true === WP_DEBUG ) {
99
- // require_once MTPHR_DNT_DIR . 'inc/ChromePhp.php';
100
- // }
101
 
102
- require_once MTPHR_DNT_DIR . 'inc/composer.php';
103
- require_once MTPHR_DNT_DIR . 'inc/helpers.php';
104
- require_once MTPHR_DNT_DIR . 'inc/hooks.php';
105
- require_once MTPHR_DNT_DIR . 'inc/post-types.php';
106
- require_once MTPHR_DNT_DIR . 'inc/settings.php';
107
- require_once MTPHR_DNT_DIR . 'inc/static.php';
108
- require_once MTPHR_DNT_DIR . 'inc/widget.php';
109
- require_once MTPHR_DNT_DIR . 'inc/functions.php';
110
-
111
- if( is_admin() ) {
112
-
113
- // Load admin specific code
114
- require_once MTPHR_DNT_DIR . 'inc/admin/ajax.php';
115
- require_once MTPHR_DNT_DIR . 'inc/admin/meta-boxes.php';
116
- require_once MTPHR_DNT_DIR . 'inc/admin/edit-columns.php';
117
- require_once MTPHR_DNT_DIR . 'inc/admin/fields/helpers.php';
118
- require_once MTPHR_DNT_DIR . 'inc/admin/fields/fields.php';
119
- require_once MTPHR_DNT_DIR . 'inc/admin/filters.php';
120
- require_once MTPHR_DNT_DIR . 'inc/admin/functions.php';
121
- require_once MTPHR_DNT_DIR . 'inc/admin/upgrades.php';
122
-
123
- } else {
124
-
125
- // Load front-end specific code
126
- require_once MTPHR_DNT_DIR . 'inc/filters.php';
127
- require_once MTPHR_DNT_DIR . 'inc/shortcodes.php';
128
- require_once MTPHR_DNT_DIR . 'inc/classes/class-mtphr-dnt.php';
129
- require_once MTPHR_DNT_DIR . 'inc/classes/class-mtphr-dnt-tick.php';
130
- require_once MTPHR_DNT_DIR . 'inc/classes/class-mtphr-dnt-image.php';
131
- require_once MTPHR_DNT_DIR . 'inc/classes/helpers/class-mtphr-dnt-string-replacement.php';
132
- require_once MTPHR_DNT_DIR . 'inc/templates.php';
133
- }
134
-
135
- require_once MTPHR_DNT_DIR . 'inc/classes/class-mtphr-dnt-roles.php';
136
- require_once MTPHR_DNT_DIR . 'inc/install.php';
137
- }
138
-
139
-
140
- /**
141
- * Loads the plugin language files.
142
- * @since 3.0
143
- */
144
- public function load_textdomain() {
145
-
146
- load_plugin_textdomain( 'ditty-news-ticker', false, 'ditty-news-ticker/languages/' );
147
- }
148
  }
149
 
150
- endif; // End if class_exists check.
 
151
 
 
 
 
 
 
152
 
153
  /**
154
- * The main function for that returns Ditty_News_Ticker
155
- * @since 3.0
 
 
 
 
 
156
  */
157
- function DNT() {
158
- return Ditty_News_Ticker::instance();
159
  }
160
-
161
- // Get Ditty News Ticker Running
162
- DNT();
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  /**
4
+ * Plugin Name: Ditty (formerly Ditty News Ticker)
5
+ * Plugin URI: https://www.metaphorcreations.com/ditty
6
+ * Description: Formerly Ditty News Ticker. Ditty is a multi-functional data display plugin.
7
+ * Version: 3.0
8
+ * Author: Metaphor Creations
9
+ * Author URI: https://www.metaphorcreations.com
10
+ * License: GPL-2.0+
11
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
12
+ * Text Domain: ditty-news-ticker
13
+ * Domain Path: /languages
14
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ // If this file is called directly, abort.
17
+ if ( ! defined( 'WPINC' ) ) {
18
+ die;
19
+ }
20
 
21
+ // Plugin version.
22
+ if ( ! defined( 'DITTY_VERSION' ) ) {
23
+ define( 'DITTY_VERSION', '3.0' );
24
+ }
25
 
26
+ // Plugin Folder Path.
27
+ if ( ! defined( 'DITTY_DIR' ) ) {
28
+ define( 'DITTY_DIR', plugin_dir_path( __FILE__ ) );
29
+ }
 
 
 
 
 
30
 
31
+ // Plugin Folder URL.
32
+ if ( ! defined( 'DITTY_URL' ) ) {
33
+ define( 'DITTY_URL', plugin_dir_url( __FILE__ ) );
34
+ }
35
 
36
+ // Plugin Root File.
37
+ if ( ! defined( 'DITTY_FILE' ) ) {
38
+ define( 'DITTY_FILE', __FILE__ );
39
+ }
40
 
41
+ /**
42
+ * The code that runs during plugin activation.
43
+ * This action is documented in includes/class-ditty-activator.php
44
+ */
45
+ function ditty_activate() {
46
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-ditty-activator.php';
47
+ Ditty_Activator::activate();
48
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ /**
51
+ * The code that runs during plugin deactivation.
52
+ * This action is documented in includes/class-ditty-deactivator.php
53
+ */
54
+ function ditty_deactivate() {
55
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-ditty-deactivator.php';
56
+ Ditty_Deactivator::deactivate();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
 
59
+ register_activation_hook( __FILE__, 'ditty_activate' );
60
+ register_deactivation_hook( __FILE__, 'ditty_deactivate' );
61
 
62
+ /**
63
+ * The core plugin class that is used to define internationalization,
64
+ * admin-specific hooks, and public-facing site hooks.
65
+ */
66
+ require plugin_dir_path( __FILE__ ) . 'includes/class-ditty.php';
67
 
68
  /**
69
+ * Begins execution of the plugin.
70
+ *
71
+ * Since everything within the plugin is registered via hooks,
72
+ * then kicking off the plugin from this point in the file does
73
+ * not affect the page life cycle.
74
+ *
75
+ * @since 1.0
76
  */
77
+ function Ditty() {
78
+ return Ditty::instance();
79
  }
80
+ Ditty();
 
 
inc/hooks.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Add a custom Unyson extension location - 2.2
5
- * @since 2.2
6
- */
7
- function mtphr_dnt_unyson_extension( $locations ) {
8
- $locations[MTPHR_DNT_DIR.'inc/builders/unyson'] = plugins_url('ditty-news-ticker/inc/builders/unyson');
9
- return $locations;
10
- }
11
- add_filter( 'fw_extensions_locations', 'mtphr_dnt_unyson_extension' );
 
 
 
 
 
 
 
 
 
 
 
{eddsl → includes/admin}/EDD_SL_Plugin_Updater.php RENAMED
File without changes
includes/admin/columns.php ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Set custom edit screen columns
5
+ *
6
+ * @since 3.0
7
+ * @var array $new_columns
8
+ */
9
+ function ditty_manage_posts_columns( $columns, $post_type ){
10
+ $new_columns = array();
11
+ foreach( $columns as $key => $value ) {
12
+ $new_columns[$key] = $value;
13
+ if( 'title' === $key ) {
14
+ switch( $post_type ) {
15
+ case 'ditty_display':
16
+ $new_columns['ditty_display_version'] = __( 'Version', 'ditty-news-ticker' );
17
+ $new_columns['ditty_display_type'] = __( 'Display Type', 'ditty-news-ticker' );
18
+ break;
19
+ case 'ditty_layout':
20
+ $new_columns['ditty_layout_version'] = __( 'Version', 'ditty-news-ticker' );
21
+ //$new_columns['ditty_layout_template'] = __( 'Layout Template', 'ditty-news-ticker' );
22
+ break;
23
+ case 'ditty':
24
+ $new_columns['ditty_display'] = __( 'Display', 'ditty-news-ticker' );
25
+ $new_columns['ditty_display_type'] = __( 'Display Type', 'ditty-news-ticker' );
26
+ break;
27
+ }
28
+
29
+ }
30
+ }
31
+ return $new_columns;
32
+ }
33
+ add_filter( 'manage_posts_columns', 'ditty_manage_posts_columns', 10, 2 );
34
+
35
+ /**
36
+ * Display the custom edit screen columns
37
+ *
38
+ * @since 3.0
39
+ */
40
+ function ditty_manage_posts_custom_column( $column, $post_id ){
41
+ global $post;
42
+
43
+ // if ( 'ditty' === $post->post_type ) {
44
+ // $display_meta = get_post_meta( $post_id, '_ditty_display', true );
45
+ // $display_obj = new Ditty_Display( $display_meta );
46
+ // $display_name = $display->get_label();
47
+ // $display_type = $display->get_label();
48
+ // }
49
+
50
+ switch ( $column ) {
51
+ case 'ditty_display_type':
52
+ if ( 'ditty_display' === $post->post_type ) {
53
+ $display_type = get_post_meta( $post_id, '_ditty_display_type', true );
54
+ } elseif ( 'ditty' === $post->post_type ) {
55
+ $display_id = get_post_meta( $post_id, '_ditty_display', true );
56
+ $display = new Ditty_Display( $display_id );
57
+ $display_type = $display->get_display_type();
58
+ }
59
+ $label = $display_type;
60
+ $display_types = ditty_display_types();
61
+ foreach( $display_types as $slug => $display ) {
62
+ if( $display_type === $slug ) {
63
+ $label = $display['label'];
64
+ }
65
+ }
66
+ echo "<a href='edit.php?post_type={$post->post_type}&ditty_display_type={$display_type}'>".$label."</a>";
67
+ break;
68
+ case 'ditty_layout_template':
69
+ $meta = get_post_meta( $post_id, '_ditty_layout_template', true );
70
+ echo $meta;
71
+ break;
72
+ case 'ditty_layout_version':
73
+ $meta = get_post_meta( $post_id, '_ditty_layout_version', true );
74
+ $label = $meta;
75
+ echo $label;
76
+ break;
77
+ case 'ditty_display':
78
+ $display_id = get_post_meta( $post_id, '_ditty_display', true );
79
+ $display = new Ditty_Display( $display_id );
80
+ $label = $display->get_label();
81
+ echo "<a href='edit.php?post_type={$post->post_type}&ditty_display={$display_id}'>".$label."</a> - <a href='" . get_edit_post_link( $display->get_display_id() ) . "'>" . __( 'Edit', 'ditty-news-ticker' ) . "</a>";
82
+ //echo "{$label} - <a href='" . get_edit_post_link( $display->get_display_id() ) . "'>" . __( 'Edit', 'ditty-news-ticker' ) . "</a>";
83
+ //echo $label;
84
+ break;
85
+ case 'ditty_display_version':
86
+ $meta = get_post_meta( $post_id, '_ditty_display_version', true );
87
+ $label = $meta;
88
+ echo $label;
89
+ break;
90
+ default:
91
+ break;
92
+ }
93
+ }
94
+ add_action( 'manage_posts_custom_column', 'ditty_manage_posts_custom_column', 10, 2 );
95
+
96
+ /**
97
+ * Add sortable columns
98
+ *
99
+ * @since 3.0
100
+ * @var array $new_columns
101
+ */
102
+ function ditty_display_sortable_columns( $columns ) {
103
+ $columns['ditty_display_type'] = 'ditty_display_type';
104
+ $columns['ditty_display_version'] = 'ditty_display_version';
105
+ return $columns;
106
+ }
107
+ add_filter( 'manage_edit-ditty_display_sortable_columns', 'ditty_display_sortable_columns' );
108
+
109
+ function ditty_layout_sortable_columns( $columns ) {
110
+ $columns['ditty_layout_template'] = 'ditty_layout_template';
111
+ $columns['ditty_layout_version'] = 'ditty_layout_version';
112
+ return $columns;
113
+ }
114
+ add_filter( 'manage_edit-ditty_layout_sortable_columns', 'ditty_layout_sortable_columns' );
115
+
116
+ function ditty_sortable_columns( $columns ) {
117
+ $columns['ditty_display'] = 'ditty_display';
118
+ $columns['ditty_display_type'] = 'ditty_display_type';
119
+ return $columns;
120
+ }
121
+ add_filter( 'manage_edit-ditty_sortable_columns', 'ditty_sortable_columns' );
122
+
123
+ /**
124
+ * Set the custom column order
125
+ *
126
+ * @since 3.0
127
+ * @var array $vars
128
+ */
129
+ function ditty_column_order_request( $vars ) {
130
+ if ( isset( $vars['orderby'] ) && 'ditty_display_type' === $vars['orderby'] ) {
131
+ $vars = array_merge( $vars, array(
132
+ 'meta_key' => '_ditty_display_type',
133
+ 'orderby' => 'meta_value',
134
+ ) );
135
+ } elseif ( isset( $vars['orderby'] ) && 'ditty_layout_template' === $vars['orderby'] ) {
136
+ $vars = array_merge( $vars, array(
137
+ 'meta_key' => '_ditty_layout_template',
138
+ 'orderby' => 'meta_value',
139
+ ) );
140
+ } elseif ( isset( $vars['orderby'] ) && 'ditty_layout_version' === $vars['orderby'] ) {
141
+ $vars = array_merge( $vars, array(
142
+ 'meta_key' => '_ditty_layout_version',
143
+ 'orderby' => 'meta_value',
144
+ ) );
145
+ } elseif ( isset( $vars['orderby'] ) && 'ditty_display_version' === $vars['orderby'] ) {
146
+ $vars = array_merge( $vars, array(
147
+ 'meta_key' => '_ditty_display_version',
148
+ 'orderby' => 'meta_value',
149
+ ) );
150
+ } elseif ( isset( $vars['orderby'] ) && 'ditty_display' === $vars['orderby'] ) {
151
+ $vars = array_merge( $vars, array(
152
+ 'meta_key' => '_ditty_display',
153
+ 'orderby' => 'meta_value',
154
+ ) );
155
+ }
156
+
157
+ return $vars;
158
+ }
159
+ add_filter( 'request', 'ditty_column_order_request' );
160
+
161
+ /**
162
+ * Add custom edit screen filters
163
+ *
164
+ * @since 3.0
165
+ */
166
+ function ditty_display_admin_screen_filters() {
167
+ global $typenow;
168
+
169
+ if( $typenow == 'ditty_display' || $typenow == 'ditty' ) {
170
+ $display_type = isset( $_GET['ditty_display_type'] ) ? esc_html( $_GET['ditty_display_type'] ) : '';
171
+ $display_types = ditty_display_types();
172
+ echo '<select name="ditty_display_type">';
173
+ echo '<option value="">' . __( 'Show all Types', 'ditty-news-ticker' ) . '</option>';
174
+ if( is_array( $display_types ) && count( $display_types ) > 0 ) {
175
+ foreach( $display_types as $slug => $display ) {
176
+ echo '<option value="' . $slug . '" '.selected( $slug, $display_type, false ) . '>' . $display['label'] . '</option>';
177
+ }
178
+ }
179
+ echo '</select>';
180
+
181
+ } elseif( $typenow == 'ditty_layout' ) {
182
+ $layout_template = isset( $_GET['ditty_layout_template'] ) ? esc_html( $_GET['ditty_layout_template'] ) : '';
183
+ $layout_templates = ditty_layout_templates();
184
+ echo '<select name="ditty_layout_template">';
185
+ echo '<option value="">' . __( 'Show all Templates', 'ditty-news-ticker' ) . '</option>';
186
+ if( is_array( $layout_templates ) && count( $layout_templates ) > 0 ) {
187
+ foreach( $layout_templates as $template_slug => $template_data ) {
188
+ echo '<option value="' . $template_slug . '" '.selected( $template_slug, $layout_template, false ) . '>' . $template_data['label'] . '</option>';
189
+ }
190
+ }
191
+ echo '</select>';
192
+ }
193
+ }
194
+ add_action( 'restrict_manage_posts', 'ditty_display_admin_screen_filters' );
195
+
196
+ /**
197
+ * Filter the Ditty posts
198
+ *
199
+ * @since 3.0
200
+ * @var array $qv
201
+ */
202
+ function ditty_edit_parse_query( $query ) {
203
+ global $pagenow;
204
+ $qv = &$query->query_vars;
205
+
206
+ if ( $pagenow=='edit.php' && isset( $qv['post_type'] ) && 'ditty_display' == $qv['post_type'] ) {
207
+ $meta_query = array();
208
+ if( isset( $_GET['ditty_display_type'] ) && $_GET['ditty_display_type'] != '' ) {
209
+ $meta_query[] = array(
210
+ 'key' => '_ditty_display_type',
211
+ 'value' => esc_html( $_GET['ditty_display_type'] ),
212
+ );
213
+ }
214
+ if( count( $meta_query ) > 0 ) {
215
+ $qv['meta_query'] = $meta_query;
216
+ }
217
+
218
+ } elseif ( $pagenow=='edit.php' && isset( $qv['post_type'] ) && 'ditty_layout' == $qv['post_type'] ) {
219
+ $meta_query = array();
220
+ if( isset( $_GET['ditty_layout_template'] ) && $_GET['ditty_layout_template'] != '' ) {
221
+ $meta_query[] = array(
222
+ 'key' => 'ditty_layout_template',
223
+ 'value' => esc_html( $_GET['ditty_layout_template'] ),
224
+ );
225
+ }
226
+ if( count( $meta_query ) > 0 ) {
227
+ $qv['meta_query'] = $meta_query;
228
+ }
229
+ } elseif ( $pagenow=='edit.php' && isset( $qv['post_type'] ) && 'ditty' == $qv['post_type'] ) {
230
+ $meta_query = array();
231
+ if( isset( $_GET['ditty_display'] ) && $_GET['ditty_display'] != '' ) {
232
+ $meta_query[] = array(
233
+ 'key' => '_ditty_display',
234
+ 'value' => esc_html( $_GET['ditty_display'] ),
235
+ );
236
+ }
237
+ if( isset( $_GET['ditty_display_type'] ) && $_GET['ditty_display_type'] != '' ) {
238
+ $meta_query[] = array(
239
+ 'key' => '_ditty_display',
240
+ 'value' => esc_html( $_GET['ditty_display_type'] . '--' ),
241
+ 'compare' => 'LIKE'
242
+ );
243
+ }
244
+ if( count( $meta_query ) > 0 ) {
245
+ $qv['meta_query'] = $meta_query;
246
+ }
247
+ }
248
+ }
249
+ add_filter( 'parse_query', 'ditty_edit_parse_query' );
includes/admin/info.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Register settings pages
5
+ *
6
+ * @since 3.0
7
+ */
8
+ function ditty_info_page() {
9
+ add_submenu_page(
10
+ '', // The ID of the top-level menu page to which this submenu item belongs
11
+ __( 'Ditty Info', 'ditty-news-ticker' ), // The value used to populate the browser's title bar when the menu page is active
12
+ __( 'Upgrade Details', 'ditty-news-ticker' ), // The label of this submenu item displayed in the menu
13
+ 'manage_ditty_settings', // What roles are able to access this submenu item
14
+ 'ditty_info', // The ID used to represent this submenu item
15
+ 'ditty_info_display' // The callback function used to render the options for this submenu item
16
+ );
17
+ }
18
+ add_action( 'admin_menu', 'ditty_info_page', 9 );
19
+
20
+ function ditty_info_display() {
21
+ ?>
22
+ <div id="ditty-page" class="wrap">
23
+
24
+ <div id="ditty-page__header">
25
+ <div id="ditty-page__version"><?php printf( __( 'Ditty v%s', 'ditty-news-ticker' ), ditty_version() ); ?></div>
26
+ <h1 id="ditty-page__logo" style="text-align:center;"><img id="ditty-page__logo__image" src="<?php echo DITTY_URL; ?>includes/img/ditty-logo-black.png" alt="<?php _e( 'Ditty', 'ditty-news-ticker' ); ?>" style="margin-left:auto;margin-right:auto;" /></h1>
27
+ <h3 style="text-align:center;"><?php _e( 'News Tickers were just the beginning!' ); ?></h3>
28
+
29
+ </div>
30
+
31
+ <div id="ditty-page__content">
32
+ <section class="ditty-section ditty-section--intro">
33
+ <p style="font-size:20px;margin-top:0;"><?php _e( '<strong>Ditty News Ticker</strong> has now become <strong>Ditty</strong>!' ); ?></p>
34
+ <p style="font-size:16px;"><?php _e( "This update has been a long time in the making! Due to the complete rebuild of code for <strong>Ditty 3.0</strong> we decided to limit the upgrade process. We created a new post type you can start using right away without potentially causing issues with your existing <strong>News Tickers</strong>.", 'ditty-news-ticker' ); ?></p>
35
+ <p style="font-size:16px;margin-bottom:0;"><?php _e( "Don't worry, all of your existing <strong>News Tickers</strong> will still work! Although, we do urge you to start upgrading and updating your tickers to the new <strong>Ditty</strong> post type. <strong>Ditty News Ticker</strong> is now relegated to legacy code and there will be very limited updates from this point on. Most development time will now be assigned to <strong>Ditty</strong> and existing and new <strong>Ditty</strong> extensions.", 'ditty-news-ticker' ); ?></p>
36
+ </section>
37
+ <section class="ditty-section">
38
+ <div class="ditty-row">
39
+ <div class="ditty-column">
40
+ <div class="ditty-container">
41
+ <h2 style="font-size:20px;margin-top: 0;margin-bottom:40px;"><?php printf( __( 'Ditty %s Features', 'ditty-news-ticker' ), ditty_version() ); ?>:</h2>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <div class="ditty-row">
46
+ <div class="ditty-column ditty-column--1_2">
47
+ <div class="ditty-container ditty-container--details">
48
+ <i class="fas fa-redo-alt"></i>
49
+ <div class="ditty-container--details__content">
50
+ <h3><?php _e( 'Live Updates', 'ditty-news-ticker' ); ?></h3>
51
+ <p><?php _e( 'Ditty will update in the background for users without the need to refresh the browser. Keep your content fresh and engaging.', 'ditty-news-ticker' ); ?></p>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ <div class="ditty-column ditty-column--1_2">
56
+ <div class="ditty-container ditty-container--details">
57
+ <i class="fas fa-edit"></i>
58
+ <div class="ditty-container--details__content">
59
+ <h3><?php _e( 'Live Editing', 'ditty-news-ticker' ); ?></h3>
60
+ <p><?php _e( 'See the changes you make while editing your Ditty as you make them. Add Items, edit Layouts and Displays and see what it looks like before saving.', 'ditty-news-ticker' ); ?></p>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ <div class="ditty-column ditty-column--1_2">
65
+ <div class="ditty-container ditty-container--details">
66
+ <i class="fas fa-plus-square"></i>
67
+ <div class="ditty-container--details__content">
68
+ <h3><?php _e( 'Global Rendering', 'ditty-news-ticker' ); ?></h3>
69
+ <p><?php _e( 'Easily add your Ditty globally on your site, anywhere, without modifying theme files. Want a ticker scrolling at the top of your site, no problem!', 'ditty-news-ticker' ); ?></p>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ <div class="ditty-column ditty-column--1_2">
74
+ <div class="ditty-container ditty-container--details">
75
+ <i class="fas fa-random"></i>
76
+ <div class="ditty-container--details__content">
77
+ <h3><?php _e( 'Mix & Match Content', 'ditty-news-ticker' ); ?></h3>
78
+ <p><?php _e( 'Combine multiple content feeds or custom content in a single Ditty. Merging custom default Items and feeds from various Ditty extensions together has never been easier.', 'ditty-news-ticker' ); ?></p>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ <div class="ditty-column ditty-column--1_2">
83
+ <div class="ditty-container ditty-container--details">
84
+ <i class="fas fa-tablet-alt"></i>
85
+ <div class="ditty-container--details__content">
86
+ <h3><?php _e( 'Customized Displays', 'ditty-news-ticker' ); ?></h3>
87
+ <p><?php _e( 'Render your Ditty as a custom ticker, list, slider, or other Display through extensions. Customize multiple settings to show your content the way you want.', 'ditty-news-ticker' ); ?></p>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ <div class="ditty-column ditty-column--1_2">
92
+ <div class="ditty-container ditty-container--details">
93
+ <i class="fas fa-pencil-ruler"></i>
94
+ <div class="ditty-container--details__content">
95
+ <h3><?php _e( 'Customized Layouts', 'ditty-news-ticker' ); ?></h3>
96
+ <p><?php _e( 'Take control of the the style of your content. Every Ditty Item type can be customized to reflect the style of your site. Use a pre-made template, or edit and customize to your needs!', 'ditty-news-ticker' ); ?></p>
97
+ </div>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </section>
102
+
103
+ </div>
104
+ </div><!-- /.wrap -->
105
+ <?php
106
+ }
includes/admin/settings.php ADDED
@@ -0,0 +1,410 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Register settings pages
5
+ *
6
+ * @since 3.0
7
+ */
8
+ function ditty_settings_pages() {
9
+ add_submenu_page(
10
+ 'edit.php?post_type=ditty', // The ID of the top-level menu page to which this submenu item belongs
11
+ __( 'Settings', 'ditty-news-ticker' ), // The value used to populate the browser's title bar when the menu page is active
12
+ __( 'Settings', 'ditty-news-ticker' ), // The label of this submenu item displayed in the menu
13
+ 'manage_ditty_settings', // What roles are able to access this submenu item
14
+ 'ditty_settings', // The ID used to represent this submenu item
15
+ 'ditty_settings_display' // The callback function used to render the options for this submenu item
16
+ );
17
+ }
18
+ add_action( 'admin_menu', 'ditty_settings_pages', 5 );
19
+
20
+
21
+ /**
22
+ * Render the settings page
23
+ *
24
+ * @since 3.0
25
+ */
26
+ function ditty_settings_display() {
27
+ ?>
28
+ <div id="ditty-page" class="wrap">
29
+
30
+ <div id="ditty-page__header">
31
+ <h2><?php _e( 'Ditty Settings', 'ditty-news-ticker' ); ?></h2>
32
+ </div>
33
+
34
+ <div id="ditty-page__content">
35
+ <div id="ditty-settings">
36
+
37
+ <?php
38
+ $init_panel = isset( $_GET['tab'] ) ? $_GET['tab'] : false;
39
+ $settings = apply_filters( 'ditty_settings_tabs', array(
40
+ 'general' => array(
41
+ 'icon' => 'fas fa-cog',
42
+ 'label' => __( 'General', 'ditty-news-ticker' ),
43
+ 'fields' => 'ditty_settings_general',
44
+ ),
45
+ 'global_ditty' => array(
46
+ 'icon' => 'fas fa-globe-americas',
47
+ 'label' => __( 'Global Ditty', 'ditty-news-ticker' ),
48
+ 'fields' => 'ditty_settings_global_ditty',
49
+ ),
50
+ 'layout_defaults' => array(
51
+ 'icon' => 'fas fa-pencil-ruler',
52
+ 'label' => __( 'Layout Defaults', 'ditty-news-ticker' ),
53
+ 'fields' => 'ditty_settings_variation_defaults',
54
+ ),
55
+ 'layout_templates' => array(
56
+ 'icon' => 'fas fa-pencil-ruler',
57
+ 'label' => __( 'Layout Templates', 'ditty-news-ticker' ),
58
+ 'fields' => 'ditty_settings_layout_templates',
59
+ ),
60
+ 'display_templates' => array(
61
+ 'icon' => 'fas fa-tablet-alt',
62
+ 'label' => __( 'Display Templates', 'ditty-news-ticker' ),
63
+ 'fields' => 'ditty_settings_display_templates',
64
+ ),
65
+ 'advanced' => array(
66
+ 'icon' => 'fas fa-pencil-alt',
67
+ 'label' => __( 'Advanced', 'ditty-news-ticker' ),
68
+ 'fields' => 'ditty_settings_advanced',
69
+ ),
70
+ ) );
71
+ ?>
72
+
73
+ <div class="ditty-settings__tabs">
74
+ <?php
75
+ if ( is_array( $settings ) && count( $settings ) > 0 ) {
76
+ foreach ( $settings as $slug => $setting ) {
77
+ echo '<a href="#" class="ditty-settings__tab ditty-settings__tab--' . $slug . '" data-panel="' . $slug . '">';
78
+ echo '<i class="' . $setting['icon'] . '"></i>';
79
+ echo '<span>' . $setting['label'] . '</span>';
80
+ echo '</a>';
81
+ }
82
+ }
83
+ ?>
84
+ </div>
85
+
86
+ <form class="ditty-settings__form">
87
+ <div class="ditty-settings__header">
88
+ <a href="#" class="ditty-button ditty-button--primary ditty-settings__save"><?php echo ditty_admin_strings( 'settings_save' ); ?></a>
89
+ </div>
90
+ <div class="ditty-notification-bar">
91
+ <div class="ditty-notification ditty-notification--updated"><?php echo ditty_admin_strings( 'settings_updated' ); ?></div>
92
+ <div class="ditty-notification ditty-notification--warning"><?php echo ditty_admin_strings( 'settings_changed' ); ?></div>
93
+ <div class="ditty-notification ditty-notification--error"><?php echo ditty_admin_strings( 'settings_error' ); ?></div>
94
+ </div>
95
+ <div class="ditty-settings__panels" data-init_panel="<?php echo $init_panel; ?>">
96
+ <?php
97
+ if ( is_array( $settings ) && count( $settings ) > 0 ) {
98
+ foreach ( $settings as $slug => $setting ) {
99
+ ?>
100
+ <div class="ditty-settings__panel ditty-settings__panel--<?php echo $slug; ?>" data-slide_id="<?php echo $slug; ?>" data-slide_cache="true">
101
+ <?php
102
+ if ( isset( $setting['fields'] ) && function_exists( $setting['fields'] ) ) {
103
+ call_user_func( $setting['fields'] );
104
+ }
105
+ ?>
106
+ </div>
107
+ <?php
108
+ }
109
+ }
110
+ ?>
111
+ </div>
112
+ <div class="ditty-settings__footer">
113
+ <a href="#" class="ditty-button ditty-button--primary ditty-settings__save"><?php echo ditty_admin_strings( 'settings_save' ); ?></a>
114
+ </div>
115
+ <div class="ditty-updating-overlay"></div>
116
+ </form>
117
+ </div>
118
+ </div>
119
+ </div><!-- /.wrap -->
120
+ <?php
121
+ }
122
+
123
+ /**
124
+ * Setup the general settings fields
125
+ *
126
+ * @since 3.0
127
+ */
128
+ function ditty_settings_general() {
129
+ $fields = array(
130
+ 'live_refresh' => array(
131
+ 'type' => 'number',
132
+ 'id' => 'live_refresh',
133
+ 'name' => __( 'Live Refresh Rate', 'ditty-news-ticker' ),
134
+ 'after' => __( 'Minute(s)', 'ditty-news-ticker' ),
135
+ 'help' => __( 'Set the live update refresh interval for your Ditty.', 'ditty-news-ticker' ),
136
+ 'std' => ditty_settings( 'live_refresh' ),
137
+ ),
138
+ // 'notification_email' => array(
139
+ // 'type' => 'text',
140
+ // 'id' => 'notification_email',
141
+ // 'name' => __( 'Notification Email', 'ditty-news-ticker' ),
142
+ // 'placeholder' => __( 'Add a notification email', 'ditty-news-ticker' ),
143
+ // 'sanitize' => 'email',
144
+ // 'atts' => array(
145
+ // 'type' => 'email',
146
+ // ),
147
+ // 'std' => ditty_settings( 'notification_email' ),
148
+ // ),
149
+ 'ditty_layout_ui' => array(
150
+ 'type' => 'radio',
151
+ 'id' => 'ditty_layout_ui',
152
+ 'name' => __( 'Layout Posts', 'ditty-news-ticker' ),
153
+ 'desc' => __( 'Edit Layouts directly as post types.', 'ditty-news-ticker' ),
154
+ 'inline' => true,
155
+ 'options' => array(
156
+ 'disabled' => __( 'Disabled', 'ditty-news-ticker' ),
157
+ 'enabled' => __( 'Enabled', 'ditty-news-ticker' ),
158
+ ),
159
+ 'std' => ditty_settings( 'ditty_layout_ui' ),
160
+ ),
161
+ 'ditty_display_ui' => array(
162
+ 'type' => 'radio',
163
+ 'id' => 'ditty_display_ui',
164
+ 'name' => __( 'Ditty Display Posts', 'ditty-news-ticker' ),
165
+ 'desc' => __( 'Edit Ditty Displays directly as post types.', 'ditty-news-ticker' ),
166
+ 'inline' => true,
167
+ 'options' => array(
168
+ 'disabled' => __( 'Disabled', 'ditty-news-ticker' ),
169
+ 'enabled' => __( 'Enabled', 'ditty-news-ticker' ),
170
+ ),
171
+ 'std' => ditty_settings( 'ditty_display_ui' ),
172
+ ),
173
+ );
174
+ ditty_fields( $fields );
175
+ }
176
+
177
+ /**
178
+ * Setup the layouts fields
179
+ *
180
+ * @since 3.0
181
+ */
182
+ function ditty_settings_variation_defaults() {
183
+ $fields = array(
184
+ 'layout_variation_defaults' => array(
185
+ 'type' => 'html',
186
+ 'id' => 'layout_variation_defaults',
187
+ 'name' => __( 'Layout Variation Defaults', 'ditty-news-ticker' ),
188
+ 'std' => Ditty()->layouts->variation_defaults(),
189
+ ),
190
+ );
191
+ ditty_fields( $fields );
192
+ }
193
+
194
+ /**
195
+ * Setup the layout templates fields
196
+ *
197
+ * @since 3.0
198
+ */
199
+ function ditty_settings_layout_templates() {
200
+ $fields = array(
201
+ 'layout_templates' => array(
202
+ 'type' => 'html',
203
+ 'id' => 'layout_templates',
204
+ 'name' => __( 'Layout Templates', 'ditty-news-ticker' ),
205
+ 'std' => Ditty()->layouts->layout_templates_list(),
206
+ ),
207
+ );
208
+ ditty_fields( $fields );
209
+ }
210
+
211
+ /**
212
+ * Setup the display templates fields
213
+ *
214
+ * @since 3.0
215
+ */
216
+ function ditty_settings_display_templates() {
217
+ $fields = array(
218
+ 'display_templates' => array(
219
+ 'type' => 'html',
220
+ 'id' => 'display_templates',
221
+ 'name' => __( 'Default Displays', 'ditty-news-ticker' ),
222
+ 'std' => Ditty()->displays->display_templates_list(),
223
+ ),
224
+ );
225
+ ditty_fields( $fields );
226
+ }
227
+
228
+ /**
229
+ * Setup the editor settings fields
230
+ *
231
+ * @since 3.0
232
+ */
233
+ function ditty_settings_advanced() {
234
+ $fields = array(
235
+ 'ditty_news_ticker' => array(
236
+ 'type' => 'checkbox',
237
+ 'id' => 'ditty_news_ticker',
238
+ 'name' => __( 'Ditty News Ticker', 'ditty-news-ticker' ),
239
+ 'label' => __( 'Enable Ditty News Ticker (Legacy code)', 'ditty-news-ticker' ),
240
+ 'input_desc' => __( 'This will enable loading of all legacy scripts and post types. Only enable this option if you have active Ditty News Ticker posts displaying on your site. You must refresh your browser after saving before changes take place.', 'ditty-news-ticker' ),
241
+ 'std' => ditty_settings( 'ditty_news_ticker' ),
242
+ ),
243
+ // 'ditty_layouts_sass' => array(
244
+ // 'type' => 'checkbox',
245
+ // 'id' => 'ditty_layouts_sass',
246
+ // 'name' => __( 'Ditty Layouts CSS Editor', 'ditty-news-ticker' ),
247
+ // 'label' => __( 'Use SASS for the Layout CSS editor', 'ditty-news-ticker' ),
248
+ // 'desc' => __( 'This is an advanced option. Error notifications may not work within the CSS editor.', 'ditty-news-ticker' ),
249
+ // 'std' => ditty_settings( 'ditty_layouts_sass' ),
250
+ // ),
251
+ );
252
+ ditty_fields( $fields );
253
+ }
254
+
255
+ /**
256
+ * Setup the global Ditty fields
257
+ *
258
+ * @since 3.0
259
+ */
260
+ function ditty_settings_global_ditty() {
261
+ $fields = array(
262
+ 'global_ditty' => array(
263
+ 'type' => 'group',
264
+ 'id' => 'global_ditty',
265
+ 'clone' => true,
266
+ 'clone_button' => __( 'Add More Global Tickers', 'ditty-news-ticker' ),
267
+ 'multiple_fields' => false,
268
+ 'fields' => array(
269
+ 'selector' => array(
270
+ 'type' => 'text',
271
+ 'id' => 'selector',
272
+ 'name' => __( 'HTML Selector', 'ditty-news-ticker' ),
273
+ 'help' => __( 'Add a jQuery HTML element selector to add a Ditty to.', 'ditty-news-ticker' ),
274
+ 'placeholder' => __( 'Example: #site-header', 'ditty-news-ticker' ),
275
+ ),
276
+ array(
277
+ 'type' => 'select',
278
+ 'id' => 'position',
279
+ 'name' => __( 'Position', 'ditty-news-ticker' ),
280
+ 'help' => __( 'Select the position of the Ditty in relation to the HTML selector.', 'ditty-news-ticker' ),
281
+ 'placeholder' => __( 'Select Position', 'ditty-news-ticker' ),
282
+ 'options' => array(
283
+ 'prepend' => __( 'Start of Element', 'ditty-news-ticker' ),
284
+ 'append' => __( 'End of Element', 'ditty-news-ticker' ),
285
+ 'before' => __( 'Before Element', 'ditty-news-ticker' ),
286
+ 'after' => __( 'After Element', 'ditty-news-ticker' ),
287
+ ),
288
+ ),
289
+ array(
290
+ 'type' => 'select',
291
+ 'id' => 'ditty',
292
+ 'name' => __( 'Ditty', 'ditty-news-ticker' ),
293
+ 'help' => __( 'Select a Ditty you want to display globally.', 'ditty-news-ticker' ),
294
+ 'placeholder' => __( 'Select a Ditty', 'ditty-news-ticker' ),
295
+ 'options' => Ditty()->singles->select_field_options(),
296
+ ),
297
+ array(
298
+ 'type' => 'select',
299
+ 'id' => 'display',
300
+ 'name' => __( 'Display', 'ditty-news-ticker' ),
301
+ 'help' => __( 'Optional: Select a custom display to use with the Ditty.', 'ditty-news-ticker' ),
302
+ 'placeholder' => __( 'Use Default Display', 'ditty-news-ticker' ),
303
+ 'options' => Ditty()->displays->select_field_options(),
304
+ ),
305
+ array(
306
+ 'type' => 'text',
307
+ 'id' => 'custom_id',
308
+ 'name' => __( 'Custom ID', 'ditty-news-ticker' ),
309
+ 'help' => __( 'Optional: Add a custom ID to the Ditty', 'ditty-news-ticker' ),
310
+ ),
311
+ array(
312
+ 'type' => 'text',
313
+ 'id' => 'custom_classes',
314
+ 'name' => __( 'Custom Classes', 'ditty-news-ticker' ),
315
+ 'help' => __( 'Optional: Add custom classes to the Ditty', 'ditty-news-ticker' ),
316
+ ),
317
+ ),
318
+ 'std' => ditty_settings( 'global_ditty' ),
319
+ ),
320
+ );
321
+ ditty_fields( $fields );
322
+ }
323
+
324
+ /**
325
+ * Save settings via ajax
326
+ *
327
+ * @since 3.0
328
+ */
329
+ function ditty_settings_save_ajax() {
330
+ check_ajax_referer( 'ditty', 'security' );
331
+ if ( ! current_user_can( 'manage_ditty_settings' ) ) {
332
+ return false;
333
+ }
334
+ $json_data = apply_filters( 'ditty_settings_save', $_POST, array() );
335
+ wp_send_json( $json_data );
336
+ }
337
+ add_action( 'wp_ajax_ditty_settings_save', 'ditty_settings_save_ajax' );
338
+
339
+ /**
340
+ * Save settings
341
+ *
342
+ * @since 3.0
343
+ */
344
+ function ditty_settings_save( $data, $json_data ) {
345
+
346
+ $input_updates = array();
347
+ $sanitized_global_ditty = array();
348
+ if ( isset( $data['global_ditty'] ) && is_array( $data['global_ditty'] ) && count( $data['global_ditty'] ) > 0 ) {
349
+ foreach ( $data['global_ditty'] as $index => $global_ditty ) {
350
+ $sanitized_classes = array();
351
+ if ( isset( $global_ditty['custom_classes'] ) ) {
352
+ $classes = array_map( 'trim', explode( ' ', $global_ditty['custom_classes'] ) );
353
+ if ( is_array( $classes ) && count( $classes ) > 0 ) {
354
+ foreach ( $classes as $i => $class ) {
355
+ $sanitized_classes[] = sanitize_html_class( $class );
356
+ }
357
+ }
358
+ }
359
+ $sanitized_data = array(
360
+ 'selector' => isset( $global_ditty['selector'] ) ? wp_kses_post( $global_ditty['selector'] ) : false,
361
+ 'position' => isset( $global_ditty['position'] ) ? esc_attr( $global_ditty['position'] ) : false,
362
+ 'ditty' => isset( $global_ditty['ditty'] ) ? intval( $global_ditty['ditty'] ) : false,
363
+ 'display' => isset( $global_ditty['display'] ) ? esc_attr( $global_ditty['display'] ) : false,
364
+ 'custom_id' => isset( $global_ditty['custom_id'] ) ? sanitize_title( $global_ditty['custom_id'] ) : false,
365
+ 'custom_classes' => isset( $global_ditty['custom_classes'] ) ? implode( ' ', $sanitized_classes ) : false,
366
+ );
367
+ $sanitized_global_ditty[] = $sanitized_data;
368
+
369
+ // Add data to pass back to javascript
370
+ $input_updates["global_ditty[{$index}][custom_id]"] = $sanitized_data['custom_id'];
371
+ $input_updates["global_ditty[{$index}][custom_classes]"] = $sanitized_data['custom_classes'];
372
+ }
373
+ }
374
+
375
+ $variation_types = ditty_layout_variation_types();
376
+ $sanitized_variation_defaults = array();
377
+ if ( is_array( $variation_types ) && count( $variation_types ) > 0 ) {
378
+ foreach ( $variation_types as $item_type => $item_type_variations ) {
379
+ if ( ! isset( $sanitized_variation_defaults[$item_type] ) ) {
380
+ $sanitized_variation_defaults[$item_type] = array();
381
+ }
382
+ if ( is_array( $item_type_variations ) && count( $item_type_variations ) > 0 ) {
383
+ foreach ( $item_type_variations as $variation_id => $item_type_variation ) {
384
+ if ( isset( $data["variation_default_{$item_type}_{$variation_id}"] ) ) {
385
+ $sanitized_variation_defaults[$item_type][$variation_id] = intval( $data["variation_default_{$item_type}_{$variation_id}"] );
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+
392
+ $settings = array(
393
+ 'live_refresh' => isset( $data['live_refresh'] ) ? intval( $data['live_refresh'] ) : 10,
394
+ 'ditty_display_ui' => isset( $data['ditty_display_ui'] ) ? esc_attr( $data['ditty_display_ui'] ) : 'disabled',
395
+ 'ditty_layout_ui' => isset( $data['ditty_layout_ui'] ) ? esc_attr( $data['ditty_layout_ui'] ) : 'disabled',
396
+ 'ditty_layouts_sass' => isset( $data['ditty_layouts_sass'] ) ? esc_attr( $data['ditty_layouts_sass'] ) : false,
397
+ 'variation_defaults' => $sanitized_variation_defaults,
398
+ 'global_ditty' => $sanitized_global_ditty,
399
+ 'ditty_news_ticker' => isset( $data['ditty_news_ticker'] ) ? esc_attr( $data['ditty_news_ticker'] ) : false,
400
+ 'notification_email' => ( isset( $data['notification_email'] ) && is_email( $data['notification_email'] ) ) ? $data['notification_email'] : false,
401
+ );
402
+ ditty_settings( $settings );
403
+
404
+ if ( ! isset( $json_data['input_updates'] ) ) {
405
+ $json_data['input_updates'] = array();
406
+ }
407
+ $json_data['input_updates'] = array_merge( $json_data['input_updates'], $input_updates );
408
+ return $json_data;
409
+ }
410
+ add_action( 'ditty_settings_save', 'ditty_settings_save', 10, 2 );
includes/class-ditty-activator.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Fired during plugin activation.
5
+ *
6
+ * This class defines all code necessary to run during the plugin's activation.
7
+ *
8
+ * @since 3.0
9
+ * @package Ditty
10
+ * @subpackage Ditty/includes
11
+ * @author Metaphor Creations <joe@metaphorcreations.com>
12
+ */
13
+ class Ditty_Activator {
14
+
15
+ /**
16
+ * Short Description. (use period)
17
+ *
18
+ * Long Description.
19
+ *
20
+ * @since 3.0
21
+ */
22
+ public static function activate() {
23
+ self::setup_sites();
24
+ }
25
+
26
+ /**
27
+ * Setup this site and all multisite sites
28
+ *
29
+ * @since 3.0
30
+ * @access private
31
+ */
32
+ public static function setup_sites( $network_wide = false ) {
33
+
34
+ global $wpdb;
35
+
36
+ if( is_multisite() && $network_wide ) {
37
+
38
+ foreach( $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs LIMIT 100" ) as $blog_id ) {
39
+
40
+ switch_to_blog( $blog_id );
41
+ self::run_install();
42
+ restore_current_blog();
43
+ }
44
+
45
+ } else {
46
+
47
+ self::run_install();
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Run the install process
53
+ *
54
+ * @since 3.0
55
+ * @access private
56
+ * @return string The name of the plugin.
57
+ */
58
+ public static function run_install() {
59
+
60
+ // Add Upgraded From Option
61
+ // $current_version = get_option( 'ditty_version', '0' );
62
+ // if ( version_compare( $current_version, '3.0', '<' ) ) {
63
+ // ditty_v3_upgrades();
64
+ // }
65
+ //
66
+ // if ( DITTY_VERSION != $current_version ) {
67
+ // update_option( 'ditty_version_upgraded_from', $current_version );
68
+ // update_option( 'ditty_version', DITTY_VERSION );
69
+ // }
70
+ }
71
+
72
+ }
includes/class-ditty-db-item-meta.php ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ditty DB Item Meta Class
4
+ *
5
+ * This class is for interacting with the layout meta database table
6
+ *
7
+ * @package Ditty
8
+ * @subpackage Classes/Ditty Item Meta
9
+ * @copyright Copyright (c) 2021, Metaphor Creations
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 3.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) exit;
16
+
17
+ class Ditty_DB_Item_Meta extends Ditty_DB {
18
+
19
+ /**
20
+ * Get things started
21
+ *
22
+ * @since 3.0
23
+ */
24
+ public function __construct() {
25
+ global $wpdb;
26
+
27
+ $this->table_name = $wpdb->prefix . 'ditty_itemmeta';
28
+ $this->primary_key = 'item_id';
29
+ $this->version = '1.0';
30
+
31
+ add_action( 'plugins_loaded', array( $this, 'register_table' ), 11 );
32
+ }
33
+
34
+ /**
35
+ * Get table columns and data types
36
+ *
37
+ * @since 3.0
38
+ */
39
+ public function get_columns() {
40
+ return array(
41
+ 'meta_id' => '%d',
42
+ 'item_id' => '%d',
43
+ 'meta_key' => '%s',
44
+ 'meta_value' => '%s',
45
+ );
46
+ }
47
+
48
+ /**
49
+ * Register the table with $wpdb so the metadata api can find it
50
+ *
51
+ * @since 3.0
52
+ */
53
+ public function register_table() {
54
+ global $wpdb;
55
+ $wpdb->itemmeta = $this->table_name;
56
+ }
57
+
58
+ /**
59
+ * Retrieve meta field for a item.
60
+ *
61
+ * For internal use only. Use Ditty_Item->get_item_meta() for public usage.
62
+ *
63
+ * @param int $item_id Item ID.
64
+ * @param string $meta_key The meta key to retrieve.
65
+ * @param bool $single Whether to return a single value.
66
+ * @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
67
+ *
68
+ * @access private
69
+ * @since 3.0
70
+ */
71
+ public function get_meta( $item_id = 0, $meta_key = '', $single = false ) {
72
+ $item_id = $this->sanitize_item_id( $item_id );
73
+ if ( false === $item_id ) {
74
+ return false;
75
+ }
76
+
77
+ return get_metadata( 'item', $item_id, $meta_key, $single );
78
+ }
79
+
80
+ /**
81
+ * Add meta data field to a layout.
82
+ *
83
+ * For internal use only. Use Ditty_Item->add_item_meta() for public usage.
84
+ *
85
+ * @param int $item_id Item ID.
86
+ * @param string $meta_key Metadata key.
87
+ * @param mixed $meta_value Metadata value.
88
+ * @param bool $unique Optional, default is false. Whether the same key should not be added.
89
+ * @return bool False for failure. True for success.
90
+ *
91
+ * @access private
92
+ * @since 3.0
93
+ */
94
+ public function add_meta( $item_id = 0, $meta_key = '', $meta_value, $unique = false ) {
95
+ $item_id = $this->sanitize_item_id( $item_id );
96
+ if ( false === $item_id ) {
97
+ return false;
98
+ }
99
+
100
+ return add_metadata( 'item', $item_id, $meta_key, $meta_value, $unique );
101
+ }
102
+
103
+ /**
104
+ * Update item meta field based on Item ID.
105
+ *
106
+ * For internal use only. Use Ditty_Item->update_item_meta() for public usage.
107
+ *
108
+ * Use the $prev_value parameter to differentiate between meta fields with the
109
+ * same key and Item ID.
110
+ *
111
+ * If the meta field for the item does not exist, it will be added.
112
+ *
113
+ * @param int $item_id Item Post ID.
114
+ * @param string $meta_key Metadata key.
115
+ * @param mixed $meta_value Metadata value.
116
+ * @param mixed $prev_value Optional. Previous value to check before removing.
117
+ * @return bool False on failure, true if success.
118
+ *
119
+ * @access private
120
+ * @since 3.0
121
+ */
122
+ public function update_meta( $item_id = 0, $meta_key = '', $meta_value, $prev_value = '' ) {
123
+ $item_id = $this->sanitize_item_id( $item_id );
124
+ if ( false === $item_id ) {
125
+ return false;
126
+ }
127
+
128
+ return update_metadata( 'item', $item_id, $meta_key, $meta_value, $prev_value );
129
+ }
130
+
131
+ /**
132
+ * Remove metadata matching criteria from a item.
133
+ *
134
+ * For internal use only. Use Ditty_Item->delete_item_meta() for public usage.
135
+ *
136
+ * You can match based on the key, or key and value. Removing based on key and
137
+ * value, will keep from removing duplicate metadata with the same key. It also
138
+ * allows removing all metadata matching key, if needed.
139
+ *
140
+ * @param int $item_id Item ID.
141
+ * @param string $meta_key Metadata name.
142
+ * @param mixed $meta_value Optional. Metadata value.
143
+ * @return bool False for failure. True for success.
144
+ *
145
+ * @access private
146
+ * @since 3.0
147
+ */
148
+ public function delete_meta( $item_id = 0, $meta_key = '', $meta_value = '' ) {
149
+ return delete_metadata( 'item', $item_id, $meta_key, $meta_value );
150
+ }
151
+
152
+ /**
153
+ * Retrieve all metadata by a specific item
154
+ *
155
+ * @since 3.0
156
+ * @return object
157
+ */
158
+ public function custom_meta( $item_id = 0 ) {
159
+ global $wpdb;
160
+ $item_id = esc_sql( $item_id );
161
+
162
+ return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE item_id = %s;", $item_id ) );
163
+ }
164
+
165
+ /**
166
+ * Create the table
167
+ *
168
+ * @since 3.0
169
+ */
170
+ public function create_table() {
171
+
172
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
173
+
174
+ $sql = "CREATE TABLE {$this->table_name} (
175
+ meta_id bigint(20) NOT NULL AUTO_INCREMENT,
176
+ item_id bigint(20) NOT NULL,
177
+ meta_key varchar(255) DEFAULT NULL,
178
+ meta_value longtext,
179
+ PRIMARY KEY (meta_id),
180
+ KEY item_id (item_id),
181
+ KEY meta_key (meta_key)
182
+ ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
183
+
184
+ dbDelta( $sql );
185
+
186
+ update_option( $this->table_name . '_db_version', $this->version );
187
+ }
188
+
189
+ /**
190
+ * Given a layout post ID, make sure it's a positive number, greater than zero before inserting or adding.
191
+ *
192
+ * @since 3.0
193
+ * @param int|stirng $post A passed layout post ID.
194
+ * @return int|bool The normalized layout post ID or false if it's found to not be valid.
195
+ */
196
+ private function sanitize_item_id( $item_id ) {
197
+ if ( ! is_numeric( $item_id ) ) {
198
+ return false;
199
+ }
200
+
201
+ $item_id = (int) $item_id;
202
+
203
+ // We were given a non positive number
204
+ if ( absint( $item_id ) !== $item_id ) {
205
+ return false;
206
+ }
207
+
208
+ if ( empty( $item_id ) ) {
209
+ return false;
210
+ }
211
+
212
+ return absint( $item_id );
213
+ }
214
+
215
+ }
includes/class-ditty-db-items.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ditty DB Items class
4
+ *
5
+ * This class is for interacting with the layout meta database table
6
+ *
7
+ * @package Ditty
8
+ * @subpackage Classes/Ditty DB Items
9
+ * @copyright Copyright (c) 2021, Metaphor Creations
10
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
+ * @since 3.0
12
+ */
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) exit;
16
+
17
+ class Ditty_DB_Items extends Ditty_DB {
18
+
19
+ /**
20
+ * Get things started
21
+ *
22
+ * @since 3.0
23
+ */
24
+ public function __construct() {
25
+ global $wpdb;
26
+
27
+ $this->table_name = $wpdb->prefix . 'ditty_items';
28
+ $this->primary_key = 'item_id';
29
+ $this->version = '1.0';
30
+
31
+ add_action( 'plugins_loaded', array( $this, 'register_table' ), 11 );
32
+ }
33
+
34
+ /**
35
+ * Get table columns and data types
36
+ *
37
+ * @since 3.0
38
+ */
39
+ public function get_columns() {
40
+ return array(
41
+ 'item_id' => '%d',
42
+ 'item_type' => '%s',
43
+ 'item_value' => '%s',
44
+ 'ditty_id' => '%d',
45
+ 'layout_id' => '%s',
46
+ 'layout_value' => '%s',
47
+ 'item_index' => '%d',
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Get default column values
53
+ *
54
+ * @since 3.0
55
+ */
56
+ public function get_column_defaults() {
57
+ return array(
58
+ 'item_id' => 0,
59
+ 'item_type' => '',
60
+ 'item_value' => '',
61
+ 'ditty_id' => 0,
62
+ 'layout_id' => '',
63
+ 'layout_value' => '',
64
+ 'item_index' => 0,
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Checks if a item exists
70
+ *
71
+ * @since 3.0
72
+ */
73
+ public function exists( $value = '', $field = 'item_id' ) {
74
+
75
+ $columns = $this->get_columns();
76
+ if ( ! array_key_exists( $field, $columns ) ) {
77
+ return false;
78
+ }
79
+
80
+ return (bool) $this->get_column_by( 'item_id', $field, $value );
81
+ }
82
+
83
+ /**
84
+ * Retrieve all rows by a specific column / value
85
+ *
86
+ * @since 3.0
87
+ * @return object
88
+ */
89
+ public function get_rows_by( $column, $row_id ) {
90
+ global $wpdb;
91
+ $column = esc_sql( $column );
92
+
93
+ return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $column = %s ORDER BY item_index DESC;", $row_id ) );
94
+ }
95
+
96
+ /**
97
+ * Get items for a post
98
+ *
99
+ * @since 3.0
100
+ * @return object
101
+ */
102
+ public function get_items( $ditty_id, $item_type='all', $item_order='ASC' ) {
103
+ global $wpdb;
104
+
105
+ if( $item_type == 'all' ) {
106
+ $query = $wpdb->prepare("SELECT * FROM $this->table_name WHERE ditty_id = %s ORDER BY item_index {$item_order};", $ditty_id);
107
+ } else {
108
+ $query = $wpdb->prepare("SELECT * FROM $this->table_name WHERE ditty_id = %s AND item_type = %s ORDER BY item_index {$item_order};", $ditty_id, $item_type);
109
+ }
110
+
111
+ return $wpdb->get_results( $query );
112
+ }
113
+
114
+ /**
115
+ * Search items
116
+ *
117
+ * @since 3.0
118
+ * @return object
119
+ */
120
+ public function search_items( $search, $item_type='all', $item_order='ASC' ) {
121
+ global $wpdb;
122
+ $search = '%'.$search.'%';
123
+
124
+ if( $item_type == 'all' ) {
125
+ $query = $wpdb->prepare( "SELECT * FROM $this->table_name WHERE LOWER(item_value) LIKE LOWER(%s) ORDER BY item_index {$item_order};", $search );
126
+ } else {
127
+ if ( is_array( $item_type ) ) {
128
+ $item_type = array_map( 'esc_attr', $item_type );
129
+ $item_type = implode( "','", $item_type );
130
+ }
131
+ $query = $wpdb->prepare( "SELECT * FROM $this->table_name WHERE LOWER(item_value) LIKE LOWER(%s) AND item_type IN('{$item_type}') ORDER BY item_index {$item_order};", $search );
132
+ }
133
+
134
+ return $wpdb->get_results( $query );
135
+ }
136
+
137
+ /**
138
+ * Register the table with $wpdb so the metadata api can find it
139
+ *
140
+ * @since 3.0
141
+ */
142
+ public function register_table() {
143
+ global $wpdb;
144
+ $wpdb->items = $this->table_name;
145
+ }
146
+
147
+ /**
148
+ * Create the table
149
+ *
150
+ * @since 3.0
151
+ */
152
+ public function create_table() {
153
+
154
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
155
+
156
+ $sql = "CREATE TABLE {$this->table_name} (
157
+ item_id bigint(20) NOT NULL AUTO_INCREMENT,
158
+ item_type varchar(255),
159
+ item_value longtext,
160
+ ditty_id bigint(20) NOT NULL,
161
+ layout_id bigint(20),
162
+ layout_value longtext,
163
+ item_index bigint(20),
164
+ PRIMARY KEY (item_id),
165
+ KEY ditty_id (ditty_id)
166
+ ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
167
+
168
+ dbDelta( $sql );
169
+
170
+ update_option( $this->table_name . '_db_version', $this->version );
171
+ }
172
+ }
includes/class-ditty-db.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) exit;
5
+
6
+ /**
7
+ * Base database actions
8
+ *
9
+ * @link https://www.metaphorcreations.com
10
+ * @since 3.0
11
+ *
12
+ * @package Ditty
13
+ * @subpackage Ditty/includes
14
+ */
15
+
16
+ /**
17
+ * Base database actions
18
+ *
19
+ * This class is required for all database classes
20
+ *
21
+ * @since 3.0
22
+ * @package Ditty
23
+ * @subpackage Ditty/includes
24
+ * @author Metaphor Creations <joe@metaphorcreations.com>
25
+ */
26
+ abstract class Ditty_DB {
27
+
28
+ /**
29
+ * The name of our database table
30
+ *
31
+ * @since 3.0
32
+ */
33
+ public $table_name;
34
+
35
+ /**
36
+ * The version of our database table
37
+ *
38
+ * @since 3.0
39
+ */
40
+ public $version;
41
+
42
+ /**
43
+ * The name of the primary column
44
+ *
45
+ * @since 3.0
46
+ */
47
+ public $primary_key;
48
+
49
+ /**
50
+ * Get things started
51
+ *
52
+ * @since 3.0
53
+ */
54
+ public function __construct() {}
55
+
56
+ /**
57
+ * Whitelist of columns
58
+ *
59
+ * @since 3.0
60
+ * @return array
61
+ */
62
+ public function get_columns() {
63
+ return array();
64
+ }
65
+
66
+ /**
67
+ * Default column values
68
+ *
69
+ * @since 3.0
70
+ * @return array
71
+ */
72
+ public function get_column_defaults() {
73
+ return array();
74
+ }
75
+
76
+ /**
77
+ * Retrieve a row by the primary key
78
+ *
79
+ * @since 3.0
80
+ * @return object
81
+ */
82
+ public function get( $row_id ) {
83
+ global $wpdb;
84
+ return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $this->primary_key = %s LIMIT 1;", $row_id ) );
85
+ }
86
+
87
+ /**
88
+ * Retrieve a row by a specific column / value
89
+ *
90
+ * @since 3.0
91
+ * @return object
92
+ */
93
+ public function get_by( $column, $row_id ) {
94
+ global $wpdb;
95
+ $column = esc_sql( $column );
96
+ return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $column = %s LIMIT 1;", $row_id ) );
97
+ }
98
+
99
+ /**
100
+ * Retrieve a specific column's value by the primary key
101
+ *
102
+ * @since 3.0
103
+ * @return string
104
+ */
105
+ public function get_column( $column, $row_id ) {
106
+ global $wpdb;
107
+ $column = esc_sql( $column );
108
+ return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $this->primary_key = %s LIMIT 1;", $row_id ) );
109
+ }
110
+
111
+ /**
112
+ * Retrieve a specific column's value by the the specified column / value
113
+ *
114
+ * @since 3.0
115
+ * @return string
116
+ */
117
+ public function get_column_by( $column, $column_where, $column_value ) {
118
+ global $wpdb;
119
+ $column_where = esc_sql( $column_where );
120
+ $column = esc_sql( $column );
121
+ return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $column_where = %s LIMIT 1;", $column_value ) );
122
+ }
123
+
124
+ /**
125
+ * Insert a new row
126
+ *
127
+ * @since 3.0
128
+ * @return int
129
+ */
130
+ public function insert( $data, $type = '' ) {
131
+ global $wpdb;
132
+
133
+ // Set default values
134
+ $data = wp_parse_args( $data, $this->get_column_defaults() );
135
+
136
+ do_action( 'ditty_pre_insert_' . $type, $data );
137
+
138
+ // Initialise column format array
139
+ $column_formats = $this->get_columns();
140
+
141
+ // Force fields to lower case
142
+ $data = array_change_key_case( $data );
143
+
144
+ // White list columns
145
+ $data = array_intersect_key( $data, $column_formats );
146
+
147
+ // Reorder $column_formats to match the order of columns given in $data
148
+ $data_keys = array_keys( $data );
149
+ $column_formats = array_merge( array_flip( $data_keys ), $column_formats );
150
+
151
+ $wpdb->insert( $this->table_name, $data, $column_formats );
152
+ $wpdb_insert_id = $wpdb->insert_id;
153
+
154
+ do_action( 'ditty_post_insert_' . $type, $wpdb_insert_id, $data );
155
+
156
+ return $wpdb_insert_id;
157
+ }
158
+
159
+ /**
160
+ * Update a row
161
+ *
162
+ * @since 3.0
163
+ * @return bool
164
+ */
165
+ public function update( $row_id, $data = array(), $where = '' ) {
166
+
167
+ global $wpdb;
168
+
169
+ // Row ID must be positive integer
170
+ $row_id = absint( $row_id );
171
+
172
+ if( empty( $row_id ) ) {
173
+ return false;
174
+ }
175
+
176
+ if( empty( $where ) ) {
177
+ $where = $this->primary_key;
178
+ }
179
+
180
+ // Initialise column format array
181
+ $column_formats = $this->get_columns();
182
+
183
+ // Force fields to lower case
184
+ $data = array_change_key_case( $data );
185
+
186
+ // White list columns
187
+ $data = array_intersect_key( $data, $column_formats );
188
+
189
+ // Reorder $column_formats to match the order of columns given in $data
190
+ $data_keys = array_keys( $data );
191
+ $column_formats = array_merge( array_flip( $data_keys ), $column_formats );
192
+
193
+ if ( false === $wpdb->update( $this->table_name, $data, array( $where => $row_id ), $column_formats ) ) {
194
+ return false;
195
+ }
196
+
197
+ return true;
198
+ }
199
+
200
+ /**
201
+ * Delete a row identified by the primary key
202
+ *
203
+ * @since 3.0
204
+ * @return bool
205
+ */
206
+ public function delete( $row_id = 0 ) {
207
+
208
+ global $wpdb;
209
+
210
+ // Row ID must be positive integer
211
+ $row_id = absint( $row_id );
212
+
213
+ if( empty( $row_id ) ) {
214
+ return false;
215
+ }
216
+
217
+ if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM $this->table_name WHERE $this->primary_key = %d", $row_id ) ) ) {
218
+ return false;
219
+ }
220
+
221
+ return true;
222
+ }
223
+
224
+ /**
225
+ * Check if the given table exists
226
+ *
227
+ * @since 3.0
228
+ * @param string $table The table name
229
+ * @return bool If the table name exists
230
+ */
231
+ public function table_exists( $table ) {
232
+ global $wpdb;
233
+ $table = sanitize_text_field( $table );
234
+
235
+ return $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE '%s'", $table ) ) === $table;
236
+ }
237
+
238
+ /**
239
+ * Check if the table was ever installed
240
+ *
241
+ * @since 3.0
242
+ * @return bool Returns if the customers table was installed and upgrade routine run
243
+ */
244
+ public function installed() {
245
+ return $this->table_exists( $this->table_name );
246
+ }
247
+
248
+ }
includes/class-ditty-deactivator.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Fired during plugin deactivation.
5
+ *
6
+ * This class defines all code necessary to run during the plugin's deactivation.
7
+ *
8
+ * @since 3.0
9
+ * @package Ditty
10
+ * @subpackage Ditty/includes
11
+ * @author Metaphor Creations <joe@metaphorcreations.com>
12
+ */
13
+ class Ditty_Deactivator {
14
+
15
+ /**
16
+ * Short Description. (use period)
17
+ *
18
+ * Long Description.
19
+ *
20
+ * @since 3.0
21
+ */
22
+ public static function deactivate() {
23
+
24
+ }
25
+
26
+ }
includes/class-ditty-display-item.php ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ditty Display Item Class
4
+ *
5
+ * @package Ditty
6
+ * @subpackage Classes/Ditty Item
7
+ * @copyright Copyright (c) 2021, Metaphor Creations
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 3.0
10
+ */
11
+ class Ditty_Display_Item {
12
+
13
+ private $layout_id;
14
+ private $layout_value;
15
+ private $layout_object;
16
+ private $item_id;
17
+ private $item_uniq_id;
18
+ private $item_type;
19
+ private $item_type_object;
20
+ private $item_value;
21
+ private $ditty_id;
22
+ private $has_error;
23
+ private $custom_classes;
24
+
25
+ /**
26
+ * Get things started\*
27
+ * @access public
28
+ * @since 3.0
29
+ */
30
+ public function __construct( $meta ) {
31
+ $this->layout_value = isset( $meta['layout_value'] ) ? maybe_unserialize( $meta['layout_value'] ) : false;
32
+ $this->item_value = isset( $meta['item_value'] ) ? maybe_unserialize( $meta['item_value'] ) : '';
33
+ $this->item_id = isset( $meta['item_id'] ) ? $meta['item_id'] : -1;
34
+ $this->item_uniq_id = isset( $meta['item_uniq_id'] ) ? $meta['item_uniq_id'] : $this->item_id;
35
+ $this->item_type = isset( $meta['item_type'] ) ? $meta['item_type'] : false;
36
+ $this->ditty_id = isset( $meta['ditty_id'] ) ? $meta['ditty_id'] : -1;
37
+ $this->has_error = isset( $meta['has_error'] ) ? $meta['has_error'] : false;
38
+ $this->custom_classes = isset( $meta['custom_classes'] ) ? $meta['custom_classes'] : false;
39
+ if ( ! $this->has_error ) {
40
+ $this->parse_layout_id();
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Return the item id
46
+ *
47
+ * @access public
48
+ * @since 3.0
49
+ * @return int $id
50
+ */
51
+ public function get_id() {
52
+ return $this->item_id;
53
+ }
54
+
55
+ /**
56
+ * Return the item uniq id
57
+ *
58
+ * @access public
59
+ * @since 3.0
60
+ * @return int $id
61
+ */
62
+ public function get_uniq_id() {
63
+ return $this->item_uniq_id;
64
+ }
65
+
66
+ /**
67
+ * Return the item parent id
68
+ *
69
+ * @access public
70
+ * @since 3.0
71
+ * @return int $id
72
+ */
73
+ public function get_parent_id() {
74
+ return 0;
75
+ }
76
+
77
+ /**
78
+ * Return the item value
79
+ *
80
+ * @access public
81
+ * @since 3.0
82
+ * @return string $label
83
+ */
84
+ public function get_value() {
85
+ return maybe_unserialize( $this->item_value );
86
+ }
87
+
88
+ /**
89
+ * Return the item type
90
+ *
91
+ * @access public
92
+ * @since 3.0
93
+ * @return string $label
94
+ */
95
+ public function get_item_type() {
96
+ return $this->item_type;
97
+ }
98
+
99
+ /**
100
+ * Return the layout id
101
+ *
102
+ * @access public
103
+ * @since 3.0
104
+ * @return int $layout_id
105
+ */
106
+ public function get_layout_id() {
107
+ return $this->layout_id;
108
+ }
109
+
110
+ /**
111
+ * Return the layout value
112
+ *
113
+ * @access public
114
+ * @since 3.0
115
+ * @return int $layout_id
116
+ */
117
+ public function get_layout_value() {
118
+ return $this->layout_value;
119
+ }
120
+
121
+ /**
122
+ * Return the layout css
123
+ *
124
+ * @access public
125
+ * @since 3.0
126
+ * @return html
127
+ */
128
+ public function get_layout_css() {
129
+ if ( $layout_object = $this->get_layout_object() ) {
130
+ $layout_css = $layout_object->get_css_compiled();
131
+ return $layout_css;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Return the item type object
137
+ *
138
+ * @access public
139
+ * @since 3.0
140
+ * @return int $item_type_object
141
+ */
142
+ private function get_type_object() {
143
+ if ( ! $this->item_type_object ) {
144
+ $this->item_type_object = ditty_item_type_object( $this->item_type );
145
+ }
146
+ return $this->item_type_object;
147
+ }
148
+
149
+ /**
150
+ * Return the layout object
151
+ *
152
+ * @access public
153
+ * @since 3.0
154
+ * @return int $layout_object
155
+ */
156
+ public function get_layout_object() {
157
+ if ( ! $this->layout_object ) {
158
+ $this->layout_object = new Ditty_Layout( $this->get_layout_id(), $this->get_item_type(), $this->item_value );
159
+ }
160
+ return $this->layout_object;
161
+ }
162
+
163
+ /**
164
+ * Confirm that the layout exists
165
+ *
166
+ * @access public
167
+ * @since 3.0
168
+ * @return int $id
169
+ */
170
+ private function parse_layout_id() {
171
+ $layout_value = $this->get_layout_value();
172
+ $layout_id = isset( $layout_value['default'] ) ? $layout_value['default'] : 0;
173
+ $this->layout_id = apply_filters( 'ditty_display_item_layout_id', $layout_id, $this );
174
+ if ( false === strpos( $layout_id, 'new-' ) && 'publish' != get_post_status( $this->layout_id ) ) {
175
+ $this->item_value = array( 'ditty_feed_error' => sprintf( __( 'Ditty Layout does not exist for %s item!', 'ditty-news-ticker' ), $this->get_item_type() ) );
176
+ $this->has_error = true;
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Return custom classes
182
+ *
183
+ * @access private
184
+ * @since 3.0
185
+ * @return string $classes
186
+ */
187
+ private function get_custom_classes() {
188
+ if ( $this->custom_classes ) {
189
+ $classes = explode( ' ', $this->custom_classes );
190
+ return $classes;
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Setup the item classes
196
+ *
197
+ * @access private
198
+ * @since 3.0
199
+ * @return string $classes
200
+ */
201
+ private function get_classes() {
202
+ $classes = array();
203
+ $classes[] = 'ditty-item';
204
+ $classes[] = 'ditty-item--' . esc_attr( $this->item_id );
205
+ if ( $this->item_id != $this->item_uniq_id ) {
206
+ $classes[] = 'ditty-item--' . esc_attr( $this->item_uniq_id );
207
+ }
208
+ $classes[] = 'ditty-item-type--' . esc_attr( $this->item_type );
209
+ if ( $this->layout_id ) {
210
+ $classes[] = 'ditty-layout--' . esc_attr( $this->layout_id );
211
+ } else {
212
+ $classes[] = 'ditty-layout--default';
213
+ }
214
+ if ( $this->has_error ) {
215
+ $classes[] = 'ditty-item--error';
216
+ }
217
+ if ( $custom_classes = $this->get_custom_classes() ) {
218
+ $classes = array_merge( $classes, $custom_classes );
219
+ }
220
+ $classes = apply_filters( 'ditty_display_item_classes', $classes, $this->item_id );
221
+ return implode( ' ', $classes );
222
+ }
223
+
224
+ /**
225
+ * Render the item via layout
226
+ *
227
+ * @access public
228
+ * @since 3.0
229
+ * @return html
230
+ */
231
+ public function render_html( $render='echo' ) {
232
+ $html = '';
233
+ if ( $layout_object = $this->get_layout_object() ) {
234
+ $atts = array(
235
+ 'class' => $this->get_classes(),
236
+ 'data-item_id' => $this->get_id(),
237
+ 'data-item_uniq_id' => $this->get_uniq_id(),
238
+ 'data-parent_id' => $this->get_parent_id(),
239
+ 'data-item_type' => $this->get_item_type(),
240
+ 'data-layout_id' => $this->get_layout_id(),
241
+ );
242
+
243
+ $html .= '<div ' . ditty_attr_to_html( $atts ) . '>';
244
+ $html .= '<div class="ditty-item__elements">';
245
+ $html .= do_shortcode( $layout_object->render() );
246
+ $html .= '</div>';
247
+ $html .= '</div>';
248
+ }
249
+
250
+ // Filter the html
251
+ $html = apply_filters( 'ditty_render_item', $html, $this );
252
+
253
+ if ( 'echo' == $render ) {
254
+ echo $html;
255
+ } else {
256
+ return $html;
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Compile the layout data
262
+ *
263
+ * @access public
264
+ * @since 3.0
265
+ * @return html
266
+ */
267
+ public function compile_data() {
268
+ if ( $html = $this->render_html( 'return' ) ) {
269
+ $data = array(
270
+ 'id' => ( string ) $this->get_id(),
271
+ 'uniq_id' => ( string ) $this->get_uniq_id(),
272
+ 'parent_id' => ( string ) $this->get_parent_id(),
273
+ 'html' => $html,
274
+ 'css' => $this->get_layout_css(),
275
+ 'layout_id' => $this->get_layout_id(),
276
+ 'is_disabled' => array_unique( apply_filters( 'ditty_item_disabled', array(), $this->get_id() ) ),
277
+ );
278
+ return $data;
279
+ }
280
+ }
281
+
282
+ }
includes/class-ditty-display-type-list.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Display Type List Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Display Type List
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Display_Type_List extends Ditty_Display_Type {
13
+
14
+ /**
15
+ * Type
16
+ *
17
+ * @since 3.0
18
+ */
19
+ public $type = 'list';
20
+
21
+ /**
22
+ * Setup the display settings
23
+ *
24
+ * @access public
25
+ * @since 3.0
26
+ */
27
+ public function fields( $values = array() ) {
28
+ $fields = array(
29
+ 'listSettings' => array(
30
+ 'type' => 'group',
31
+ 'id' => 'listSettings',
32
+ 'collapsible' => true,
33
+ 'default_state' => 'expanded',
34
+ 'multiple_fields' => true,
35
+ 'name' => __( 'General Settings', 'ditty-news-ticker' ),
36
+ 'help' => __( 'Configure the general functionality settings.', 'ditty-news-ticker' ),
37
+ 'fields' => array(
38
+ 'spacing' => array(
39
+ 'type' => 'slider',
40
+ 'id' => 'spacing',
41
+ 'name' => __( 'Spacing', 'ditty-news-ticker' ),
42
+ 'help' => __( 'Set the amount of space between items (in pixels).', 'ditty-news-ticker' ),
43
+ 'suffix' => 'px',
44
+ 'js_options' => array(
45
+ 'min' => 0,
46
+ 'max' => 100,
47
+ 'step' => 1,
48
+ ),
49
+ 'std' => isset( $values['spacing'] ) ? $values['spacing'] : false,
50
+ ),
51
+ 'paging' => array(
52
+ 'type' => 'radio',
53
+ 'id' => 'paging',
54
+ 'name' => __( 'Paging', 'ditty-news-ticker' ),
55
+ 'help' => __( 'Split the list into pages', 'ditty-news-ticker' ),
56
+ 'inline' => true,
57
+ 'options' => array(
58
+ 0 => __( 'No', 'ditty-news-ticker' ),
59
+ 1 => __( 'Yes', 'ditty-news-ticker' ),
60
+ ),
61
+ 'std' => isset( $values['paging'] ) ? $values['paging'] : false,
62
+ ),
63
+ 'perPage' => array(
64
+ 'type' => 'number',
65
+ 'id' => 'perPage',
66
+ 'name' => __( 'Items Per Page', 'ditty-news-ticker' ),
67
+ 'help' => __( 'Set the number of items to show per page', 'ditty-news-ticker' ),
68
+ 'visible' => array( '_ditty_listSettings[paging]', '=', '1' ),
69
+ 'std' => isset( $values['perPage'] ) ? $values['perPage'] : false,
70
+ ),
71
+ 'transition' => array(
72
+ 'type' => 'select',
73
+ 'id' => 'transition',
74
+ 'name' => __( 'Page Transition', 'ditty-news-ticker' ),
75
+ 'help' => __( 'Set the type of transition to use between pages', 'ditty-news-ticker' ),
76
+ 'options' => ditty_slider_transitions(),
77
+ 'std' => isset( $values['transition'] ) ? $values['transition'] : false,
78
+ ),
79
+ 'transitionEase' => array(
80
+ 'type' => 'select',
81
+ 'id' => 'transitionEase',
82
+ 'name' => __( 'Page Transition Ease', 'ditty-news-ticker' ),
83
+ 'help' => __( 'Set the easing of the transition between pages.', 'ditty-news-ticker' ),
84
+ 'options' => ditty_ease_array(),
85
+ 'std' => isset( $values['transitionEase'] ) ? $values['transitionEase'] : false,
86
+ ),
87
+ 'transitionSpeed' => array(
88
+ 'type' => 'slider',
89
+ 'id' => 'transitionSpeed',
90
+ 'name' => __( 'Page Transition Speed', 'ditty-news-ticker' ),
91
+ 'help' => __( 'Set the speed of the transition between pages.', 'ditty-news-ticker' ),
92
+ 'suffix' => ' ' . __( 'second(s)', 'ditty-news-ticker' ),
93
+ 'js_options' => array(
94
+ 'min' => 0,
95
+ 'max' => 10,
96
+ 'step' => 0.25,
97
+ ),
98
+ 'std' => isset( $values['transitionSpeed'] ) ? $values['transitionSpeed'] : false,
99
+ ),
100
+ 'heightEase' => array(
101
+ 'type' => 'select',
102
+ 'id' => 'heightEase',
103
+ 'name' => __( 'Height Ease', 'ditty-news-ticker' ),
104
+ 'help' => __( 'Set the easing of the list height.', 'ditty-news-ticker' ),
105
+ 'options' => ditty_ease_array(),
106
+ 'std' => isset( $values['heightEase'] ) ? $values['heightEase'] : false,
107
+ ),
108
+ 'heightSpeed' => array(
109
+ 'type' => 'slider',
110
+ 'id' => 'heightSpeed',
111
+ 'name' => __( 'Height Speed', 'ditty-news-ticker' ),
112
+ 'help' => __( 'Set the speed of the list height.', 'ditty-news-ticker' ),
113
+ 'suffix' => ' ' . __( 'second(s)', 'ditty-news-ticker' ),
114
+ 'js_options' => array(
115
+ 'min' => 0,
116
+ 'max' => 10,
117
+ 'step' => 0.25,
118
+ ),
119
+ 'std' => isset( $values['heightSpeed'] ) ? $values['heightSpeed'] : false,
120
+ ),
121
+ 'autoplay' => array(
122
+ 'type' => 'radio',
123
+ 'id' => 'autoplay',
124
+ 'name' => __( 'Auto Play', 'ditty-news-ticker' ),
125
+ 'help' => __( 'Auto play the slider', 'ditty-news-ticker' ),
126
+ 'inline' => true,
127
+ 'options' => array(
128
+ 0 => __( 'No', 'ditty-news-ticker' ),
129
+ 1 => __( 'Yes', 'ditty-news-ticker' ),
130
+ ),
131
+ 'std' => isset( $values['autoplay'] ) ? $values['autoplay'] : false,
132
+ ),
133
+ 'autoplayPause' => array(
134
+ 'type' => 'checkbox',
135
+ 'id' => 'autoplayPause',
136
+ 'name' => __( 'Pause Autoplay on Hover', 'ditty-news-ticker' ),
137
+ 'label' => __( 'Pause the autoplay on mouse over', 'ditty-news-ticker' ),
138
+ 'help' => __( 'Pause the autoplay on mouse over', 'ditty-news-ticker' ),
139
+ 'std' => isset( $values['autoplayPause'] ) ? $values['autoplayPause'] : false,
140
+ ),
141
+ 'autoplaySpeed' => array(
142
+ 'type' => 'slider',
143
+ 'id' => 'autoplaySpeed',
144
+ 'name' => __( 'Auto Play Speed', 'ditty-news-ticker' ),
145
+ 'help' => __( 'Set the amount of delay between slides', 'ditty-news-ticker' ),
146
+ 'suffix' => ' ' . __( 'seconds', 'ditty-news-ticker' ),
147
+ 'js_options' => array(
148
+ 'min' => 0,
149
+ 'max' => 60,
150
+ 'step' => 0.25,
151
+ ),
152
+ 'std' => isset( $values['autoplay'] ) ? $values['autoplay'] : false,
153
+ ),
154
+ 'shuffle' => array(
155
+ 'type' => 'checkbox',
156
+ 'id' => 'shuffle',
157
+ 'name' => __( 'Shuffle Items', 'ditty-news-ticker' ),
158
+ 'label' => __( 'Randomly shuffle items on each page load', 'ditty-news-ticker' ),
159
+ 'help' => __( 'Randomly shuffle items on each page load', 'ditty-news-ticker' ),
160
+ 'std' => isset( $values['shuffle'] ) ? $values['shuffle'] : false,
161
+ ),
162
+ ),
163
+ ),
164
+ 'initialSettings' => array(
165
+ 'type' => 'group',
166
+ 'id' => 'initSettings',
167
+ 'collapsible' => true,
168
+ 'default_state' => 'collapsed',
169
+ 'multiple_fields' => true,
170
+ 'name' => __( 'Initial Settings', 'ditty-news-ticker' ),
171
+ 'help' => __( 'Configure the initial display settings.', 'ditty-news-ticker' ),
172
+ 'fields' => array(
173
+ 'initTransition' => array(
174
+ 'type' => 'select',
175
+ 'id' => 'initTransition',
176
+ 'name' => __( 'Initial Page Transition', 'ditty-news-ticker' ),
177
+ 'help' => __( 'Set the transition for initial display.', 'ditty-news-ticker' ),
178
+ 'options' => ditty_slider_transitions(),
179
+ 'std' => isset( $values['initTransition'] ) ? $values['initTransition'] : false,
180
+ ),
181
+ 'initTransitionEase' => array(
182
+ 'type' => 'select',
183
+ 'id' => 'initTransitionEase',
184
+ 'name' => __( 'Initial Page Transition Ease', 'ditty-news-ticker' ),
185
+ 'help' => __( 'Set the easing for initial display.', 'ditty-news-ticker' ),
186
+ 'options' => ditty_ease_array(),
187
+ 'std' => isset( $values['initTransitionEase'] ) ? $values['initTransitionEase'] : false,
188
+ ),
189
+ 'initTransitionSpeed' => array(
190
+ 'type' => 'slider',
191
+ 'id' => 'initTransitionSpeed',
192
+ 'name' => __( 'Initial Page Transition Speed', 'ditty-news-ticker' ),
193
+ 'help' => __( 'Set the transition speed for initial display.', 'ditty-news-ticker' ),
194
+ 'suffix' => ' ' . __( 'second(s)', 'ditty-news-ticker' ),
195
+ 'js_options' => array(
196
+ 'min' => 0,
197
+ 'max' => 10,
198
+ 'step' => 0.25,
199
+ ),
200
+ 'std' => isset( $values['initTransitionSpeed'] ) ? $values['initTransitionSpeed'] : false,
201
+ ),
202
+ 'initHeightEase' => array(
203
+ 'type' => 'select',
204
+ 'id' => 'initHeightEase',
205
+ 'name' => __( 'Initial Height Ease', 'ditty-news-ticker' ),
206
+ 'help' => __( 'Set the height easing for initial display.', 'ditty-news-ticker' ),
207
+ 'options' => ditty_ease_array(),
208
+ 'std' => isset( $values['initHeightEase'] ) ? $values['initHeightEase'] : false,
209
+ ),
210
+ 'initHeightSpeed' => array(
211
+ 'type' => 'slider',
212
+ 'id' => 'initHeightSpeed',
213
+ 'name' => __( 'Initial Height Speed', 'ditty-news-ticker' ),
214
+ 'help' => __( 'Set the height speed for initial display.', 'ditty-news-ticker' ),
215
+ 'suffix' => ' ' . __( 'second(s)', 'ditty-news-ticker' ),
216
+ 'js_options' => array(
217
+ 'min' => 0,
218
+ 'max' => 10,
219
+ 'step' => 0.25,
220
+ ),
221
+ 'std' => isset( $values['initHeightSpeed'] ) ? $values['initHeightSpeed'] : false,
222
+ ),
223
+ ),
224
+ ),
225
+ 'arrowSettings' => parent::arrow_settings( $values ),
226
+ 'bulletSettings' => parent::bullet_settings( $values ),
227
+ 'containerStyles' => parent::container_style_settings( $values ),
228
+ 'contentStyles' => parent::content_style_settings( $values ),
229
+ 'pageStyles' => parent::page_style_settings( $values ),
230
+ 'itemStyles' => parent::item_style_settings( $values ),
231
+ // 'importExportSettings' => array(
232
+ // 'type' => 'group',
233
+ // 'id' => 'importExportSettings',
234
+ // 'collapsible' => true,
235
+ // 'default_state' => 'collapsed',
236
+ // 'multiple_fields' => true,
237
+ // 'name' => __( 'Import/Export', 'ditty-news-ticker' ),
238
+ // 'help' => __( 'Import or export the display settings.', 'ditty-news-ticker' ),
239
+ // 'fields' => array(
240
+ // 'importExport' => array(
241
+ // 'type' => 'html',
242
+ // 'id' => 'importExport',
243
+ // 'std' => parent::import_export_settings( $values ),
244
+ // ),
245
+ // ),
246
+ // ),
247
+ );
248
+ return $fields;
249
+ }
250
+
251
+
252
+ /**
253
+ * Set the metabox defaults
254
+ * @access public
255
+ * @since 3.0
256
+ */
257
+ public function default_settings() {
258
+ $defaults = json_decode( '{"spacing":"14","paging":"1","perPage":"10","transition":"fade","transitionEase":"easeInOutQuint","transitionSpeed":"1","heightEase":"easeInOutQuint","heightSpeed":"1","autoplay":"0","autoplaySpeed":"0","arrows":"none","arrowsIconColor":"","arrowsBgColor":"","arrowsPosition":"center","arrowsPadding":{"paddingTop":"","paddingBottom":"20px","paddingLeft":"","paddingRight":""},"bullets":"style1","bulletsColor":"","bulletsColorActive":"","bulletsPosition":"bottomCenter","bulletsSpacing":"2","bulletsPadding":{"paddingTop":"20px","paddingBottom":"","paddingLeft":"","paddingRight":""},"maxWidth":"","bgColor":"","padding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"margin":{"marginTop":"","marginBottom":"","marginLeft":"","marginRight":""},"borderColor":"","borderStyle":"none","borderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"borderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"contentsBgColor":"","contentsPadding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"contentsBorderColor":"","contentsBorderStyle":"none","contentsBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"contentsBorderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"pageBgColor":"","pagePadding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"pageBorderColor":"","pageBorderStyle":"none","pageBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"pageBorderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"itemTextColor":"","itemBgColor":"","itemPadding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"itemBorderColor":"","itemBorderStyle":"none","itemBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"itemBorderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""}}', true );
259
+ return apply_filters( 'ditty_display_default_settings', $defaults, $this->type );
260
+ }
261
+
262
+ /**
263
+ * Return an array of default displays
264
+ * @access private
265
+ * @since 3.0
266
+ */
267
+ public function templates() {
268
+ $defaults = $this->default_settings();
269
+
270
+ $templates = array();
271
+ $templates['default'] = array(
272
+ 'label' => __( 'Default List', 'ditty-news-ticker' ),
273
+ 'description' => __( 'Default list display', 'ditty-news-ticker' ),
274
+ 'settings' => $defaults,
275
+ 'version' => '1.0',
276
+ );
277
+ $templates['default_slider'] = array(
278
+ 'label' => __( 'Default Slider', 'ditty-news-ticker' ),
279
+ 'description' => __( 'Default slider display', 'ditty-news-ticker' ),
280
+ 'settings' => json_decode( '{"spacing":"20","paging":"1","perPage":"1","transition":"slideLeft","transitionEase":"easeInOutQuint","transitionSpeed":"1","heightEase":"easeInOutQuint","heightSpeed":"1","autoplay":"1","autoplaySpeed":"7","arrows":"style1","arrowsIconColor":"","arrowsBgColor":"","arrowsPosition":"center","arrowsPadding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"arrowsStatic":"1","bullets":"style1","bulletsColor":"","bulletsColorActive":"","bulletsPosition":"bottomCenter","bulletsSpacing":"2","bulletsPadding":{"paddingTop":"20px","paddingBottom":"","paddingLeft":"","paddingRight":""},"maxWidth":"","bgColor":"","padding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"margin":{"marginTop":"","marginBottom":"","marginLeft":"auto","marginRight":"auto"},"borderColor":"","borderStyle":"none","borderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"borderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"contentsBgColor":"","contentsPadding":{"paddingTop":"","paddingBottom":"","paddingLeft":"40px","paddingRight":"40px"},"contentsBorderColor":"","contentsBorderStyle":"none","contentsBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"contentsBorderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"pageBgColor":"","pagePadding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"pageBorderColor":"","pageBorderStyle":"none","pageBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"pageBorderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"itemTextColor":"","itemBgColor":"","itemPadding":{"paddingTop":"5px","paddingBottom":"5px","paddingLeft":"5px","paddingRight":"5px"},"itemBorderColor":"","itemBorderStyle":"none","itemBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"itemBorderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""}}', true ),
281
+ 'version' => '1.0',
282
+ );
283
+
284
+ return apply_filters( 'ditty_display_type_templates', $templates, $this->type );
285
+ }
286
+
287
+ }
includes/class-ditty-display-type-ticker.php ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Display Type Ticker Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Display Type Ticker
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Display_Type_Ticker extends Ditty_Display_Type {
13
+
14
+ /**
15
+ * Type
16
+ *
17
+ * @since 3.0
18
+ */
19
+ public $type = 'ticker';
20
+
21
+ /**
22
+ * Setup the fields
23
+ *
24
+ * @access public
25
+ * @since 3.0
26
+ */
27
+ public function fields( $values = array() ) {
28
+ $fields = array(
29
+ 'tickerSettings' => array(
30
+ 'type' => 'group',
31
+ 'id' => 'tickerSettings',
32
+ 'collapsible' => true,
33
+ 'default_state' => 'expanded',
34
+ 'multiple_fields' => true,
35
+ 'name' => __( 'General Settings', 'ditty-news-ticker' ),
36
+ 'help' => __( 'Configure the general functionality settings.', 'ditty-news-ticker' ),
37
+ 'fields' => array(
38
+ 'direction' => array(
39
+ 'type' => 'radio',
40
+ 'id' => 'direction',
41
+ 'name' => __( 'Direction', 'ditty-news-ticker' ),
42
+ 'help' => __( 'Set the direction of the ticker.', 'ditty-news-ticker' ),
43
+ 'options' => array(
44
+ 'left' => __( 'Left', 'ditty-news-ticker' ),
45
+ 'right' => __( 'Right', 'ditty-news-ticker' ),
46
+ 'down' => __( 'Down', 'ditty-news-ticker' ),
47
+ 'up' => __( 'Up', 'ditty-news-ticker' ),
48
+ ),
49
+ 'inline' => true,
50
+ 'std' => isset( $values['direction'] ) ? $values['direction'] : false,
51
+ ),
52
+ 'spacing' => array(
53
+ 'type' => 'slider',
54
+ 'id' => 'spacing',
55
+ 'name' => __( 'Spacing', 'ditty-news-ticker' ),
56
+ 'help' => __( 'Set the amount of space between items (in pixels).', 'ditty-news-ticker' ),
57
+ 'suffix' => 'px',
58
+ 'js_options' => array(
59
+ 'min' => 0,
60
+ 'max' => 100,
61
+ 'step' => 1,
62
+ 'postfix' => 'px',
63
+ ),
64
+ 'std' => isset( $values['spacing'] ) ? $values['spacing'] : false,
65
+ ),
66
+ 'speed' => array(
67
+ 'type' => 'slider',
68
+ 'id' => 'speed',
69
+ 'name' => __( 'Speed', 'ditty-news-ticker' ),
70
+ 'help' => __( 'Set the speed of the ticker.', 'ditty-news-ticker' ),
71
+ 'js_options' => array(
72
+ 'min' => 0,
73
+ 'max' => 50,
74
+ 'step' => 1,
75
+ ),
76
+ 'std' => isset( $values['speed'] ) ? $values['speed'] : false,
77
+ ),
78
+ 'minHeight' => array(
79
+ 'type' => 'text',
80
+ 'id' => 'minHeight',
81
+ 'name' => __( 'Min. Height', 'ditty-news-ticker' ),
82
+ 'help' => __( 'Set the minimum height of the Ditty for vertical scrolling tickers.', 'ditty-news-ticker' ),
83
+ 'std' => isset( $values['minHeight'] ) ? $values['minHeight'] : false,
84
+ ),
85
+ 'maxHeight' => array(
86
+ 'type' => 'text',
87
+ 'id' => 'maxHeight',
88
+ 'name' => __( 'Max. Height', 'ditty-news-ticker' ),
89
+ 'help' => __( 'Set the maximum height of the Ditty for vertical scrolling tickers.', 'ditty-news-ticker' ),
90
+ 'std' => isset( $values['maxHeight'] ) ? $values['maxHeight'] : false,
91
+ ),
92
+ 'hoverPause' => array(
93
+ 'type' => 'checkbox',
94
+ 'id' => 'hoverPause',
95
+ 'name' => __( 'Hover Pause', 'ditty-news-ticker' ),
96
+ 'label' => __( 'Pause the ticker on mouse over', 'ditty-news-ticker' ),
97
+ 'help' => __( 'Pause the ticker on mouse over.', 'ditty-news-ticker' ),
98
+ 'std' => isset( $values['hoverPause'] ) ? $values['hoverPause'] : false,
99
+ ),
100
+ 'scrollInit' => array(
101
+ 'type' => 'radio',
102
+ 'id' => 'scrollInit',
103
+ 'name' => __( 'Initial Display', 'ditty-news-ticker' ),
104
+ 'help' => __( 'Choose how the ticker should initialize.', 'ditty-news-ticker' ),
105
+ 'options' => array(
106
+ 'empty' => __( 'Empty', 'ditty-news-ticker' ),
107
+ 'filled' => __( 'Filled', 'ditty-news-ticker' ),
108
+ ),
109
+ 'inline' => true,
110
+ 'std' => isset( $values['scrollInit'] ) ? $values['scrollInit'] : false,
111
+ ),
112
+ 'scrollDelay' => array(
113
+ 'type' => 'slider',
114
+ 'id' => 'scrollDelay',
115
+ 'name' => __( 'Scroll Delay', 'ditty-news-ticker' ),
116
+ 'help' => __( 'Delay the start of scrolling for filled tickers.', 'ditty-news-ticker' ),
117
+ 'suffix' => ' ' . __( 'seconds', 'ditty-news-ticker' ),
118
+ 'js_options' => array(
119
+ 'min' => 0,
120
+ 'max' => 10,
121
+ 'step' => 0.25,
122
+ ),
123
+ 'std' => isset( $values['scrollDelay'] ) ? $values['scrollDelay'] : false,
124
+ ),
125
+ 'heightEase' => array(
126
+ 'type' => 'select',
127
+ 'id' => 'heightEase',
128
+ 'name' => __( 'Height Ease', 'ditty-news-ticker' ),
129
+ 'help' => __( 'Set the easing of the ticker height.', 'ditty-news-ticker' ),
130
+ 'options' => ditty_ease_array(),
131
+ 'std' => isset( $values['heightEase'] ) ? $values['heightEase'] : false,
132
+ ),
133
+ 'heightSpeed' => array(
134
+ 'type' => 'slider',
135
+ 'id' => 'heightSpeed',
136
+ 'name' => __( 'Height Speed', 'ditty-news-ticker' ),
137
+ 'help' => __( 'Set the speed of the ticker height.', 'ditty-news-ticker' ),
138
+ 'suffix' => ' ' . __( 'second(s)', 'ditty-news-ticker' ),
139
+ 'js_options' => array(
140
+ 'min' => 0,
141
+ 'max' => 10,
142
+ 'step' => 0.25,
143
+ ),
144
+ 'std' => isset( $values['heightSpeed'] ) ? $values['heightSpeed'] : false,
145
+ ),
146
+ 'shuffle' => array(
147
+ 'type' => 'checkbox',
148
+ 'id' => 'shuffle',
149
+ 'name' => __( 'Shuffle Items', 'ditty-news-ticker' ),
150
+ 'label' => __( 'Randomly shuffle items on each page load', 'ditty-news-ticker' ),
151
+ 'help' => __( 'Randomly shuffle items on each page load.', 'ditty-news-ticker' ),
152
+ 'std' => isset( $values['shuffle'] ) ? $values['shuffle'] : false,
153
+ ),
154
+ ),
155
+ ),
156
+ 'containerStyles' => parent::container_style_settings( $values ),
157
+ 'contentStyles' => parent::content_style_settings( $values ),
158
+ 'itemStyles' => parent::item_style_settings( $values, false, array(
159
+ 'itemMaxWidth' => array(
160
+ 'type' => 'text',
161
+ 'id' => 'itemMaxWidth',
162
+ 'name' => __( 'Max Width', 'ditty-news-ticker' ),
163
+ 'help' => __( 'Set a maximum width for items', 'ditty-news-ticker' ),
164
+ 'std' => isset( $values['itemMaxWidth'] ) ? $values['itemMaxWidth'] : false,
165
+ ),
166
+ ) ),
167
+ // 'importExportSettings' => array(
168
+ // 'type' => 'group',
169
+ // 'id' => 'importExportSettings',
170
+ // 'collapsible' => true,
171
+ // 'default_state' => 'collapsed',
172
+ // 'multiple_fields' => true,
173
+ // 'name' => __( 'Import/Export', 'ditty-news-ticker' ),
174
+ // 'help' => __( 'Import or export the display settings.', 'ditty-news-ticker' ),
175
+ // 'fields' => array(
176
+ // 'importExport' => array(
177
+ // 'type' => 'html',
178
+ // 'id' => 'importExport',
179
+ // 'std' => parent::import_export_settings( $values ),
180
+ // ),
181
+ // ),
182
+ // ),
183
+ );
184
+ return $fields;
185
+ }
186
+
187
+ /**
188
+ * Set the metabox defaults
189
+ * @access public
190
+ * @since 3.0
191
+ */
192
+ public function default_settings() {
193
+
194
+ $defaults = json_decode( '{"direction":"left","spacing":"25","speed":"10","hoverPause":"1","scrollInit":"empty","scrollDelay":"3","heightEase":"easeInOutQuint","heightSpeed":"1.5","maxWidth":"","bgColor":"","padding":{"paddingTop":"5px","paddingBottom":"5px","paddingLeft":"5px","paddingRight":"5px"},"margin":{"marginTop":"","marginBottom":"","marginLeft":"","marginRight":""},"borderColor":"","borderStyle":"none","borderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"borderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"contentsBgColor":"rgba(255, 255, 255, 0.5)","contentsPadding":{"paddingTop":"10px","paddingBottom":"10px","paddingLeft":"10px","paddingRight":"10px"},"contentsBorderColor":"","contentsBorderStyle":"none","contentsBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"contentsBorderRadius":{"borderTopLeftRadius":"3px","borderTopRightRadius":"3px","borderBottomLeftRadius":"3px","borderBottomRightRadius":"3px"},"itemTextColor":"","itemBgColor":"","itemPadding":{"paddingTop":"","paddingBottom":"","paddingLeft":"","paddingRight":""},"itemBorderColor":"","itemBorderStyle":"none","itemBorderWidth":{"borderTopWidth":"","borderBottomWidth":"","borderLeftWidth":"","borderRightWidth":""},"itemBorderRadius":{"borderTopLeftRadius":"","borderTopRightRadius":"","borderBottomLeftRadius":"","borderBottomRightRadius":""},"itemMaxWidth":"400px"}', true );
195
+
196
+ return apply_filters( 'ditty_display_default_settings', $defaults, $this->type );
197
+ }
198
+
199
+ /**
200
+ * Return an array of default displays
201
+ * @access private
202
+ * @since 3.0
203
+ */
204
+ public function templates() {
205
+ $defaults = $this->default_settings();
206
+
207
+ $templates = array();
208
+ $templates['default'] = array(
209
+ 'label' => __( 'Default Ticker', 'ditty-news-ticker' ),
210
+ 'description' => __( 'Default ticker display', 'ditty-news-ticker' ),
211
+ 'settings' => $defaults,
212
+ 'version' => '1.0',
213
+ );
214
+ return apply_filters( 'ditty_display_type_templates', $templates, $this->type );
215
+ }
216
+
217
+ }
includes/class-ditty-display-type.php ADDED
@@ -0,0 +1,574 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Display Type Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Display Type
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Display_Type {
13
+
14
+ /**
15
+ * Type
16
+ *
17
+ * @since 3.0
18
+ */
19
+ public $type = 'none';
20
+
21
+ /**
22
+ * Label
23
+ *
24
+ * @since 3.0
25
+ */
26
+ public $label;
27
+
28
+ /**
29
+ * Fields
30
+ *
31
+ * @since 3.0
32
+ */
33
+ public $icon;
34
+
35
+ /**
36
+ * Description
37
+ *
38
+ * @since 3.0
39
+ */
40
+ public $description;
41
+
42
+ /**
43
+ * Metabox
44
+ *
45
+ * @since 3.0
46
+ */
47
+ public $metabox;
48
+
49
+ /**
50
+ * Templates
51
+ *
52
+ * @since 3.0
53
+ */
54
+ public $templates;
55
+
56
+
57
+ /**
58
+ * Get things started
59
+ * @access public
60
+ * @since 3.0
61
+ */
62
+ public function __construct() {
63
+
64
+ $display_types = ditty_display_types();
65
+ if ( isset( $display_types[$this->type] ) ) {
66
+ $this->label = $display_types[$this->type]['label'];
67
+ $this->icon = $display_types[$this->type]['icon'];
68
+ $this->description = $display_types[$this->type]['description'];
69
+ }
70
+ $this->metabox = $this->metabox();
71
+ $this->templates = $this->templates();
72
+ }
73
+
74
+ /**
75
+ * Return the type
76
+ * @access public
77
+ * @since 3.0
78
+ * @return string $type
79
+ */
80
+ public function get_type() {
81
+ return $this->type;
82
+ }
83
+
84
+ /**
85
+ * Return the label
86
+ * @access public
87
+ * @since 3.0
88
+ * @return string $label
89
+ */
90
+ public function get_label() {
91
+ return $this->label;
92
+ }
93
+
94
+ /**
95
+ * Return the icon
96
+ * @access public
97
+ * @since 3.0
98
+ * @return string $icon
99
+ */
100
+ public function get_icon() {
101
+ return $this->icon;
102
+ }
103
+
104
+ /**
105
+ * Return the description
106
+ * @access public
107
+ * @since 3.0
108
+ * @return string $description
109
+ *
110
+ */
111
+ public function get_description() {
112
+ return $this->description;
113
+ }
114
+
115
+ /**
116
+ * Setup the fields metabox
117
+ * @access public
118
+ * @since 3.0
119
+ */
120
+ public function metabox() {
121
+ }
122
+
123
+ /**
124
+ * Setup the display settings
125
+ * @access public
126
+ * @since 3.0
127
+ */
128
+ public function settings( $display_values = false, $action = 'render' ) {
129
+ $values = $this->get_values( $display_values );
130
+ $fields = $this->fields( $values );
131
+ ditty_fields( $fields, $values, $action );
132
+ }
133
+
134
+ /**
135
+ * Update values sent from the editor
136
+ * @access public
137
+ * @since 3.0
138
+ */
139
+ // TODO: Sanitize display meta
140
+ public function sanitize_settings( $values ) {
141
+ $fields = $this->fields();
142
+ return ditty_sanitize_fields( $fields, $values, "ditty_display_type_{$this->get_type()}" );
143
+ }
144
+
145
+ /**
146
+ * Return an array of default displays
147
+ * @access private
148
+ * @since 3.0
149
+ */
150
+ public function templates() {
151
+ return array();
152
+ }
153
+
154
+ /**
155
+ * Return the templates array
156
+ * @access public
157
+ * @since 3.0
158
+ */
159
+ public function get_templates() {
160
+ return $this->templates;
161
+ }
162
+
163
+ /**
164
+ * Return an array of default displays
165
+ * @access public
166
+ * @since 3.0
167
+ */
168
+ public function get_template( $id ) {
169
+ if ( isset( $this->templates[$id] ) ) {
170
+ return $this->templates[$id];
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Get values to populate the metabox
176
+ *
177
+ * @access public
178
+ * @since 3.0
179
+ */
180
+ public function get_values( $display_values=false ) {
181
+ $defaults = $this->default_settings();
182
+ if ( ! $display_values ) {
183
+ return $defaults;
184
+ }
185
+ $values = wp_parse_args( $display_values, $defaults );
186
+ unset( $values['draft_values'] );
187
+ return $values;
188
+ }
189
+
190
+ /**
191
+ * Return the display styles
192
+ * @access public
193
+ * @since 3.0
194
+ * @return int $id
195
+ */
196
+ public function import_export_settings( $values ) {
197
+ $html = '';
198
+ $html .= '<div class="ditty-editor__import-export ditty-editor__import-export--display-type">';
199
+ $html .= '<textarea class="ditty-editor__import-export__field">';
200
+ $html .= json_encode( $values );
201
+ $html .= '</textarea>';
202
+ $html .= '<a class="ditty-editor__import-export__update ditty-button" href="#">' . __( 'Update', 'ditty-news-ticker' ) . '</a>';
203
+ $html .= '</div>';
204
+ return $html;
205
+ }
206
+
207
+ /**
208
+ * Return arrow settings
209
+ *
210
+ * @since 3.0
211
+ * @var $settings array
212
+ */
213
+ public function arrow_settings( $values, $id = 'arrowSettings' ) {
214
+ $settings = array(
215
+ 'type' => 'group',
216
+ 'id' => $id,
217
+ 'collapsible' => true,
218
+ 'default_state' => 'collapsed',
219
+ 'multiple_fields' => true,
220
+ 'name' => __( 'Arrow Navigation Settings', 'ditty-news-ticker' ),
221
+ 'help' => __( 'Configure arrow navigation settings.', 'ditty-news-ticker' ),
222
+ 'fields' => array(
223
+ 'arrows' => array(
224
+ 'type' => 'select',
225
+ 'id' => 'arrows',
226
+ 'name' => __( 'Arrows', 'ditty-news-ticker' ),
227
+ 'help' => __( 'Set the arrow navigation style', 'ditty-news-ticker' ),
228
+ 'options' => array(
229
+ 'none' => __( 'Hide', 'ditty-news-ticker' ),
230
+ 'style1' => __( 'Show', 'ditty-news-ticker' ),
231
+ ),
232
+ 'std' => isset( $values['arrows'] ) ? $values['arrows'] : false,
233
+ ),
234
+ 'arrowsIconColor' => array(
235
+ 'type' => 'color',
236
+ 'id' => 'arrowsIconColor',
237
+ 'name' => __( 'Arrows Icon Color', 'ditty-news-ticker' ),
238
+ 'help' => __( 'Add a custom icon color to the arrows', 'ditty-news-ticker' ),
239
+ 'std' => isset( $values['arrowsIconColor'] ) ? $values['arrowsIconColor'] : false,
240
+ ),
241
+ 'arrowsBgColor' => array(
242
+ 'type' => 'color',
243
+ 'id' => 'arrowsBgColor',
244
+ 'name' => __( 'Arrows Background Color', 'ditty-news-ticker' ),
245
+ 'help' => __( 'Add a custom background color to the arrows', 'ditty-news-ticker' ),
246
+ 'std' => isset( $values['arrowsBgColor'] ) ? $values['arrowsBgColor'] : false,
247
+ ),
248
+ 'arrowsPosition' => array(
249
+ 'type' => 'select',
250
+ 'id' => 'arrowsPosition',
251
+ 'name' => __( 'Arrows Position', 'ditty-news-ticker' ),
252
+ 'help' => __( 'Set the position of the arrows', 'ditty-news-ticker' ),
253
+ 'options' => array(
254
+ 'flexStart' => __( 'Top', 'ditty-news-ticker' ),
255
+ 'center' => __( 'Center', 'ditty-news-ticker' ),
256
+ 'flexEnd' => __( 'Bottom', 'ditty-news-ticker' ),
257
+ ),
258
+ 'std' => isset( $values['arrowsPosition'] ) ? $values['arrowsPosition'] : false,
259
+ ),
260
+ 'arrowsPadding' => array(
261
+ 'type' => 'spacing',
262
+ 'id' => 'arrowsPadding',
263
+ 'name' => __( 'Arrows Padding', 'ditty-news-ticker' ),
264
+ 'help' => __( 'Add padding to the arrows container', 'ditty-news-ticker' ),
265
+ 'std' => isset( $values['arrowsPadding'] ) ? $values['arrowsPadding'] : false,
266
+ ),
267
+ 'arrowsStatic' => array(
268
+ 'type' => 'checkbox',
269
+ 'id' => 'arrowsStatic',
270
+ 'name' => __( 'Arrows Visibility', 'ditty-news-ticker' ),
271
+ 'label' => __( 'Keep arrows visible at all times', 'ditty-news-ticker' ),
272
+ 'help' => __( 'Keep arrows visible at all times', 'ditty-news-ticker' ),
273
+ 'std' => isset( $values['arrowsStatic'] ) ? $values['arrowsStatic'] : false,
274
+ ),
275
+ ),
276
+ );
277
+ return $settings;
278
+ }
279
+
280
+ /**
281
+ * Return bullet settings
282
+ *
283
+ * @since 3.0
284
+ * @var $settings array
285
+ */
286
+ public function bullet_settings( $values, $id = 'bulletSettings' ) {
287
+ $settings = array(
288
+ 'type' => 'group',
289
+ 'id' => $id,
290
+ 'collapsible' => true,
291
+ 'default_state' => 'collapsed',
292
+ 'multiple_fields' => true,
293
+ 'name' => __( 'Bullet Navigation Settings', 'ditty-news-ticker' ),
294
+ 'help' => __( 'Configure bullet navigation settings.', 'ditty-news-ticker' ),
295
+ 'fields' => array(
296
+ 'bullets' => array(
297
+ 'type' => 'select',
298
+ 'id' => 'bullets',
299
+ 'name' => __( 'Bullets', 'ditty-news-ticker' ),
300
+ 'help' => __( 'Set the bullet navigation style', 'ditty-news-ticker' ),
301
+ 'options' => array(
302
+ 'none' => __( 'Hide', 'ditty-news-ticker' ),
303
+ 'style1' => __( 'Show', 'ditty-news-ticker' ),
304
+ ),
305
+ 'std' => isset( $values['bullets'] ) ? $values['bullets'] : false,
306
+ ),
307
+ 'bulletsColor' => array(
308
+ 'type' => 'color',
309
+ 'id' => 'bulletsColor',
310
+ 'name' => __( 'Bullets Color', 'ditty-news-ticker' ),
311
+ 'help' => __( 'Add a custom color to the bullets', 'ditty-news-ticker' ),
312
+ 'std' => isset( $values['bulletsColor'] ) ? $values['bulletsColor'] : false,
313
+ ),
314
+ 'bulletsColorActive' => array(
315
+ 'type' => 'color',
316
+ 'id' => 'bulletsColorActive',
317
+ 'name' => __( 'Bullets Active Color', 'ditty-news-ticker' ),
318
+ 'help' => __( 'Add a custom color to the active bullet', 'ditty-news-ticker' ),
319
+ 'std' => isset( $values['bulletsColorActive'] ) ? $values['bulletsColorActive'] : false,
320
+ ),
321
+ 'bulletsPosition' => array(
322
+ 'type' => 'select',
323
+ 'id' => 'bulletsPosition',
324
+ 'name' => __( 'Bullets Position', 'ditty-news-ticker' ),
325
+ 'help' => __( 'Set the position of the bullets', 'ditty-news-ticker' ),
326
+ 'options' => array(
327
+ 'topLeft' => __( 'Top Left', 'ditty-news-ticker' ),
328
+ 'topCenter' => __( 'Top Center', 'ditty-news-ticker' ),
329
+ 'topRight' => __( 'Top Right', 'ditty-news-ticker' ),
330
+ 'bottomLeft' => __( 'Bottom Left', 'ditty-news-ticker' ),
331
+ 'bottomCenter' => __( 'Bottom Center', 'ditty-news-ticker' ),
332
+ 'bottomRight' => __( 'Bottom Right', 'ditty-news-ticker' ),
333
+ ),
334
+ 'std' => isset( $values['bulletsPosition'] ) ? $values['bulletsPosition'] : false,
335
+ ),
336
+ 'bulletsSpacing' => array(
337
+ 'type' => 'slider',
338
+ 'id' => 'bulletsSpacing',
339
+ 'name' => __( 'Bullets Spacing', 'ditty-news-ticker' ),
340
+ 'help' => __( 'Set the amount of space between bullets (in pixels).', 'ditty-news-ticker' ),
341
+ 'suffix' => 'px',
342
+ 'js_options' => array(
343
+ 'min' => 0,
344
+ 'max' => 50,
345
+ 'step' => 1,
346
+ ),
347
+ 'std' => isset( $values['bulletsSpacing'] ) ? $values['bulletsSpacing'] : false,
348
+ ),
349
+ 'bulletsPadding' => array(
350
+ 'type' => 'spacing',
351
+ 'id' => 'bulletsPadding',
352
+ 'name' => __( 'Bullets Padding', 'ditty-news-ticker' ),
353
+ 'help' => __( 'Add padding to the bullets container', 'ditty-news-ticker' ),
354
+ 'std' => isset( $values['bulletsPadding'] ) ? $values['bulletsPadding'] : false,
355
+ ),
356
+ ),
357
+ );
358
+ return $settings;
359
+ }
360
+
361
+ /**
362
+ * Return border settings
363
+ *
364
+ * @since 3.0
365
+ * @var $settings array
366
+ */
367
+ public function border_settings( $values, $prefix = '' ) {
368
+ $settings = array();
369
+ $prefixed = ( '' != $prefix ) ? "{$prefix}Border" : 'border';
370
+ $settings["{$prefixed}Color"] = array(
371
+ 'type' => 'color',
372
+ 'id' => "{$prefixed}Color",
373
+ 'name' => __( 'Border Color', 'ditty-news-ticker' ),
374
+ 'std' => isset( $values["{$prefixed}Color"] ) ? $values["{$prefixed}Color"] : false,
375
+ );
376
+ $settings["{$prefixed}Style"] = array(
377
+ 'type' => 'select',
378
+ 'id' => "{$prefixed}Style",
379
+ 'name' => __( 'Border Style', 'ditty-news-ticker' ),
380
+ 'help' => __( 'A border style must be set for a border to render', 'ditty-news-ticker' ),
381
+ 'options' => ditty_border_styles_array(),
382
+ 'std' => isset( $values["{$prefixed}Style"] ) ? $values["{$prefixed}Style"] : false,
383
+ );
384
+ $settings["{$prefixed}Width"] = array(
385
+ 'type' => 'spacing',
386
+ 'id' => "{$prefixed}Width",
387
+ 'name' => __( 'Border Width', 'ditty-news-ticker' ),
388
+ 'options' => array(
389
+ 'borderTopWidth' => __( 'Top', 'ditty-news-ticker' ),
390
+ 'borderBottomWidth' => __( 'Bottom', 'ditty-news-ticker' ),
391
+ 'borderLeftWidth' => __( 'Left', 'ditty-news-ticker' ),
392
+ 'borderRightWidth' => __( 'Right', 'ditty-news-ticker' ),
393
+ ),
394
+ 'std' => isset( $values["{$prefixed}Width"] ) ? $values["{$prefixed}Width"] : false,
395
+ );
396
+ $settings["{$prefixed}Radius"] = array(
397
+ 'type' => 'radius',
398
+ 'id' => "{$prefixed}Radius",
399
+ 'name' => __( 'Border Radius', 'ditty-news-ticker' ),
400
+ 'std' => isset( $values["{$prefixed}Radius"] ) ? $values["{$prefixed}Radius"] : false,
401
+ );
402
+ return $settings;
403
+ }
404
+
405
+ /**
406
+ * Return container style settings
407
+ *
408
+ * @since 3.0
409
+ * @var $settings array
410
+ */
411
+ public function container_style_settings( $values, $id = 'containerStyles', $extra_fields = array() ) {
412
+ $base_fields = array(
413
+ 'maxWidth' => array(
414
+ 'type' => 'text',
415
+ 'id' => 'maxWidth',
416
+ 'name' => __( 'Max. Width', 'ditty-news-ticker' ),
417
+ 'help' => __( 'Set a maximum width for the container', 'ditty-news-ticker' ),
418
+ 'std' => isset( $values['maxWidth'] ) ? $values['maxWidth'] : false,
419
+ ),
420
+ 'bgColor' => array(
421
+ 'type' => 'color',
422
+ 'id' => 'bgColor',
423
+ 'name' => __( 'Background Color', 'ditty-news-ticker' ),
424
+ 'std' => isset( $values['bgColor'] ) ? $values['bgColor'] : false,
425
+ ),
426
+ 'padding' => array(
427
+ 'type' => 'spacing',
428
+ 'id' => 'padding',
429
+ 'name' => __( 'Padding', 'ditty-news-ticker' ),
430
+ 'std' => isset( $values['padding'] ) ? $values['padding'] : false,
431
+ ),
432
+ 'margin' => array(
433
+ 'type' => 'spacing',
434
+ 'id' => 'margin',
435
+ 'name' => __( 'Margin', 'ditty-news-ticker' ),
436
+ 'options' => array(
437
+ 'marginTop' => __( 'Top', 'ditty-news-ticker' ),
438
+ 'marginBottom' => __( 'Bottom', 'ditty-news-ticker' ),
439
+ 'marginLeft' => __( 'Left', 'ditty-news-ticker' ),
440
+ 'marginRight' => __( 'Right', 'ditty-news-ticker' ),
441
+ ),
442
+ 'std' => isset( $values['margin'] ) ? $values['margin'] : false,
443
+ ),
444
+ );
445
+ $border_fields = $this->border_settings( $values );
446
+ $fields = array_merge( $base_fields, $border_fields, $extra_fields );
447
+ $settings = array(
448
+ 'type' => 'group',
449
+ 'id' => $id,
450
+ 'collapsible' => true,
451
+ 'default_state' => 'collapsed',
452
+ 'multiple_fields' => true,
453
+ 'name' => __( 'Container Styles', 'ditty-news-ticker' ),
454
+ 'help' => __( 'Add custom container styles.', 'ditty-news-ticker' ),
455
+ 'fields' => $fields,
456
+ );
457
+ return $settings;
458
+ }
459
+
460
+ /**
461
+ * Return content style settings
462
+ *
463
+ * @since 3.0
464
+ * @var $settings array
465
+ */
466
+ public function content_style_settings( $values, $id = 'content_styles', $extra_fields = array() ) {
467
+ $base_fields = array(
468
+ 'contentsBgColor' => array(
469
+ 'type' => 'color',
470
+ 'id' => 'contentsBgColor',
471
+ 'name' => __( 'Background Color', 'ditty-news-ticker' ),
472
+ 'std' => isset( $values['contentsBgColor'] ) ? $values['contentsBgColor'] : false,
473
+ ),
474
+ 'contentsPadding' => array(
475
+ 'type' => 'spacing',
476
+ 'id' => 'contentsPadding',
477
+ 'name' => __( 'Padding', 'ditty-news-ticker' ),
478
+ 'std' => isset( $values['contentsPadding'] ) ? $values['contentsPadding'] : false,
479
+ ),
480
+ );
481
+ $border_fields = $this->border_settings( $values, 'contents' );
482
+ $fields = array_merge( $base_fields, $border_fields, $extra_fields );
483
+ $settings = array(
484
+ 'type' => 'group',
485
+ 'id' => $id,
486
+ 'collapsible' => true,
487
+ 'default_state' => 'collapsed',
488
+ 'multiple_fields' => true,
489
+ 'name' => __( 'Content Styles', 'ditty-news-ticker' ),
490
+ 'help' => __( 'Add custom content styles.', 'ditty-news-ticker' ),
491
+ 'fields' => $fields,
492
+ );
493
+ return $settings;
494
+ }
495
+
496
+ /**
497
+ * Return page style settings
498
+ *
499
+ * @since 3.0
500
+ * @var $settings array
501
+ */
502
+ public function page_style_settings( $values, $id = 'pageStyles', $extra_fields = array() ) {
503
+ $base_fields = array(
504
+ 'pageBgColor' => array(
505
+ 'type' => 'color',
506
+ 'id' => 'pageBgColor',
507
+ 'name' => __( 'Background Color', 'ditty-news-ticker' ),
508
+ 'std' => isset( $values['pageBgColor']) ? $values['pageBgColor'] : false,
509
+ ),
510
+ 'pagePadding' => array(
511
+ 'type' => 'spacing',
512
+ 'id' => 'pagePadding',
513
+ 'name' => __( 'Padding', 'ditty-news-ticker' ),
514
+ 'std' => isset( $values['pagePadding'] ) ? $values['pagePadding'] : false,
515
+ ),
516
+ );
517
+ $border_fields = $this->border_settings( $values, 'page' );
518
+ $fields = array_merge( $base_fields, $border_fields, $extra_fields );
519
+ $settings = array(
520
+ 'type' => 'group',
521
+ 'id' => $id,
522
+ 'collapsible' => true,
523
+ 'default_state' => 'collapsed',
524
+ 'multiple_fields' => true,
525
+ 'name' => __( 'Page Styles', 'ditty-news-ticker' ),
526
+ 'help' => __( 'Add custom page styles.', 'ditty-news-ticker' ),
527
+ 'fields' => $fields,
528
+ );
529
+ return $settings;
530
+ }
531
+
532
+ /**
533
+ * Return item style settings
534
+ *
535
+ * @since 3.0
536
+ * @var $settings array
537
+ */
538
+ public function item_style_settings( $values, $id = 'itemStyles', $extra_fields = array() ) {
539
+ $base_fields = array(
540
+ 'itemTextColor' => array(
541
+ 'type' => 'color',
542
+ 'id' => 'itemTextColor',
543
+ 'name' => __( 'Text Color', 'ditty-news-ticker' ),
544
+ 'std' => isset( $values['itemTextColor'] ) ? $values['itemTextColor'] : false,
545
+ ),
546
+ 'itemBgColor' => array(
547
+ 'type' => 'color',
548
+ 'id' => 'itemBgColor',
549
+ 'name' => __( 'Background Color', 'ditty-news-ticker' ),
550
+ 'std' => isset( $values['itemBgColor'] ) ? $values['itemBgColor'] : false,
551
+ ),
552
+ 'itemPadding' => array(
553
+ 'type' => 'spacing',
554
+ 'id' => 'itemPadding',
555
+ 'name' => __( 'Padding', 'ditty-news-ticker' ),
556
+ 'std' => isset( $values['itemPadding'] ) ? $values['itemPadding'] : false,
557
+ ),
558
+ );
559
+ $border_fields = $this->border_settings( $values, 'item' );
560
+ $fields = array_merge( $base_fields, $border_fields, $extra_fields );
561
+ $settings = array(
562
+ 'type' => 'group',
563
+ 'id' => $id,
564
+ 'collapsible' => true,
565
+ 'default_state' => 'collapsed',
566
+ 'multiple_fields' => true,
567
+ 'name' => __( 'Item Styles', 'ditty-news-ticker' ),
568
+ 'help' => __( 'Add custom item styles.', 'ditty-news-ticker' ),
569
+ 'fields' => $fields,
570
+ );
571
+ return $settings;
572
+ }
573
+
574
+ }
includes/class-ditty-display.php ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Display Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Display
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Display {
13
+
14
+ private $display_id;
15
+ private $display_object;
16
+ private $display_type;
17
+ private $icon;
18
+ private $label;
19
+ private $description;
20
+ private $settings;
21
+ private $version;
22
+
23
+ /**
24
+ * Get things started
25
+ * @access public
26
+ * @since 3.0
27
+ */
28
+ public function __construct( $display_id ) {
29
+
30
+ // If this is a new display
31
+ if ( false !== strpos( $display_id, 'new-' ) ) {
32
+ $this->parse_draft_data( $display_id );
33
+
34
+ // Else, this is an existing display
35
+ } elseif ( get_post( $display_id ) ) {
36
+ $this->construct_from_id( $display_id );
37
+ $this->parse_draft_data( $display_id );
38
+ }
39
+ $this->construct_display_object_data();
40
+ return $this;
41
+ }
42
+
43
+ /**
44
+ * Parse the draft data
45
+ * @access public
46
+ * @since 3.0
47
+ * @return int $id
48
+ */
49
+ public function parse_draft_data( $display_id ) {
50
+ $this->display_id = $display_id;
51
+ $draft_values = ditty_draft_display_get( $display_id );
52
+ if ( ! $draft_values ) {
53
+ return false;
54
+ }
55
+ $this->label = isset( $draft_values['label'] ) ? $draft_values['label'] : $this->label;
56
+ $this->description = isset( $draft_values['description'] ) ? $draft_values['description'] : $this->description;
57
+ $this->display_type = isset( $draft_values['display_type'] ) ? $draft_values['display_type'] : $this->display_type;
58
+ $this->settings = isset( $draft_values['settings'] ) ? $draft_values['settings'] : $this->settings;
59
+ $this->version = isset( $draft_values['version'] ) ? $draft_values['version'] : $this->version;
60
+ }
61
+
62
+ /**
63
+ * Construct class from ID
64
+ * @access private
65
+ * @since 3.0
66
+ */
67
+ private function construct_from_id( $display_id ) {
68
+ $this->display_id = $display_id;
69
+ $this->display_type = get_post_meta( $display_id, '_ditty_display_type', true );
70
+ $this->label = get_the_title( $display_id );
71
+ $this->description = get_post_meta( $display_id, '_ditty_display_description', true );
72
+ $this->settings = get_post_meta( $display_id, '_ditty_display_settings', true );
73
+ $this->version = get_post_meta( $display_id, '_ditty_display_version', true );
74
+ }
75
+
76
+ /**
77
+ * Construct the type object data
78
+ * @access public
79
+ * @since 3.0
80
+ */
81
+ public function construct_display_object_data() {
82
+ if ( ! $display_object = $this->get_display_object() ) {
83
+ return false;
84
+ }
85
+ $this->icon = $display_object->get_icon();
86
+ }
87
+
88
+ /**
89
+ * Return the display object
90
+ * @access public
91
+ * @since 3.0
92
+ * @return int $display_object
93
+ */
94
+ public function get_display_object() {
95
+ if ( empty( $this->display_object ) ) {
96
+ $this->display_object = ditty_display_type_object( $this->display_type );
97
+ }
98
+ return $this->display_object;
99
+ }
100
+
101
+ /**
102
+ * Return the base id
103
+ * @access public
104
+ * @since 3.0
105
+ * @return int $id
106
+ */
107
+ public function get_display_id() {
108
+ return $this->display_id;
109
+ }
110
+
111
+ /**
112
+ * Set the base id
113
+ * @access public
114
+ * @since 3.0
115
+ * @return int $id
116
+ */
117
+ public function set_display_id( $display_id ) {
118
+ $this->display_id = $display_id;
119
+ return $this->display_id;
120
+ }
121
+
122
+ /**
123
+ * Return the display type
124
+ * @access public
125
+ * @since 3.0
126
+ * @return int $id
127
+ */
128
+ public function get_display_type() {
129
+ return $this->display_type;
130
+ }
131
+
132
+ /**
133
+ * Return the display icon
134
+ * @access public
135
+ * @since 3.0
136
+ * @return int $id
137
+ */
138
+ public function get_icon() {
139
+ return $this->icon;
140
+ }
141
+
142
+ /**
143
+ * Return the display label
144
+ * @access public
145
+ * @since 3.0
146
+ * @return string $label
147
+ */
148
+ public function get_label() {
149
+ return $this->label;
150
+ }
151
+
152
+ /**
153
+ * Set the display label
154
+ * @access public
155
+ * @since 3.0
156
+ * @return int $id
157
+ */
158
+ public function set_label( $label ) {
159
+ if ( $label != $this->label ) {
160
+ $sanitized_label = sanitize_text_field( $label );
161
+ $this->label = $sanitized_label;
162
+ return $this->label;
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Return the display description
168
+ * @access public
169
+ * @since 3.0
170
+ * @return int $id
171
+ */
172
+ public function get_description() {
173
+ return $this->description;
174
+ }
175
+
176
+ /**
177
+ * Return the display settings
178
+ * @access public
179
+ * @since 3.0
180
+ * @return int $id
181
+ */
182
+ public function get_settings() {
183
+ return $this->settings;
184
+ }
185
+
186
+ /**
187
+ * Return the version
188
+ * @access public
189
+ * @since 3.0
190
+ * @return string $version
191
+ */
192
+ public function get_version() {
193
+ return $this->version;
194
+ }
195
+
196
+ /**
197
+ * Set the version
198
+ * @access public
199
+ * @since 3.0
200
+ * @return string $version
201
+ */
202
+ public function set_version( $version ) {
203
+ $this->version = $version;
204
+ return $this->version;
205
+ }
206
+
207
+ /**
208
+ * Return the display values
209
+ * @access public
210
+ * @since 3.0
211
+ * @return int $id
212
+ */
213
+ public function get_values() {
214
+ $values = $this->get_settings();
215
+ if ( ! is_array( $values ) ) {
216
+ return array();
217
+ }
218
+ return $values;
219
+ }
220
+
221
+ /**
222
+ * Update the display settings
223
+ * @access public
224
+ * @since 3.0
225
+ * @return int $id
226
+ */
227
+ public function update_settings( $settings = array() ) {
228
+ if ( ! is_array( $settings ) ) {
229
+ return false;
230
+ }
231
+ $display_object = $this->get_display_object();
232
+ $sanitized_settings = $display_object->sanitize_settings( $settings );
233
+ $this->settings = $sanitized_settings;
234
+ return $this->settings;
235
+ }
236
+
237
+ /**
238
+ * Return the display metabox
239
+ * @access public
240
+ * @since 3.0
241
+ * @return int $id
242
+ */
243
+ public function object_settings() {
244
+ $display_object = $this->get_display_object();
245
+ return $display_object->settings( $this->get_values() );
246
+ }
247
+
248
+ /**
249
+ * Setup the display classes
250
+ * @access public
251
+ * @since 3.0
252
+ * @return string $classes
253
+ */
254
+ public function get_editor_classes() {
255
+ $classes = array();
256
+ $classes[] = 'ditty-data-list__item';
257
+ $classes[] = 'ditty-editor-display';
258
+ $classes[] = 'ditty-editor-display--' . esc_attr( $this->display_type );
259
+ $classes = apply_filters( 'ditty_display_classes', $classes );
260
+ return implode( ' ', $classes );
261
+ }
262
+
263
+ /**
264
+ * Render the admin edit row
265
+ * @access public
266
+ * @since 3.0
267
+ * @return html
268
+ */
269
+ public function render_editor_list_item( $render='echo' ) {
270
+ if ( 'return' == $render ) {
271
+ ob_start();
272
+ }
273
+ $atts = array(
274
+ 'id' => 'ditty-editor-display--' . $this->get_display_id(),
275
+ 'class' => $this->get_editor_classes(),
276
+ 'data-display_id' => $this->get_display_id(),
277
+ 'data-display_type' => $this->get_display_type(),
278
+ );
279
+ ?>
280
+ <div <?php echo ditty_attr_to_html( $atts ); ?>>
281
+ <?php do_action( 'ditty_editor_display_elements', $this ); ?>
282
+ </div>
283
+ <?php
284
+ if ( 'return' == $render ) {
285
+ return trim( ob_get_clean() );
286
+ }
287
+ }
288
+
289
+ }
includes/class-ditty-displays.php ADDED
@@ -0,0 +1,913 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Displays Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Displays
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Displays {
13
+
14
+ private $new_displays;
15
+
16
+ /**
17
+ * Get things started
18
+ * @access public
19
+ * @since 3.0
20
+ */
21
+ public function __construct() {
22
+
23
+ // WP metabox hooks
24
+ add_action( 'add_meta_boxes', array( $this, 'metaboxes' ) );
25
+ add_action( 'save_post', array( $this, 'metabox_save' ) );
26
+ add_action( 'wp_ajax_ditty_admin_display_update', array( $this, 'admin_update_ajax' ) );
27
+
28
+ // General hooks
29
+ add_filter( 'post_row_actions', array( $this, 'modify_list_row_actions' ), 10, 2 );
30
+ add_action( 'ditty_editor_update', array( $this, 'update_drafts' ), 10, 2 );
31
+ add_filter( 'ditty_post_meta_update', array( $this, 'modify_ditty_draft_meta'), 10, 3 );
32
+
33
+ // Editior elements
34
+ add_action( 'ditty_editor_tabs', array( $this, 'editor_tab' ), 10, 2 );
35
+ add_action( 'ditty_editor_panels', array( $this, 'editor_panel' ), 10, 2 );
36
+
37
+ // Display elements
38
+ add_action( 'ditty_editor_display_elements', array( $this, 'editor_display_icon' ), 5 );
39
+ add_action( 'ditty_editor_display_elements', array( $this, 'editor_display_label' ), 10 );
40
+ add_action( 'ditty_editor_display_elements', array( $this, 'editor_display_edit' ), 15 );
41
+ add_action( 'ditty_editor_display_elements', array( $this, 'editor_display_clone' ), 20 );
42
+ add_action( 'ditty_editor_display_elements', array( $this, 'editor_display_delete' ), 25 );
43
+
44
+ // Ajax
45
+ add_action( 'wp_ajax_ditty_editor_select_display', array( $this, 'editor_select_display_ajax' ) );
46
+ add_action( 'wp_ajax_nopriv_ditty_editor_select_display', array( $this, 'editor_select_display_ajax' ) );
47
+ add_action( 'wp_ajax_ditty_editor_display_fields', array( $this, 'editor_fields_ajax' ) );
48
+ add_action( 'wp_ajax_nopriv_ditty_editor_display_fields', array( $this, 'editor_fields_ajax' ) );
49
+ add_action( 'wp_ajax_ditty_editor_display_clone', array( $this, 'editor_clone_ajax' ) );
50
+ add_action( 'wp_ajax_nopriv_ditty_editor_display_clone', array( $this, 'editor_clone_ajax' ) );
51
+ add_action( 'wp_ajax_ditty_editor_display_update', array( $this, 'editor_update_ajax' ) );
52
+ add_action( 'wp_ajax_nopriv_ditty_editor_display_update', array( $this, 'editor_update_ajax' ) );
53
+
54
+ add_action( 'wp_ajax_ditty_install_display', array( $this, 'install_display' ) );
55
+ }
56
+
57
+ /**
58
+ * Install default displays
59
+ *
60
+ * @access private
61
+ * @since 3.0
62
+ */
63
+ public function install_default( $display_type, $display_template = false, $display_version = false ) {
64
+ $args = array(
65
+ 'template' => $display_template,
66
+ 'version' => $display_version,
67
+ );
68
+ if ( $display_ids = ditty_displays_with_type( $display_type, $args ) ) {
69
+ return reset( $display_ids );
70
+ }
71
+
72
+ $display_object = ditty_display_type_object( $display_type );
73
+ $templates = $display_object->templates();
74
+ if ( ! isset( $templates[$display_template] ) ) {
75
+ return false;
76
+ }
77
+ $postarr = array(
78
+ 'post_type' => 'ditty_display',
79
+ 'post_status' => 'publish',
80
+ 'post_title' => $templates[$display_template]['label'],
81
+ );
82
+ if ( $new_display_id = wp_insert_post( $postarr ) ) {
83
+ update_post_meta( $new_display_id, '_ditty_display_type', esc_attr( $display_type ) );
84
+ update_post_meta( $new_display_id, '_ditty_display_template', esc_attr( $display_template ) );
85
+ if ( isset( $templates[$display_template]['description'] ) ) {
86
+ update_post_meta( $new_display_id, '_ditty_display_description', wp_kses_post( $templates[$display_template]['description'] ) );
87
+ }
88
+ if ( isset( $templates[$display_template]['version'] ) ) {
89
+ update_post_meta( $new_display_id, '_ditty_display_version', wp_kses_post( $templates[$display_template]['version'] ) );
90
+ }
91
+ if ( isset( $templates[$display_template]['settings'] ) ) {
92
+ $fields = $display_object->fields();
93
+ $sanitized_settings = ditty_sanitize_fields( $fields, $templates[$display_template]['settings'], "ditty_display_type_{$display_type}" );
94
+ update_post_meta( $new_display_id, '_ditty_display_settings', $sanitized_settings );
95
+ }
96
+ }
97
+ return $new_display_id;
98
+ }
99
+
100
+ /**
101
+ * Install a display via ajax
102
+ *
103
+ * @access public
104
+ * @since 3.0
105
+ */
106
+ public function install_display() {
107
+ check_ajax_referer( 'ditty', 'security' );
108
+ $display_type_ajax = isset( $_POST['display_type'] ) ? $_POST['display_type'] : false;
109
+ $display_template_ajax = isset( $_POST['display_template'] ) ? $_POST['display_template'] : false;
110
+ $display_version_ajax = isset( $_POST['display_version'] ) ? $_POST['display_version'] : false;
111
+
112
+ if ( ! current_user_can( 'publish_ditty_displays' ) || ! $display_type_ajax || ! $display_template_ajax ) {
113
+ wp_die();
114
+ }
115
+ $display_id = $this->install_default( $display_type_ajax, $display_template_ajax, $display_version_ajax );
116
+
117
+ $args = array(
118
+ 'type' => 'button',
119
+ 'label' => __( 'Installed', 'ditty-ticker' ),
120
+ 'link' => '#',
121
+ 'size' => 'small',
122
+ 'input_class' => 'ditty-default-display-view',
123
+ 'field_only' => true,
124
+ 'atts' => array(
125
+ 'disabled' => 'disabled',
126
+ ),
127
+ );
128
+ $button = ditty_field( $args );
129
+
130
+ $data = array(
131
+ 'display_id' => $display_id,
132
+ 'button' => $button,
133
+ );
134
+ wp_send_json( $data );
135
+ }
136
+
137
+ /**
138
+ * List the default displays
139
+ *
140
+ * @access public
141
+ * @since 3.0
142
+ * @param html
143
+ */
144
+ public function display_templates_list() {
145
+ $html = '';
146
+ $display_types = ditty_display_types();
147
+ $default_displays = ditty_default_displays();
148
+ if ( is_array( $default_displays ) && count( $default_displays ) > 0 ) {
149
+ $html .= '<ul id="ditty-display-templates">';
150
+ foreach ( $default_displays as $display_type => $display_data ) {
151
+ $html .= '<li class="ditty-templates-list__type">';
152
+ $html .= '<div class="ditty-templates-list__type__heading">';
153
+ $html .= '<h3>' . $display_data['label'] . '</h3>';
154
+ $html .= '</div>';
155
+ if ( is_array( $display_data['templates'] ) && count( $display_data['templates'] ) > 0 ) {
156
+ $html .= '<ul id="ditty-templates-list__templates">';
157
+ foreach ( $display_data['templates'] as $template => $template_data ) {
158
+ $args = array(
159
+ 'template' => $template,
160
+ 'return' => 'versions',
161
+ );
162
+ $display_versions = ditty_displays_with_type( $display_type, $args );
163
+ $html .= '<li class="ditty-templates-list__template">';
164
+ $html .= '<div class="ditty-templates-list__template__heading">';
165
+ $html .= '<h4 class="ditty-templates-list__template__label">';
166
+ $html .= $template_data['label'] . " <small class='ditty-layout-version'>(v{$template_data['version']})</small>";
167
+ $html .= '</h4>';
168
+ $html .= '<p class="ditty-templates-list__template__description">' . $template_data['description'] . '</p>';
169
+ $html .= '</div>';
170
+
171
+ $args = array(
172
+ 'type' => 'button',
173
+ 'label' => __( 'Installed', 'ditty-ticker' ),
174
+ 'link' => '#',
175
+ 'size' => 'small',
176
+ 'input_class' => 'ditty-default-display-view',
177
+ 'field_only' => true,
178
+ );
179
+ if ( $display_versions ) {
180
+ if ( in_array( $template_data['version'], $display_versions ) ) {
181
+ $args['label'] = __( 'Installed', 'ditty-ticker' );
182
+ $args['atts'] = array(
183
+ 'disabled' => 'disabled',
184
+ );
185
+ } else {
186
+ $args['label'] = sprintf( __( 'Install Version %s', 'ditty-ticker' ), $template_data['version'] );
187
+ $args['input_class'] = 'ditty-default-display-install';
188
+ $args['icon_after'] = 'fas fa-download';
189
+ $args['atts'] = array(
190
+ 'data-display_type' => $display_type,
191
+ 'data-display_template' => $template,
192
+ 'data-display_version' => $template_data['version'],
193
+ );
194
+ }
195
+ } else {
196
+ $args['label'] = __( 'Install Template', 'ditty-ticker' );
197
+ $args['input_class'] = 'ditty-default-display-install';
198
+ $args['icon_after'] = 'fas fa-download';
199
+ $args['atts'] = array(
200
+ 'data-display_type' => $display_type,
201
+ 'data-display_template' => $template,
202
+ 'data-display_version' => $template_data['version'],
203
+ );
204
+ }
205
+ $html .= ditty_field( $args );
206
+ $html .= '</li>';
207
+ }
208
+ $html .= '</ul>';
209
+ }
210
+ $html .= '</li>';
211
+ }
212
+ $html .= '</ul>';
213
+ }
214
+
215
+ return $html;
216
+ }
217
+
218
+ /**
219
+ * Add the post ID to the list row actions
220
+ *
221
+ * @since 3.0
222
+ * @return void
223
+ */
224
+ public function modify_list_row_actions( $actions, $post ) {
225
+ if ( $post->post_type == 'ditty_display' ) {
226
+ //$id_string = sprintf( __( 'ID: %d', 'ditty-news-ticker' ), $post->ID );
227
+ $id_array = array(
228
+ 'id' => sprintf( __( 'ID: %d', 'ditty-news-ticker' ), $post->ID ),
229
+ );
230
+ $actions = array_merge( $id_array, $actions );
231
+ }
232
+ return $actions;
233
+ }
234
+
235
+ /**
236
+ * Add metaboxes
237
+ *
238
+ * @since 3.0
239
+ * @return void
240
+ */
241
+ public function metaboxes() {
242
+ add_meta_box( 'ditty-display-info', __( 'Display Info', 'ditty-news-ticker' ), array( $this, 'metabox_display_info' ), 'ditty_display', 'side', 'high' );
243
+ add_meta_box( 'ditty-display-settings', __( 'Display Settings', 'ditty-news-ticker' ), array( $this, 'metabox_display_settings' ), 'ditty_display', 'normal' );
244
+ }
245
+
246
+ /**
247
+ * Save custom meta
248
+ *
249
+ * @since 3.0
250
+ * @return void
251
+ */
252
+ public function metabox_save( $post_id ) {
253
+ global $post;
254
+
255
+ // verify nonce
256
+ if ( ! isset( $_POST['ditty_display_nonce'] ) || ! wp_verify_nonce( $_POST['ditty_display_nonce'], basename( __FILE__ ) ) ) {
257
+ return $post_id;
258
+ }
259
+
260
+ // check autosave
261
+ if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_REQUEST['bulk_edit'] ) ) return $post_id;
262
+
263
+ // don't save if only a revision
264
+ if ( isset( $post->post_type ) && $post->post_type == 'revision' ) return $post_id;
265
+
266
+ // check permissions
267
+ if ( isset( $_POST['post_type'] ) && 'ditty_display' == $_POST['post_type'] ) {
268
+ if ( ! current_user_can( 'edit_ditty_display', $post_id ) ) {
269
+ return $post_id;
270
+ }
271
+ } elseif ( ! current_user_can( 'edit_ditty_display', $post_id ) ) {
272
+ return $post_id;
273
+ }
274
+
275
+ if ( isset( $_POST['_ditty_display_description'] ) ) {
276
+ $display_description = sanitize_text_field( $_POST['_ditty_display_description'] );
277
+ update_post_meta( $post_id, '_ditty_display_description', $display_description );
278
+ }
279
+
280
+ // Remove the version number of edited displays
281
+ delete_post_meta( $post_id, '_ditty_display_template' );
282
+ delete_post_meta( $post_id, '_ditty_display_version' );
283
+ }
284
+
285
+ /**
286
+ * Update the display via ajax
287
+ *
288
+ * @since 3.0
289
+ */
290
+ public function admin_update_ajax() {
291
+ check_ajax_referer( 'ditty', 'security' );
292
+ $display_id_ajax = isset( $_POST['display_id'] ) ? $_POST['display_id'] : false;
293
+ if ( ! current_user_can( 'edit_ditty_displays' ) || ! $display_id_ajax ) {
294
+ wp_die();
295
+ }
296
+ $settings = $_POST;
297
+ unset( $settings['action'] );
298
+ unset( $settings['display_id'] );
299
+ unset( $settings['security'] );
300
+
301
+ $json_data = array();
302
+ $display_type = get_post_meta( $display_id_ajax, '_ditty_display_type', true );
303
+ if ( $display_type_object = ditty_display_type_object( $display_type ) ) {
304
+ $fields = $display_type_object->fields();
305
+ $sanitized_display_settings = ditty_sanitize_fields( $fields, $settings, "ditty_display_type_{$display_type}" );
306
+ update_post_meta( $display_id_ajax, '_ditty_display_settings', $sanitized_display_settings );
307
+ $json_data['sanitize_settings'] = $sanitized_display_settings;
308
+ } else {
309
+ $json_data['error'] = __( 'Display type does not exist', 'ditty-news-ticker' );
310
+ }
311
+ wp_send_json( $json_data );
312
+ }
313
+
314
+ /**
315
+ * Add the Layout info metabox
316
+ *
317
+ * @since 3.0
318
+ * @return void
319
+ */
320
+ public function metabox_display_info() {
321
+ global $post;
322
+ $display_type = get_post_meta( $post->ID, '_ditty_display_type', true );
323
+ $display_description = get_post_meta( $post->ID, '_ditty_display_description', true );
324
+ if ( $display_type_object = ditty_display_type_object( $display_type ) ) {
325
+ $display_name = $display_type_object->get_label();
326
+ }
327
+
328
+ $fields = array();
329
+ $fields['type'] = array(
330
+ 'type' => 'text',
331
+ 'id' => '_ditty_display_type',
332
+ 'name' => __( 'Display Type', 'ditty-news-ticker' ),
333
+ 'std' => $display_name,
334
+ 'atts' => array(
335
+ 'disabled' => 'disabled',
336
+ ),
337
+ );
338
+ $fields['description'] = array(
339
+ 'type' => 'textarea',
340
+ 'id' => '_ditty_display_description',
341
+ 'name' => __( 'Description', 'ditty-news-ticker' ),
342
+ 'std' => $display_description,
343
+ );
344
+ ditty_fields( $fields );
345
+ echo '<input type="hidden" name="ditty_display_nonce" value="' . wp_create_nonce( basename( __FILE__ ) ) . '" />';
346
+ }
347
+
348
+ /**
349
+ * Add the Layout html metabox
350
+ *
351
+ * @since 3.0
352
+ * @return void
353
+ */
354
+ public function metabox_display_settings() {
355
+ global $post;
356
+ $display_type = get_post_meta( $post->ID, '_ditty_display_type', true );
357
+ if ( $display_type_object = ditty_display_type_object( $display_type ) ) {
358
+ $display_settings = get_post_meta( $post->ID, '_ditty_display_settings', true );
359
+ $setting_fields = $display_type_object->fields( $display_settings );
360
+ echo "<div class='ditty-display-admin-settings ditty-display-admin-settings--{$display_type}'>";
361
+ ditty_fields( $setting_fields );
362
+ echo '</div>';
363
+ } else {
364
+ echo sprintf( __( '% display type does not exist.', 'ditty-news-ticier' ), $display_type );
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Add the editor item icon
370
+ *
371
+ * @since 3.0
372
+ */
373
+ public function editor_display_icon( $display ) {
374
+ echo '<span class="ditty-data-list__item__icon"><i class="' . $display->get_icon() . '" data-class="' . $display->get_icon() . '"></i></span>';
375
+ }
376
+
377
+ /**
378
+ * Add the editor item label
379
+ *
380
+ * @since 3.0
381
+ */
382
+ public function editor_display_label( $display ) {
383
+ $version = $display->get_version();
384
+ $version_string = '';
385
+ if ( $version ) {
386
+ $version_string = " <small class='ditty-display-version'>(v{$version})</small>";
387
+ }
388
+ ?>
389
+ <span class="ditty-data-list__item__label"><?php echo $display->get_label(); ?><?php echo $version_string; ?></span>
390
+ <?php
391
+ }
392
+
393
+ /**
394
+ * Add the editor edit html button
395
+ *
396
+ * @since 3.0
397
+ */
398
+ public function editor_display_edit( $display ) {
399
+ if ( current_user_can( 'edit_ditty_displays' ) ) {
400
+ echo '<a href="#" class="ditty-data-list__item__edit protip" data-pt-title="' . __( 'Edit Display', 'ditty-news-ticker' ) . '"><i class="fas fa-edit" data-class="fas fa-edit"></i></a>';
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Add the editor clone button
406
+ *
407
+ * @since 3.0
408
+ */
409
+ public function editor_display_clone( $display ) {
410
+ if ( current_user_can( 'publish_ditty_displays' ) ) {
411
+ echo '<a href="#" class="ditty-data-list__item__clone protip" data-pt-title="' . __( 'Clone', 'ditty-news-ticker' ) . '"><i class="fas fa-clone" data-class="fas fa-clone"></i></a>';
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Add the editor delete button
417
+ *
418
+ * @since 3.0
419
+ */
420
+ public function editor_display_delete( $display ) {
421
+ if ( current_user_can( 'delete_ditty_displays' ) ) {
422
+ echo '<a href="#" class="ditty-data-list__item__delete protip" data-pt-title="' . __( 'Delete', 'ditty-news-ticker' ) . '"><i class="fas fa-trash-alt" data-class="fas fa-trash-alt"></i></a>';
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Return an array of custom displays
428
+ *
429
+ * @access private
430
+ * @since 3.0
431
+ * @param array $displays.
432
+ */
433
+ // private function get_custom_displays() {
434
+ // $display_types = ditty_display_types();
435
+ // $args = array(
436
+ // 'posts_per_page' => -1,
437
+ // 'orderby' => 'post_title',
438
+ // 'order' => 'ASC',
439
+ // 'post_type' => 'ditty_display',
440
+ // 'fields' => 'ids',
441
+ // 'meta_query' => array(
442
+ // array(
443
+ // 'key' => '_ditty_display_type',
444
+ // 'value' => array_keys( $display_types ),
445
+ // 'compare' => 'IN',
446
+ // ),
447
+ // ),
448
+ // );
449
+ // return get_posts( $args );
450
+ // }
451
+
452
+ /**
453
+ * Return an array of displays by type
454
+ *
455
+ * @access public
456
+ * @since 3.0
457
+ * @param array $displays.
458
+ */
459
+ public function get_displays_data() {
460
+ $displays = array();
461
+ $display_types = ditty_display_types();
462
+ ksort( $display_types );
463
+ if ( is_array( $display_types ) && count( $display_types ) > 0 ) {
464
+ foreach ( $display_types as $type_slug => $display_type ) {
465
+ if ( ! $display_object = ditty_display_type_object( $type_slug ) ) {
466
+ continue;
467
+ }
468
+ $args = array(
469
+ 'posts_per_page' => -1,
470
+ 'orderby' => 'post_title',
471
+ 'order' => 'ASC',
472
+ 'post_type' => 'ditty_display',
473
+ 'meta_key' => '_ditty_display_type',
474
+ 'meta_value' => $type_slug,
475
+ );
476
+ $posts = get_posts( $args );
477
+ if ( is_array( $posts ) && count( $posts ) > 0 ) {
478
+ foreach ( $posts as $i => $post ) {
479
+ $version = get_post_meta( $post->ID, '_ditty_display_version', true );
480
+ $version_string = '';
481
+ if ( $version ) {
482
+ $version_string = " <small class='ditty-display-version'>(v{$version})</small>";
483
+ }
484
+ $displays[] = array(
485
+ 'type_id' => $type_slug,
486
+ 'type_label' => $display_type['label'],
487
+ 'display_id' => $post->ID,
488
+ 'display_label' => $post->post_title.$version_string,
489
+ );
490
+ }
491
+ }
492
+ }
493
+ }
494
+ return $displays;
495
+ }
496
+
497
+ /**
498
+ * Return an array of displays for select fields
499
+ *
500
+ * @access public
501
+ * @since 3.0
502
+ * @param array $options.
503
+ */
504
+ public function select_field_options() {
505
+ $displays = $this->get_displays_data();
506
+ $options = array();
507
+
508
+ if ( is_array( $displays ) && count( $displays ) > 0 ) {
509
+ foreach ( $displays as $i => $display ) {
510
+ $options[$display['display_id']] = $display['type_label'] . ': ' . $display['display_label'];
511
+ }
512
+ }
513
+
514
+ return $options;
515
+ }
516
+
517
+ /**
518
+ * Return an array of all display values
519
+ *
520
+ * @access public
521
+ * @since 3.0
522
+ * @param array $values.
523
+ */
524
+ public function get_values( $display_atts ) {
525
+
526
+ if ( ! is_array( $display_atts ) ) {
527
+ $display_atts = $this->get_attributes( $display_atts );
528
+ }
529
+
530
+ if ( ! $display_object = ditty_display_type_object( $display_atts['type'] ) ) {
531
+ return false;
532
+ }
533
+
534
+ // If this is a custom post id
535
+ if ( 'custom' == $display_atts['group'] ) {
536
+
537
+ $defaults = $display_object->default_settings();
538
+ $settings = get_post_meta( $display_atts['id'], "_ditty_{$display_atts['type']}_settings", true );
539
+ $settings = wp_parse_args( $settings, $defaults['settings'] );
540
+ $display = get_post_meta( $display_atts['id'], "_ditty_{$display_atts['type']}_display", true );
541
+ $display = wp_parse_args( $display, $defaults['display'] );
542
+
543
+ // If this is a template
544
+ } else {
545
+
546
+ $template = $display_object->get_template( $display_atts['id'] );
547
+ $settings = $template['settings'];
548
+ $display = $template['display'];
549
+ }
550
+
551
+ return apply_filters( 'ditty_display_values', ( $settings + $display ), $display_atts['id'], $display_atts['type'] );
552
+ }
553
+
554
+ /**
555
+ * Return a displays values via ajax
556
+ *
557
+ * @access public
558
+ * @since 3.0
559
+ * @param json.
560
+ */
561
+ public function editor_values_ajax() {
562
+
563
+ // Check the nonce
564
+ check_ajax_referer( 'ditty', 'security' );
565
+
566
+ $display_id = isset( $_POST['display_id'] ) ? $_POST['display_id'] : false;
567
+ if ( $display = new Ditty_Display( $display_id ) ) {
568
+ $data = array(
569
+ 'values' => $display->get_values( 'merged' ),
570
+ );
571
+ } else {
572
+ $data = array(
573
+ 'error' => __( 'Display does not exist', 'ditty-news-ticker' ),
574
+ );
575
+ }
576
+
577
+ wp_send_json( $data );
578
+ }
579
+
580
+ /**
581
+ * Add to the editor tabs
582
+ *
583
+ * @access public
584
+ * @since 3.0
585
+ * @param $html
586
+ */
587
+ public function editor_tab( $tabs, $ditty_id ) {
588
+ if ( ! current_user_can( 'edit_ditty_displays' ) ) {
589
+ return false;
590
+ }
591
+ $tabs['displays'] = array(
592
+ 'icon' => 'fas fa-tablet-alt',
593
+ 'label' => __( 'Display', 'ditty-news-ticker' ),
594
+ );
595
+ return $tabs;
596
+ }
597
+
598
+ /**
599
+ * Return the editor displays panel
600
+ *
601
+ * @access public
602
+ * @since 3.0
603
+ * @param $html
604
+ */
605
+ public function editor_panel( $panels, $ditty_id ) {
606
+ if ( ! current_user_can( 'edit_ditty_displays' ) ) {
607
+ return false;
608
+ }
609
+ $display_id = get_post_meta( $ditty_id, '_ditty_display', true );
610
+ if ( ! $display_id ) {
611
+ $display_id = ditty_default_display( $ditty_id );
612
+ }
613
+ $display_types = ditty_display_types();
614
+ ob_start();
615
+ ?>
616
+ <div class="ditty-editor-options ditty-metabox">
617
+ <div class="ditty-editor-options__contents">
618
+ <div class="ditty-data-list">
619
+ <div class="ditty-data-list__filters">
620
+ <?php
621
+ if ( is_array( $display_types ) && count( $display_types ) > 0 ) {
622
+ foreach ( $display_types as $type => $display ) {
623
+ if ( ! $display_object = ditty_display_type_object( $type ) ) {
624
+ continue;
625
+ }
626
+ echo '<a class="ditty-display-panel__filter ditty-data-list__filter" data-filter="' . $type . '" href="#"><i class="' . $display_object->get_icon() . '"></i>' . $display_object->get_label() . '</a>';
627
+ }
628
+ }
629
+ ?>
630
+ </div>
631
+ <div class="ditty-data-list__items" data-active="<?php echo $display_id; ?>">
632
+ <?php
633
+ // Add the custom displays
634
+ if ( $displays_data = $this->get_displays_data() ) {
635
+ foreach ( $displays_data as $i => $data ) {
636
+ $display = new Ditty_Display( $data['display_id'] );
637
+ echo $display->render_editor_list_item( 'return' );
638
+ }
639
+ }
640
+ ?>
641
+ </div>
642
+ </div>
643
+ </div>
644
+ </div>
645
+ <?php
646
+ // Return the output
647
+ $html = ob_get_clean();
648
+
649
+ $panels['displays'] = $html;
650
+ return $panels;
651
+ }
652
+
653
+ /**
654
+ * Load a display
655
+ *
656
+ * @access public
657
+ * @since 3.0
658
+ */
659
+ public function editor_select_display_ajax() {
660
+ check_ajax_referer( 'ditty', 'security' );
661
+ $display_id_ajax = isset( $_POST['display_id'] ) ? $_POST['display_id'] : false;
662
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
663
+ if ( ! current_user_can( 'edit_ditty_items' ) || ! $display_id_ajax ) {
664
+ wp_die();
665
+ }
666
+ ditty_set_draft_values( $draft_values_ajax );
667
+ $display = new Ditty_Display( $display_id_ajax );
668
+ $settings = $display->get_settings();
669
+ wp_send_json( $settings );
670
+ }
671
+
672
+ /**
673
+ * Return a displays values to edit
674
+ *
675
+ * @access public
676
+ * @since 3.0
677
+ * @param json.
678
+ */
679
+ public function editor_fields_ajax() {
680
+ check_ajax_referer( 'ditty', 'security' );
681
+ $display_id_ajax = isset( $_POST['display_id'] ) ? $_POST['display_id'] : false;
682
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
683
+ if ( ! current_user_can( 'edit_ditty_displays' ) || ! $display_id_ajax ) {
684
+ wp_die();
685
+ }
686
+ ditty_set_draft_values( $draft_values_ajax );
687
+ $display = new Ditty_Display( $display_id_ajax );
688
+ ?>
689
+ <form class="ditty-editor-options ditty-display-type-options ditty-display-type-options--<?php echo $display->get_display_type(); ?> ditty-metabox">
690
+ <div class="ditty-editor-options__contents">
691
+ <div class="ditty-editor-options__header">
692
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--start">
693
+ <a href="#" class="ditty-editor-options__back"><i class="fas fa-chevron-left" data-class="fas fa-chevron-left"></i></a>
694
+ </div>
695
+ <input class="ditty-editor-options__title" type="text" name="title" placeholder="<?php _e( 'Title Goes Here...', 'ditty-news-ticker' ); ?>" value="<?php echo $display->get_label(); ?>" />
696
+ </div>
697
+ <div class="ditty-editor-options__body">
698
+ <div class="ditty-editor-options__fields">
699
+ <?php
700
+ $display->object_settings();
701
+ ?>
702
+ </div>
703
+ </div>
704
+ </div>
705
+ </form>
706
+ <?php
707
+ wp_die();
708
+ }
709
+
710
+ /**
711
+ * Update the display via ajax
712
+ *
713
+ * @since 3.0
714
+ */
715
+ public function editor_update_ajax() {
716
+ check_ajax_referer( 'ditty', 'security' );
717
+ $display_id_ajax = isset( $_POST['display_id'] ) ? $_POST['display_id'] : false;
718
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
719
+ if ( ! current_user_can( 'edit_ditty_displays' ) || ! $display_id_ajax ) {
720
+ wp_die();
721
+ }
722
+ ditty_set_draft_values( $draft_values_ajax );
723
+
724
+ $display = new Ditty_Display( $display_id_ajax );
725
+ $settings = $_POST;
726
+
727
+ // Possibly update the label
728
+ $draft_label = false;
729
+ if ( isset( $settings['title'] ) ) {
730
+ if ( $display->get_label() != $settings['title'] ) {
731
+ $draft_label = $display->set_label( $settings['title'] );
732
+ }
733
+ unset( $settings['title'] );
734
+ }
735
+ unset( $settings['action'] );
736
+ unset( $settings['display_id'] );
737
+ unset( $settings['draft_values'] );
738
+ unset( $settings['security'] );
739
+
740
+ // Update the settings
741
+ $draft_settings = $display->update_settings( $settings );
742
+
743
+ $data = array(
744
+ 'draft_id' => $display->get_display_id(),
745
+ 'draft_label' => $draft_label ? $draft_label : null,
746
+ 'draft_settings' => $draft_settings,
747
+ 'draft_settings_json' => json_encode( $draft_settings ),
748
+ );
749
+ if ( $draft_label ) {
750
+ $data['draft_label'] = $draft_label;
751
+ }
752
+
753
+ wp_send_json( $data );
754
+ }
755
+
756
+ /**
757
+ * Clone a display
758
+ *
759
+ * @access public
760
+ * @since 3.0
761
+ * @param json.
762
+ */
763
+ public function editor_clone_ajax() {
764
+ check_ajax_referer( 'ditty', 'security' );
765
+ $display_id_ajax = isset( $_POST['display_id'] ) ? $_POST['display_id'] : false;
766
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
767
+ if ( ! current_user_can( 'publish_ditty_displays' ) || ! $display_id_ajax ) {
768
+ wp_die();
769
+ }
770
+ ditty_set_draft_values( $draft_values_ajax );
771
+
772
+ // Clone the source display
773
+ $editor_display = new Ditty_Display( $display_id_ajax );
774
+ $draft_id = uniqid( 'new-' );
775
+ $draft_label = sprintf( __( '%s Clone', 'ditty-news-ticker' ), $editor_display->get_label() );
776
+ $editor_display->set_display_id( $draft_id );
777
+ $editor_display->set_label( $draft_label );
778
+ $editor_display->set_version( '' );
779
+ $draft_data = array(
780
+ 'label' => $editor_display->get_label(),
781
+ 'description' => $editor_display->get_description(),
782
+ 'display_type' => $editor_display->get_display_type(),
783
+ 'settings' => $editor_display->get_settings(),
784
+ );
785
+ $data = array(
786
+ 'editor_display' => $editor_display->render_editor_list_item( 'return' ),
787
+ 'draft_id' => $draft_id,
788
+ 'draft_data' => $draft_data,
789
+ );
790
+ wp_send_json( $data );
791
+ }
792
+
793
+ /**
794
+ * Return the temporary new display IDs
795
+ *
796
+ * @access public
797
+ * @since 3.0
798
+ * @param array $new_displays
799
+ */
800
+ private function get_new_displays() {
801
+ if ( empty( $this->new_displays ) ) {
802
+ $this->new_displays = array();
803
+ }
804
+ return $this->new_displays;
805
+ }
806
+
807
+ /**
808
+ * Update the temporary new display IDs
809
+ *
810
+ * @access public
811
+ * @since 3.0
812
+ * @param array $new_displays
813
+ */
814
+ private function update_new_displays( $new_id, $post_id ) {
815
+ $new_displays = $this->get_new_displays();
816
+ $new_displays[$new_id] = $post_id;
817
+ $this->new_displays = $new_displays;
818
+ }
819
+
820
+ /**
821
+ * Modify a Ditty's draft meta
822
+ *
823
+ * @access public
824
+ * @since 3.0
825
+ * @param json.
826
+ */
827
+ public function modify_ditty_draft_meta( $meta_value, $meta_key, $ditty_id ) {
828
+ if ( $meta_key == '_ditty_display' ) {
829
+ if ( false === strpos( $meta_value, 'new-' ) ) {
830
+ return $meta_value;
831
+ }
832
+ $new_displays = $this->get_new_displays();
833
+ if ( isset( $new_displays[$meta_value] ) ) {
834
+ return $new_displays[$meta_value];
835
+ }
836
+ }
837
+ return $meta_value;
838
+ }
839
+
840
+ /**
841
+ * Save display draft values on Ditty update
842
+ *
843
+ * @access public
844
+ * @since 3.0
845
+ */
846
+ public function update_drafts( $ditty_id, $draft_values ) {
847
+ if ( ! current_user_can( 'edit_ditty_displays' ) ) {
848
+ return false;
849
+ }
850
+
851
+ $add_to_live_update = false;
852
+ if ( isset( $draft_values['displays'] ) && is_array( $draft_values['displays'] ) && count( $draft_values['displays'] ) > 0 ) {
853
+ foreach ( $draft_values['displays'] as $display_id => $display_data ) {
854
+ $display_type = false;
855
+
856
+ // Delete a display
857
+ if ( 'DELETE' == $display_data ) {
858
+ wp_trash_post( $display_id );
859
+ continue;
860
+
861
+ } elseif( is_array( $display_data ) ) {
862
+
863
+ // Add or update a display
864
+ if ( false !== strpos( $display_id, 'new-' ) ) {
865
+
866
+ $postarr = array(
867
+ 'post_type' => 'ditty_display',
868
+ 'post_status' => 'publish',
869
+ 'post_title' => $display_data['label'],
870
+ );
871
+ $updated_display_id = wp_insert_post( $postarr );
872
+ $this->update_new_displays( $display_id, $updated_display_id );
873
+ $display_id = $updated_display_id;
874
+
875
+ } else {
876
+ if ( isset( $display_data['label'] ) ) {
877
+ $postarr = array(
878
+ 'ID' => $display_id,
879
+ 'post_title' => $display_data['label'],
880
+ );
881
+ wp_update_post( $postarr );
882
+ }
883
+ }
884
+
885
+ // Update a display description
886
+ if ( isset( $display_data['description'] ) ) {
887
+ update_post_meta( $display_id, '_ditty_display_description', wp_kses_post( $display_data['description'] ) );
888
+ }
889
+
890
+ // Update a display type
891
+ if ( isset( $display_data['display_type'] ) ) {
892
+ $display_type = esc_attr( $display_data['display_type'] );
893
+ update_post_meta( $display_id, '_ditty_display_type', $display_type );
894
+ }
895
+
896
+ // Update a display settings
897
+ if ( isset( $display_data['settings'] ) ) {
898
+ if ( ! $display_type ) {
899
+ $display_type = get_post_meta( $display_id, '_ditty_display_type', true );
900
+ }
901
+ $display_object = ditty_display_type_object( $display_type );
902
+ $fields = $display_object->fields();
903
+ $sanitized_settings = ditty_sanitize_fields( $fields, $display_data['settings'], "ditty_display_type_{$display_type}" );
904
+ update_post_meta( $display_id, '_ditty_display_settings', $sanitized_settings );
905
+ }
906
+
907
+ // Remove the version number of edited displays
908
+ delete_post_meta( $display_id, '_ditty_display_version' );
909
+ }
910
+ }
911
+ }
912
+ }
913
+ }
includes/class-ditty-editor.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Editor Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Editor
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Editor {
13
+
14
+ /**
15
+ * Get things started
16
+ *
17
+ * @access public
18
+ * @since 3.0
19
+ */
20
+ public function __construct() {
21
+ add_action( 'wp_ajax_ditty_editor_load_contents', array( $this, 'editor_load_contents' ) );
22
+ add_action( 'wp_ajax_noprive_ditty_editor_load_contents', array( $this, 'editor_load_contents' ) );
23
+ add_action( 'init', array( $this, 'editor_update' ) );
24
+ }
25
+
26
+ /**
27
+ * Load the editor contents
28
+ *
29
+ * @access public
30
+ * @since 3.0
31
+ */
32
+ public function editor_load_contents() {
33
+ check_ajax_referer( 'ditty', 'security' );
34
+ $ditty_id = isset( $_POST['ditty_id'] ) ? intval( $_POST['ditty_id'] ) : false;
35
+ $data = array(
36
+ 'tabs' => apply_filters( 'ditty_editor_tabs', array(), $ditty_id ),
37
+ 'panels' => apply_filters( 'ditty_editor_panels', array(), $ditty_id ),
38
+ 'draft_data' => ditty_get_draft_values(),
39
+ );
40
+ wp_send_json( $data );
41
+ }
42
+
43
+ /**
44
+ * Update a ditty from the editor
45
+ *
46
+ * @access public
47
+ * @since 3.0
48
+ * @param json.
49
+ */
50
+ public function editor_update() {
51
+
52
+ if ( ! isset( $_POST['_ditty_editor_nonce'] ) ) {
53
+ return false;
54
+ }
55
+ if ( ! wp_verify_nonce( $_POST['_ditty_editor_nonce'], 'ditty-editor' ) ) {
56
+ return false;
57
+ }
58
+
59
+ $ditty_id = isset( $_POST['ditty_id'] ) ? $_POST['ditty_id'] : false;
60
+ do_action( 'ditty_editor_update', $ditty_id );
61
+
62
+ $data = array(
63
+ 'ditty_id' => $ditty_id,
64
+ 'response' => __( 'Ditty updated', 'ditty-news-ticker' ),
65
+ );
66
+ wp_send_json( $data );
67
+ }
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+ }
includes/class-ditty-errors.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Error Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Error
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Errors {
13
+
14
+ /**
15
+ * Get things started
16
+ *
17
+ * @access public
18
+ * @since 3.0
19
+ */
20
+ public function __construct() {
21
+ }
22
+
23
+ /**
24
+ * Add error
25
+ *
26
+ * @since 3.0
27
+ * @return void
28
+ */
29
+ public function add_error( $error ) {
30
+ /*
31
+ $error_log = true;
32
+ $email = ditty_settings( 'notification_email' );
33
+ if ( $email ) {
34
+ if ( is_array( $error ) || is_object( $error ) ) {
35
+ $error = print_r( $error, true );
36
+ }
37
+ wp_mail( $email, __( 'Ditty... Error' ), $error );
38
+ }
39
+ if ( $error_log ) {
40
+ error_log( $error );
41
+ }
42
+ */
43
+ }
44
+
45
+ }
includes/class-ditty-extensions.php ADDED
@@ -0,0 +1,642 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Extensions Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Extensions
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+
13
+ class Ditty_Extensions {
14
+
15
+ /**
16
+ * Slug
17
+ *
18
+ * @since 3.0
19
+ */
20
+ public $licenses;
21
+
22
+ /**
23
+ * Get things started
24
+ * @access public
25
+ * @since 3.0
26
+ */
27
+ public function __construct() {
28
+ add_action( 'admin_init', array( $this, 'add_extension_updaters' ), 0 );
29
+ add_action( 'admin_menu', array( $this, 'add_extensions_page' ), 3 );
30
+ add_action( 'network_admin_menu', array( $this, 'add_extensions_page' ) );
31
+
32
+ // Ajax
33
+ add_action( 'wp_ajax_ditty_extension_license_activate', array( $this, 'license_activate_ajax' ) );
34
+ add_action( 'wp_ajax_ditty_extension_license_refresh', array( $this, 'license_refresh_ajax' ) );
35
+ add_action( 'wp_ajax_ditty_extension_license_deactivate', array( $this, 'license_deactivate_ajax' ) );
36
+ add_action( 'wp_ajax_ditty_extension_panel_update', array( $this, 'panel_update_ajax' ) );
37
+
38
+ $this->licenses = $this->get_licenses();
39
+ }
40
+
41
+ /**
42
+ * Add the extensions page
43
+ * @access public
44
+ * @since 3.0
45
+ */
46
+ public function add_extensions_page() {
47
+ if ( is_multisite() ) {
48
+ if ( is_network_admin() ) {
49
+ add_submenu_page( 'settings.php', __( 'Ditty Extensions', 'ditty-news-ticker' ), __( 'Extensions', 'ditty-news-ticker' ), 'manage_ditty_settings', 'ditty_extensions', array( $this, 'extensions_page' ) );
50
+ }
51
+ } else {
52
+ add_submenu_page( 'edit.php?post_type=ditty', __( 'Ditty Extensions', 'ditty-news-ticker' ), __( 'Extensions', 'ditty-news-ticker' ), 'manage_ditty_settings', 'ditty_extensions', array( $this, 'extensions_page' ) );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Load all the extension updaters
58
+ * @access public
59
+ * @since 3.0
60
+ */
61
+ public function add_extension_updaters() {
62
+ if ( wp_doing_ajax() ) {
63
+ return false;
64
+ }
65
+ $extension_licenses = ditty_extension_licenses();
66
+ $ditty_licenses = $this->licenses;
67
+ if ( is_array( $extension_licenses ) && count( $extension_licenses ) > 0 ) {
68
+ foreach( $extension_licenses as $slug => $license_settings ) {
69
+ if ( ! isset( $license_settings['version'] ) || ! isset( $license_settings['item_id'] ) || ! isset( $license_settings['path'] ) ) {
70
+ continue;
71
+ }
72
+ $license_key = isset( $ditty_licenses[$slug] ) ? trim( $ditty_licenses[$slug]['key'] ) : '';
73
+ $edd_updater = new EDD_SL_Plugin_Updater( 'https://www.metaphorcreations.com', $license_settings['path'],
74
+ array(
75
+ 'version' => $license_settings['version'], // current version number
76
+ 'license' => $license_key, // license key (used get_option above to retrieve from DB)
77
+ 'item_id' => $license_settings['item_id'], // ID of the product
78
+ 'author' => isset( $license_settings['author'] ) ? $license_settings['author'] : __( 'Ditty...', 'ditty-news-ticker' ), // author of this plugin
79
+ 'beta' => false,
80
+ )
81
+ );
82
+ }
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Return a message string
88
+ * @access public
89
+ * @since 3.0
90
+ */
91
+ private function status_message( $slug, $extension ) {
92
+ $messages = array(
93
+ 'valid' => __( 'License is active.', 'ditty-news-ticker' ),
94
+ 'generic_error' => __( 'An error occurred, please try again.', 'ditty-news-ticker' ),
95
+ 'remote_error' => __( 'An error occurred, please try again.', 'ditty-news-ticker' ),
96
+ 'expired' => __( 'Your license key expired on %s.', 'ditty-news-ticker' ),
97
+ 'disabled' => __( 'Your license key has been disabled.', 'ditty-news-ticker' ),
98
+ 'revoked' => __( 'Your license key has been disabled.', 'ditty-news-ticker' ),
99
+ 'missing' => __( 'Invalid license.', 'ditty-news-ticker' ),
100
+ 'invalid' => __( 'Your license is not active for this URL.', 'ditty-news-ticker' ),
101
+ 'site_inactive' => __( 'Your license is not active for this URL.', 'ditty-news-ticker' ),
102
+ 'item_name_mismatch' => sprintf( __( 'This appears to be an invalid license key for %s.', 'ditty-news-ticker' ), $extension ),
103
+ 'no_activations_left' => __( 'Your license key has reached its activation limit.', 'ditty-news-ticker' ),
104
+ 'deactivated' => __( 'License is deactivated.', 'ditty-news-ticker' ),
105
+ 'failed' => __( 'Update failed.', 'ditty-news-ticker' ),
106
+ );
107
+ $messages = apply_filters( 'ditty_extensions_messages', $messages, $extension );
108
+ if ( isset( $messages[$slug] ) ) {
109
+ $message = $messages[$slug];
110
+ if ( 'expired' == $slug ) {
111
+ $license_data = $this->get_license( $extension );
112
+ $message = sprintf( $message, date_i18n( get_option( 'date_format' ), strtotime( $license_data['expires'], current_time( 'timestamp' ) ) ) );
113
+ }
114
+ if ( 'expired' == $slug || 'no_activations_left' == $slug ) {
115
+ $link = 'https://www.metaphorcreations.com';
116
+ $message .= '<br/><span class="ditty-extension__renewal-link">' . sprintf( __( 'Please <a href="%s" target="_blank">update or renew your license</a>.', 'ditty-news-ticker' ), $link ) . '</span>';
117
+ }
118
+ return $message;
119
+ }
120
+ //return sprintf( __( '%s: No message available.', 'ditty-news-ticker' ), $slug );
121
+ }
122
+
123
+ /**
124
+ * Return the license data
125
+ * @access public
126
+ * @since 3.0
127
+ */
128
+ private function get_licenses() {
129
+ $licenses = ( is_multisite() ) ? get_site_option( 'ditty_licenses', array() ) : get_option( 'ditty_licenses', array() );
130
+ return $licenses;
131
+ }
132
+
133
+ /**
134
+ * Return an extension's license data
135
+ * @access public
136
+ * @since 3.0
137
+ */
138
+ public function get_license( $slug ) {
139
+ if ( isset( $this->licenses[$slug] ) ) {
140
+ return $this->licenses[$slug];
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Return an extension's license data
146
+ * @access public
147
+ * @since 3.0
148
+ */
149
+ public function has_valid_license( $slug ) {
150
+ if ( $license_data = Ditty()->extensions->get_license( $slug ) ) {
151
+ if ( 'valid' == $license_data['status'] ) {
152
+ return true;
153
+ }
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Update the license data
159
+ * @access public
160
+ * @since 3.0
161
+ */
162
+ private function update_licenses( $data ) {
163
+ $licenses = ( is_multisite() ) ? update_site_option( 'ditty_licenses', $data ) : update_option( 'ditty_licenses', $data );
164
+ $this->licenses = $licenses;
165
+ return $licenses;
166
+ }
167
+
168
+ /**
169
+ * Update an extension's license
170
+ * @access public
171
+ * @since 3.0
172
+ */
173
+ private function update_license( $extension, $license_key='', $status='', $expires='', $error=false ) {
174
+ $licenses = $this->licenses;
175
+ if ( ! is_array( $licenses ) || empty( $licenses ) ) {
176
+ $licenses = array();
177
+ }
178
+ if ( ! isset( $licenses[$extension] ) ) {
179
+ $licenses[$extension] = array();
180
+ }
181
+ $licenses[$extension]['key'] = sanitize_text_field( $license_key );
182
+ $licenses[$extension]['status'] = esc_attr( $status );
183
+ $licenses[$extension]['expires'] = sanitize_text_field( $expires );
184
+ $licenses[$extension]['error'] = esc_attr( $error );
185
+
186
+ $updated_licenses = array();
187
+ if ( is_array( $licenses ) && count( $licenses ) > 0 ) {
188
+ foreach ( $licenses as $slug => $license ) {
189
+ if ( '' === $slug ) {
190
+ continue;
191
+ }
192
+ $updated_licenses[$slug] = $license;
193
+ }
194
+ }
195
+
196
+ return $this->update_licenses( $updated_licenses );
197
+ }
198
+
199
+ /**
200
+ * Remove an extension's license
201
+ * @access public
202
+ * @since 3.0
203
+ */
204
+ private function remove_license( $extension ) {
205
+ $licenses = $this->licenses;
206
+ if ( ! is_array( $licenses ) || empty( $licenses ) ) {
207
+ return false;
208
+ }
209
+ unset( $licenses[$extension] );
210
+ return $this->update_licenses( $licenses );
211
+ }
212
+
213
+ /**
214
+ * Check if a license is active
215
+ * @access public
216
+ * @since 3.0
217
+ */
218
+ public function get_license_status( $extension ) {
219
+ $licenses = $this->licenses;
220
+ if ( ! is_array( $licenses ) || empty( $licenses ) ) {
221
+ $licenses = array();
222
+ }
223
+ if ( ! isset( $licenses[$extension] ) ) {
224
+ return false;
225
+ }
226
+ if ( isset( $licenses[$extension]['status'] ) ) {
227
+ return $licenses[$extension]['status'];
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Render an extension
233
+ * @access public
234
+ * @since 3.0
235
+ */
236
+ private function render_extension( $extension, $data, $extension_licenses ) {
237
+ $settings = isset( $data['settings'] ) ? $data['settings'] : array();
238
+ $license_settings = isset( $extension_licenses[$extension] ) ? $extension_licenses[$extension] : false;
239
+ $oauth_settings = false;
240
+ $other_settings = array();
241
+ if ( is_array( $settings ) && count( $settings ) > 0 ) {
242
+ foreach ( $settings as $i => $setting ) {
243
+ if ( 'oauth' === $setting['id'] ) {
244
+ $oauth_settings = $setting;
245
+ } else {
246
+ $other_settings[] = $setting;
247
+ }
248
+ }
249
+ }
250
+
251
+ $init_panel = false;
252
+ $license = '';
253
+ $license_key = '';
254
+ $status = 'dna';
255
+ $error = '';
256
+ $user_name = false;
257
+ $user_avatar = false;
258
+ $user_banner = false;
259
+
260
+ if ( isset( $_GET['extension'] ) && isset( $_GET['panel'] ) && $_GET['extension'] == $extension ) {
261
+ $init_panel = $_GET['panel'];
262
+ }
263
+ if ( $license_settings ) {
264
+
265
+ // Add the license to the settings array
266
+ $license_settings['id'] = 'license';
267
+ $license_settings['label'] = __( 'License', 'ditty-news-ticker' );
268
+ $settings = array( 'license' => $license_settings ) + $settings;
269
+
270
+ if ( $license_data = $this->get_license( $extension ) ) {
271
+ $license_key = isset( $license_data['key'] ) ? substr( $license_data['key'], 0, -15 ) . '***************' : '';
272
+ $status = isset( $license_data['status'] ) ? $license_data['status'] : '';
273
+ $error = isset( $license_data['error'] ) ? $license_data['error'] : '';
274
+ } else {
275
+ $status = 'none';
276
+ }
277
+ }
278
+
279
+ $heading_style = '';
280
+ $classes = 'ditty-extension ditty-extension--' . $extension;
281
+ if ( $oauth_settings ) {
282
+ $classes .= ' ditty-extension--oauth';
283
+ if ( isset( $oauth_settings['has_custom_keys'] ) && '' != $oauth_settings['has_custom_keys'] ) {
284
+ $classes .= ' ditty-extension--custom-keys';
285
+ }
286
+ if ( isset( $oauth_settings['user_name'] ) ) {
287
+ $user_name = $oauth_settings['user_name'];
288
+ }
289
+ if ( isset( $oauth_settings['user_avatar'] ) ) {
290
+ $user_avatar = $oauth_settings['user_avatar'];
291
+ }
292
+ if ( isset( $oauth_settings['user_banner'] ) ) {
293
+ $user_banner = $oauth_settings['user_banner'];
294
+ $heading_style = ' style="background-image:url(' . esc_url_raw( $user_banner ) . ');"';
295
+ }
296
+ }
297
+ $attr = array(
298
+ 'class' => $classes,
299
+ 'data-extension' => $extension,
300
+ 'data-license_status' => $status,
301
+ );
302
+ if ( $oauth_settings ) {
303
+ $attr['data-api'] = ( isset( $oauth_settings['authorized'] ) && '' != $oauth_settings['authorized'] ) ? 'authorized' : 'unauthorized';
304
+ if ( isset( $oauth_settings['has_custom_keys'] ) && '' != $oauth_settings['has_custom_keys'] ) {
305
+ $attr['data-api_keys'] = $oauth_settings['has_custom_keys'];
306
+ }
307
+ }
308
+ ?>
309
+ <div <?php echo ditty_attr_to_html( $attr ); ?>>
310
+ <div class="ditty-extension__contents">
311
+
312
+ <div class="ditty-extension__header"<?php echo $heading_style; ?>>
313
+ <?php if ( ! $user_banner ) { ?>
314
+ <div class="ditty-extension__header__icon"><i class="<?php echo $data['icon']; ?>"></i></div>
315
+ <?php } ?>
316
+ <div class="ditty-extension__header__overlay"></div>
317
+ <div class="ditty-extension__icon">
318
+ <?php if ( $user_avatar ) { ?>
319
+ <img src="<?php echo esc_url_raw( $user_avatar ); ?>" />
320
+ <i class="ditty-extension__icon__small <?php echo $data['icon']; ?>"></i>
321
+ <?php } else { ?>
322
+ <i class="<?php echo $data['icon']; ?>"></i>
323
+ <?php } ?>
324
+ </div>
325
+ <h3 class="ditty-extension__title"><?php echo $data['name']; ?></h3>
326
+ </div>
327
+ <?php
328
+ if ( isset( $data['preview'] ) ) {
329
+ ?>
330
+ <div class="ditty-extension__preview">
331
+ <a class="ditty-extension__preview__link ditty-button" href="<?php echo esc_url_raw( $data['url'] ); ?>" target="_blank"><?php _e( 'Preview Extension', 'ditty-news-ticker' ); ?></a>
332
+ </div>
333
+ <?php
334
+ } else {
335
+
336
+ if ( is_array( $settings ) && count( $settings ) > 0 ) {
337
+ echo '<div class="ditty-extension__tabs">';
338
+ foreach ( $settings as $i => $setting ) {
339
+ echo '<a href="#" class="ditty-extension__tab" data-slide_id="' . $setting['id'] . '">' . $setting['label'] . '</a>';
340
+ }
341
+ echo '</div>';
342
+ }
343
+
344
+ if ( is_array( $settings ) && count( $settings ) > 0 ) {
345
+ echo '<div class="ditty-extension__panels" data-init_panel="' . $init_panel . '">';
346
+ foreach ( $settings as $i => $setting ) {
347
+ ?>
348
+ <div class="ditty-extension__panel ditty-extension__panel--<?php echo $setting['id']; ?>" data-slide_id="<?php echo $setting['id']; ?>" data-slide_cache="true">
349
+ <form class="ditty-extension__form">
350
+ <?php
351
+ if( 'license' == $setting['id'] ) {
352
+ ?>
353
+ <div class="ditty-field">
354
+ <?php
355
+ if ( '' == $error ) {
356
+ $license_message = $this->status_message( $status, $extension );
357
+ } else {
358
+ $license_message = $this->status_message( $error, $extension );
359
+ }
360
+ ?>
361
+ <label class="ditty-field__label ditty-extension__license__message"><?php echo $license_message; ?></label>
362
+ <div class="ditty-field__input ditty-extension__license__fields">
363
+ <input class="ditty-extension__license__input regular-text" name="ditty_licenses[<?php echo $extension; ?>]" type="text" placeholder="<?php _e( 'Add your license key here', 'ditty-news-ticker' ); ?>" value="<?php echo esc_attr( $license_key ); ?>" />
364
+ <a class="ditty-extension__license__submit ditty-button protip" href="#" data-extension="<?php echo esc_attr( $extension ); ?>" data-extension_id="<?php echo esc_attr( $setting['item_id'] ); ?>" data-extension_name="<?php echo esc_attr( $data['name'] ); ?>" data-pt-title="<?php _e( 'Activate License', 'ditty-news-ticker' ); ?>"><i class="fas fa-check" data-class="fas fa-check"></i></a>
365
+ <a class="ditty-extension__license__refresh ditty-button protip" href="#" data-extension="<?php echo esc_attr( $extension ); ?>" data-extension_id="<?php echo esc_attr( $setting['item_id'] ); ?>" data-extension_name="<?php echo esc_attr( $data['name'] ); ?>" data-pt-title="<?php _e( 'Refresh License', 'ditty-news-ticker' ); ?>"><i class="fas fa-sync-alt" data-class="fas fa-sync-alt"></i></a>
366
+ <a class="ditty-extension__license__deactivate ditty-button protip" href="#" data-extension="<?php echo esc_attr( $extension ); ?>" data-extension_id="<?php echo esc_attr( $setting['item_id'] ); ?>" data-extension_name="<?php echo esc_attr( $data['name'] ); ?>" data-pt-title="<?php _e( 'Deactive License', 'ditty-news-ticker' ); ?>"><i class="fas fa-times" data-class="fas fa-times"></i></a>
367
+ </div>
368
+ </div>
369
+ <?php
370
+ } else {
371
+ if ( isset( $setting['func'] ) && function_exists( $setting['func'] ) ) {
372
+ call_user_func( $setting['func'] );
373
+ } elseif( isset( $setting['fields'] ) ) {
374
+ ditty_fields( $setting['fields'] );
375
+ $update_button = isset( $setting['update_button'] ) ? $setting['update_button'] : 'default';
376
+ if ( 'disabled' != $update_button ) {
377
+ echo ditty_field(
378
+ array(
379
+ 'type' => 'button',
380
+ 'id' => 'submit',
381
+ 'label' => __( 'Update', 'ditty-news-ticker' ),
382
+ 'priority' => 'primary',
383
+ 'full_width' => true,
384
+ 'icon_after' => 'fas fa-check',
385
+ ),
386
+ );
387
+ }
388
+ }
389
+ }
390
+ ?>
391
+ </form>
392
+ </div>
393
+ <?php
394
+ }
395
+ echo '</div>';
396
+ }
397
+ }
398
+ ?>
399
+ </div>
400
+ </div>
401
+ <?php
402
+ }
403
+
404
+ /**
405
+ * Render the extensions page
406
+ * @access public
407
+ * @since 3.0
408
+ */
409
+ public function extensions_page() {
410
+ if ( wp_doing_ajax() ) {
411
+ return false;
412
+ }
413
+
414
+ $extension_licenses = ditty_extension_licenses();
415
+ $extensions = ditty_extensions();
416
+ if ( isset( $_GET['extension'] ) ) {
417
+ $extensions = array( $_GET['extension'] => $extensions[$_GET['extension']]) + $extensions;
418
+ }
419
+ ?>
420
+ <div id="ditty-page" class="wrap">
421
+
422
+ <div id="ditty-page__header">
423
+ <h2><?php _e( 'Ditty Extensions', 'ditty-news-ticker' ); ?></h2>
424
+ </div>
425
+
426
+ <div id="ditty-page__content">
427
+ <div id="ditty-extensions">
428
+
429
+ <div class="ditty-extensions-group ditty-extensions-group--active">
430
+ <h3><?php _e( 'Active Extensions', 'ditty-news-ticker' ); ?></h3>
431
+ <div class="ditty-extensions-grid">
432
+ <?php
433
+ if ( is_array( $extensions ) && count( $extensions ) > 0 ) {
434
+ foreach ( $extensions as $extension => $data ) {
435
+ if ( isset( $data['preview'] ) ) {
436
+ continue;
437
+ }
438
+ $this->render_extension( $extension, $data, $extension_licenses );
439
+ }
440
+ }
441
+ ?>
442
+ </div>
443
+ </div>
444
+
445
+ <div class="ditty-extensions-group ditty-extensions-group--other">
446
+ <h3><?php _e( 'Additional Ditty Extensions', 'ditty-news-ticker' ); ?></h3>
447
+ <div class="ditty-extensions-grid">
448
+ <?php
449
+ if ( is_array( $extensions ) && count( $extensions ) > 0 ) {
450
+ foreach ( $extensions as $extension => $data ) {
451
+ if ( isset( $data['preview'] ) ) {
452
+ $this->render_extension( $extension, $data, $extension_licenses );
453
+ }
454
+ }
455
+ }
456
+ ?>
457
+ </div>
458
+ </div>
459
+ </div>
460
+
461
+ </div>
462
+ <?php
463
+ }
464
+
465
+ /**
466
+ * Attempt to activate a license
467
+ *
468
+ * @access public
469
+ * @since 3.0
470
+ */
471
+ public function license_activate( $extension, $license_key, $item_id ) {
472
+
473
+ // data to send in our API request
474
+ $api_params = array(
475
+ 'edd_action' => 'activate_license',
476
+ 'license' => $license_key,
477
+ 'item_id' => $item_id, // the name of our product in EDD
478
+ 'url' => home_url(),
479
+ );
480
+
481
+ // Call the custom API.
482
+ $response = wp_remote_post( 'https://www.metaphorcreations.com', array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
483
+ $status = '';
484
+ $error = false;
485
+ $message = '';
486
+
487
+ // make sure the response came back okay
488
+ if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
489
+ $error = 'remote_error';
490
+ if ( is_wp_error( $response ) ) {
491
+ $message = $response->get_error_message();
492
+ } else {
493
+ $message = $this->status_message( 'remote_error', $extension );
494
+ }
495
+ } else {
496
+ $license_data = json_decode( wp_remote_retrieve_body( $response ) );
497
+ if ( false === $license_data->success ) {
498
+ $error = $license_data->error;
499
+ switch( $license_data->error ) {
500
+ case 'expired' :
501
+ $message = sprintf(
502
+ $this->status_message( $license_data->error, $extension ),
503
+ date_i18n( get_option( 'date_format' ), strtotime( $license_data->expires, current_time( 'timestamp' ) ) )
504
+ );
505
+ break;
506
+ default :
507
+ $message = $this->status_message( $license_data->error, $extension );
508
+ break;
509
+ }
510
+ if ( '' == $message ) {
511
+ $error = 'generic_error';
512
+ $message = $this->status_message( 'generic_error', $extension );
513
+ }
514
+ }
515
+ $status = $license_data->license; // will be either "valid" or "invalid"
516
+ $expires = $license_data->expires;
517
+ if ( 'valid' == $status ) {
518
+ $message = $this->status_message( 'valid', $extension );
519
+ }
520
+ $this->update_license( $extension, $license_key, $status, $expires, $error );
521
+ }
522
+
523
+ $data = array(
524
+ 'status' => $status,
525
+ 'error' => $error,
526
+ 'message' => $message,
527
+ 'response' => $response,
528
+ );
529
+ return $data;
530
+ }
531
+ public function license_activate_ajax() {
532
+ check_ajax_referer( 'ditty', 'security' );
533
+ $license_key_ajax = isset( $_POST['license'] ) ? sanitize_text_field( $_POST['license'] ) : false;
534
+ $extension_ajax = isset( $_POST['extension'] ) ? esc_attr( $_POST['extension'] ) : false;
535
+ $extension_id_ajax = isset( $_POST['extension_id'] ) ? intval( $_POST['extension_id'] ) : false;
536
+ $extension_name_ajax = isset( $_POST['extension_name'] ) ? sanitize_text_field( $_POST['extension_name'] ) : false;
537
+ if ( ! $license_key_ajax || ! $extension_id_ajax || ! $extension_ajax ) {
538
+ wp_die();
539
+ }
540
+ $data = $this->license_activate( $extension_ajax, $license_key_ajax, $extension_id_ajax );
541
+ if ( 'valid' == $data['status'] ) {
542
+ $data['license_key'] = substr( $license_key_ajax, 0, -15 ) . '***************';
543
+ }
544
+ wp_send_json( $data );
545
+ }
546
+ public function license_refresh_ajax() {
547
+ check_ajax_referer( 'ditty', 'security' );
548
+ $extension_ajax = isset( $_POST['extension'] ) ? esc_attr( $_POST['extension'] ) : false;
549
+ $extension_id_ajax = isset( $_POST['extension_id'] ) ? intval( $_POST['extension_id'] ) : false;
550
+ $extension_name_ajax = isset( $_POST['extension_name'] ) ? sanitize_text_field( $_POST['extension_name'] ) : false;
551
+ $license = $this->get_license( $extension_ajax );
552
+ if ( ! $extension_id_ajax || ! $extension_ajax || ! isset( $license['key'] ) ) {
553
+ wp_die();
554
+ }
555
+ $data = $this->license_activate( $extension_ajax, $license['key'], $extension_id_ajax );
556
+ wp_send_json( $data );
557
+ }
558
+
559
+ /**
560
+ * Remove a license
561
+ *
562
+ * @access public
563
+ * @since 3.0
564
+ */
565
+ public function license_deactivate( $extension, $license_key, $item_id ) {
566
+
567
+ // data to send in our API request
568
+ $api_params = array(
569
+ 'edd_action' => 'deactivate_license',
570
+ 'license' => $license_key,
571
+ 'item_id' => $item_id, // the name of our product in EDD
572
+ 'url' => home_url(),
573
+ );
574
+
575
+ // Call the custom API.
576
+ $response = wp_remote_post( 'https://www.metaphorcreations.com', array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
577
+ $status = '';
578
+ $error = false;
579
+ $message = '';
580
+
581
+ // make sure the response came back okay
582
+ if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
583
+ $error = 'remote_error';
584
+ if ( is_wp_error( $response ) ) {
585
+ $message = $response->get_error_message();
586
+ } else {
587
+ $message = $this->status_message( 'remote_error', $extension );
588
+ }
589
+ } else {
590
+ $license_data = json_decode( wp_remote_retrieve_body( $response ) );
591
+ $status = $license_data->license; // will be either "deactivated" or "failed"
592
+ $message = $this->status_message( $status, $extension );
593
+ $this->remove_license( $extension );
594
+ }
595
+
596
+ $data = array(
597
+ 'status' => $status,
598
+ 'error' => $error,
599
+ 'message' => $message,
600
+ 'response' => $response,
601
+ 'license_key' => 'DELETE',
602
+ );
603
+ return $data;
604
+ }
605
+ public function license_deactivate_ajax() {
606
+ check_ajax_referer( 'ditty', 'security' );
607
+ $extension_ajax = isset( $_POST['extension'] ) ? esc_attr( $_POST['extension'] ) : false;
608
+ $extension_id_ajax = isset( $_POST['extension_id'] ) ? intval( $_POST['extension_id'] ) : false;
609
+ $extension_name_ajax = isset( $_POST['extension_name'] ) ? sanitize_text_field( $_POST['extension_name'] ) : false;
610
+ $license = $this->get_license( $extension_ajax );
611
+ if ( ! $extension_id_ajax || ! $extension_ajax || ! isset( $license['key'] ) ) {
612
+ wp_die();
613
+ }
614
+ $data = $this->license_deactivate( $extension_ajax, $license['key'], $extension_id_ajax );
615
+ wp_send_json( $data );
616
+ }
617
+
618
+ /**
619
+ * Settings update
620
+ *
621
+ * @access public
622
+ * @since 3.0
623
+ */
624
+ public function panel_update_ajax() {
625
+ check_ajax_referer( 'ditty', 'security' );
626
+
627
+ $extension_ajax = isset( $_POST['extension'] ) ? esc_attr( $_POST['extension'] ) : false;
628
+ $panel_ajax = isset( $_POST['panel'] ) ? esc_attr( $_POST['panel'] ) : false;
629
+ if ( ! $extension_ajax || ! current_user_can( 'manage_ditty_settings' ) ) {
630
+ wp_die();
631
+ }
632
+
633
+ $panel_data = array(
634
+ 'post_data' => $_POST,
635
+ 'extension' => $extension_ajax,
636
+ 'panel' => $panel_ajax,
637
+ );
638
+ $panel_data = apply_filters( 'ditty_extension_panel_update', $panel_data );
639
+ wp_send_json( $panel_data );
640
+ }
641
+
642
+ }
includes/class-ditty-i18n.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Define the internationalization functionality
5
+ *
6
+ * Loads and defines the internationalization files for this plugin
7
+ * so that it is ready for translation.
8
+ *
9
+ * @link https://www.metaphorcreations.com
10
+ * @since 3.0
11
+ *
12
+ * @package Ditty
13
+ * @subpackage Ditty/includes
14
+ */
15
+
16
+ /**
17
+ * Define the internationalization functionality.
18
+ *
19
+ * Loads and defines the internationalization files for this plugin
20
+ * so that it is ready for translation.
21
+ *
22
+ * @since 3.0
23
+ * @package Ditty
24
+ * @subpackage Ditty/includes
25
+ * @author Metaphor Creations <joe@metaphorcreations.com>
26
+ */
27
+ class Ditty_i18n {
28
+
29
+
30
+ /**
31
+ * Load the plugin text domain for translation.
32
+ *
33
+ * @since 3.0
34
+ */
35
+ public function load_plugin_textdomain() {
36
+
37
+ load_plugin_textdomain(
38
+ 'ditty-news-ticker',
39
+ false,
40
+ dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/'
41
+ );
42
+
43
+ }
44
+
45
+
46
+
47
+ }
includes/class-ditty-item-type-default.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Default Type Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Default Type
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Item_Type_Default extends Ditty_Item_Type {
13
+
14
+ /**
15
+ * Slug
16
+ *
17
+ * @since 3.0
18
+ */
19
+ public $slug = 'default';
20
+
21
+ /**
22
+ * Setup the fields
23
+ *
24
+ * @access public
25
+ * @since 3.0
26
+ */
27
+ public function fields( $values = array() ) {
28
+ $fields = array(
29
+ 'content' => array(
30
+ 'type' => 'textarea',
31
+ 'id' => 'content',
32
+ 'name' => __( 'Content', 'ditty-news-ticker' ),
33
+ 'help' => __( 'Add the content of your item. HTML and inline styles are supported.', 'ditty-news-ticker' ),
34
+ 'std' => isset( $values['content'] ) ? $values['content'] : false,
35
+ ),
36
+ 'link_url' => array(
37
+ 'type' => 'text',
38
+ 'id' => 'link_url',
39
+ 'name' => __( 'Link', 'ditty-news-ticker' ),
40
+ 'help' => __( 'Add a custom link to your content. You can also add a link directly into your content.', 'ditty-news-ticker' ),
41
+ 'atts' => array(
42
+ 'type' => 'url',
43
+ ),
44
+ 'std' => isset( $values['link_url'] ) ? $values['link_url'] : false,
45
+ ),
46
+ 'link_title' => array(
47
+ 'type' => 'text',
48
+ 'id' => 'link_title',
49
+ 'name' => __( 'Title', 'ditty-news-ticker' ),
50
+ 'help' => __( 'Add a title to the custom lnk.', 'ditty-news-ticker' ),
51
+ 'std' => isset( $values['link_title'] ) ? $values['link_title'] : false,
52
+ ),
53
+ 'link_target' => array(
54
+ 'type' => 'select',
55
+ 'id' => 'link_target',
56
+ 'name' => __( 'Target', 'ditty-news-ticker' ),
57
+ 'help' => __( 'Set a target for your link.', 'ditty-news-ticker' ),
58
+ 'options' => array(
59
+ '_self' => '_self',
60
+ '_blank' => '_blank'
61
+ ),
62
+ 'std' => isset( $values['link_target'] ) ? $values['link_target'] : false,
63
+ ),
64
+ 'link_nofollow' => array(
65
+ 'type' => 'checkbox',
66
+ 'id' => 'link_nofollow',
67
+ 'name' => __( 'No Follow', 'ditty-news-ticker' ),
68
+ 'label' => __( 'Add "nofollow" to link', 'ditty-news-ticker' ),
69
+ 'help' => __( 'Enabling this setting will add an attribute called \'nofollow\' to your link. This tells search engines to not follow this link.', 'ditty-news-ticker' ),
70
+ 'std' => isset( $values['link_nofollow'] ) ? $values['link_nofollow'] : false,
71
+ ),
72
+ );
73
+ return $fields;
74
+ }
75
+
76
+ /**
77
+ * Set the default field values
78
+ *
79
+ * @access public
80
+ * @since 3.0
81
+ */
82
+ public function default_settings() {
83
+ $defaults = array(
84
+ 'content' => __( 'This is a sample item. Please edit me!', 'ditty-news-ticker' ),
85
+ 'link_url' => '',
86
+ 'link_title' => '',
87
+ 'link_target' => '_self',
88
+ 'link_nofollow' => '',
89
+ );
90
+ return apply_filters( 'ditty_type_default_settings', $defaults, $this->slug );
91
+ }
92
+
93
+ /**
94
+ * Sanitize the settings
95
+ *
96
+ * @access public
97
+ * @since 3.0
98
+ */
99
+ public function sanitize_settings( $values ) {
100
+ $sanitized_fields = array(
101
+ 'content' => isset( $values['content'] ) ? wp_kses_post( $values['content'] ) : false,
102
+ 'link_url' => isset( $values['link_url'] ) ? esc_url_raw( $values['link_url'] ) : false,
103
+ 'link_title' => isset( $values['link_title'] ) ? esc_attr( $values['link_title'] ) : false,
104
+ 'link_target' => isset( $values['link_target'] ) ? esc_attr( $values['link_target'] ) : false,
105
+ 'link_nofollow' => isset( $values['link_nofollow'] ) ? esc_attr( $values['link_nofollow'] ) : false,
106
+ );
107
+ return $sanitized_fields;
108
+ }
109
+
110
+ /**
111
+ * Display the editor preview
112
+ *
113
+ * @since 3.0
114
+ * @access public
115
+ * @var string $preview The editor list display of a item
116
+ */
117
+ public function editor_preview( $value ) {
118
+ if ( ! isset( $value['content'] ) || '' == $value['content'] ) {
119
+ return __( 'No text set...', 'ditty-news-ticker' );
120
+ }
121
+ $preview = stripslashes( wp_html_excerpt( $value['content'], 200, '...' ) );
122
+ return $preview;
123
+ }
124
+ }
includes/class-ditty-item-type-posts-lite.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Item Type Posts Lite class
5
+ *
6
+ * @package Ditty Posts
7
+ * @subpackage Classes/Ditty Item Type Posts Lite
8
+ * @copyright Copyright (c) 2019, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Item_Type_Posts_Lite extends Ditty_Item_Type {
13
+
14
+ /**
15
+ * Slug
16
+ *
17
+ * @since 3.0
18
+ */
19
+ public $slug = 'posts_feed';
20
+
21
+ /**
22
+ * Prepare items for Ditty use
23
+ *
24
+ * @access public
25
+ * @since 3.0
26
+ * @return array
27
+ */
28
+ public function prepare_items( $meta ) {
29
+ $item_value = maybe_unserialize( $meta['item_value'] );
30
+ //ChromePhp::log( '$item_value:', $item_value );
31
+ // Set the query args
32
+ $query_args = array(
33
+ 'posts_per_page' => $item_value['limit'],
34
+ );
35
+ $ditty_posts_query = new WP_Query( $query_args );
36
+
37
+ $prepared_meta = array();
38
+ if ( $ditty_posts_query->have_posts() ) : while ( $ditty_posts_query->have_posts() ) : $ditty_posts_query->the_post();
39
+ global $post;
40
+ $item_value = maybe_unserialize( $meta['item_value'] );
41
+ $item_value['item'] = $post;
42
+
43
+ $ditty_item = $meta;
44
+ $ditty_item['item_uniq_id'] = $ditty_item['item_id'] . '_' . get_the_ID();
45
+ $ditty_item['item_value'] = $item_value;
46
+
47
+ $prepared_meta[] = $ditty_item;
48
+
49
+ endwhile;
50
+ wp_reset_postdata();
51
+ else :
52
+ endif;
53
+
54
+ return $prepared_meta;
55
+ }
56
+
57
+ /**
58
+ * Setup the type settings
59
+ *
60
+ * @access public
61
+ * @since 3.0
62
+ */
63
+ public function fields( $values = array() ) {
64
+ $fields = array(
65
+ 'limit' => array(
66
+ 'type' => 'number',
67
+ 'id' => 'limit',
68
+ 'name' => __( 'Limit', 'ditty-news-ticker' ),
69
+ 'help' => __( 'Set the number of Posts to display.', 'ditty-news-ticker' ),
70
+ 'std' => isset( $values['limit'] ) ? $values['limit'] : false,
71
+ ),
72
+ );
73
+ return $fields;
74
+ }
75
+
76
+ /**
77
+ * Set the default field values
78
+ *
79
+ * @access public
80
+ * @since 3.0
81
+ */
82
+ public function default_settings() {
83
+ $defaults = array(
84
+ 'limit' => 10,
85
+ );
86
+ return apply_filters( 'ditty_type_default_settings', $defaults, $this->slug );
87
+ }
88
+
89
+ /**
90
+ * Set the default layout variation types
91
+ *
92
+ * @access public
93
+ * @since 3.0
94
+ */
95
+ public function get_layout_variation_types() {
96
+ $layout_variations = array(
97
+ 'default' => array(
98
+ 'template' => 'default_post',
99
+ 'label' => __( 'Default', 'ditty-news-ticker' ),
100
+ 'description' => __( 'Default variation.', 'ditty-news-ticker' ),
101
+ ),
102
+ );
103
+ return apply_filters( 'ditty_item_type_variation_types', $layout_variations, $this );
104
+ }
105
+
106
+ /**
107
+ * Display the editor preview
108
+ *
109
+ * @since 3.0
110
+ * @access public
111
+ * @var string $preview The editor list display of a item
112
+ */
113
+ public function editor_preview( $value ) {
114
+ $defaults = $this->default_settings();
115
+ $args = wp_parse_args( $value, $defaults );
116
+ $preview = sprintf( __( 'Displaying %d Posts' ), $args['limit'] );
117
+ return $preview;
118
+ }
119
+ }
includes/class-ditty-item-type-wp-editor.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Item Type WP Editor Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty WP Editor Type
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Item_Type_WP_Editor extends Ditty_Item_Type {
13
+
14
+ /**
15
+ * Slug
16
+ *
17
+ * @since 3.0
18
+ */
19
+ public $slug = 'wp_editor';
20
+
21
+ /**
22
+ * Setup the type settings
23
+ *
24
+ * @access public
25
+ * @since 3.0
26
+ */
27
+ public function fields( $values = array() ) {
28
+ $fields = array(
29
+ 'content' => array(
30
+ 'type' => 'wysiwyg',
31
+ 'id' => 'content',
32
+ 'name' => __( 'Content', 'ditty-news-ticker' ),
33
+ 'help' => __( 'Add the content of your item. HTML and inline styles are supported.', 'ditty-news-ticker' ),
34
+ 'std' => isset( $values['content'] ) ? $values['content'] : false,
35
+ ),
36
+ );
37
+ return $fields;
38
+ }
39
+
40
+ /**
41
+ * Set the default field values
42
+ *
43
+ * @access public
44
+ * @since 3.0
45
+ */
46
+ public function default_settings() {
47
+ $defaults = array(
48
+ 'content' => __( 'This is a sample item. Please edit me!', 'ditty-news-ticker' ),
49
+ );
50
+ return apply_filters( 'ditty_type_default_settings', $defaults, $this->slug );
51
+ }
52
+
53
+ /**
54
+ * Display the editor preview
55
+ *
56
+ * @since 3.0
57
+ * @access public
58
+ * @var string $preview The editor list display of a item
59
+ */
60
+ public function editor_preview( $value ) {
61
+ if ( ! isset( $value['content'] ) || '' == $value['content'] ) {
62
+ return __( 'No content set...', 'ditty-news-ticker' );
63
+ }
64
+
65
+ $preview = stripslashes( wp_html_excerpt( $value['content'], 200, '...' ) );
66
+ return $preview;
67
+ }
68
+ }
includes/class-ditty-item-type.php ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Item Type Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Item Type
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Item_Type {
13
+
14
+ public $slug = 'none';
15
+ public $type;
16
+ public $label;
17
+ public $icon;
18
+ public $description;
19
+ public $script_id;
20
+
21
+ /**
22
+ * Get things started
23
+ *
24
+ * @access public
25
+ * @since 3.0
26
+ */
27
+ public function __construct() {
28
+ $item_types = ditty_item_types();
29
+ if ( isset( $item_types[$this->slug] ) ) {
30
+ $this->type = $item_types[$this->slug]['type'];
31
+ $this->label = $item_types[$this->slug]['label'];
32
+ $this->icon = $item_types[$this->slug]['icon'];
33
+ $this->description = $item_types[$this->slug]['description'];
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Prepare items for Ditty use
39
+ *
40
+ * @access public
41
+ * @since 3.0
42
+ * @return array
43
+ */
44
+ public function prepare_items( $meta ) {
45
+ $ditty_item = $meta;
46
+ return array( $ditty_item );
47
+ }
48
+
49
+ /**
50
+ * Return the type
51
+ *
52
+ * @access public
53
+ * @since 3.0
54
+ * @return string $type
55
+ */
56
+ public function get_type() {
57
+ return $this->type;
58
+ }
59
+
60
+ /**
61
+ * Return the label
62
+ *
63
+ * @access public
64
+ * @since 3.0
65
+ * @return string $label
66
+ */
67
+ public function get_label() {
68
+ return $this->label;
69
+ }
70
+
71
+ /**
72
+ * Return the icon
73
+ *
74
+ * @access public
75
+ * @since 3.0
76
+ * @return string $icon
77
+ */
78
+ public function get_icon() {
79
+ return $this->icon;
80
+ }
81
+
82
+ /**
83
+ * Return the description
84
+ *
85
+ * @access public
86
+ * @since 3.0
87
+ * @return string $description
88
+ *
89
+ */
90
+ public function get_description() {
91
+ return $this->description;
92
+ }
93
+
94
+ /**
95
+ * Return the script id
96
+ *
97
+ * @access public
98
+ * @since 3.0
99
+ * @return string $script_id
100
+ *
101
+ */
102
+ public function get_script_id() {
103
+ if ( ! empty( $this->script_id ) ) {
104
+ return $this->script_id;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Setup the type settings
110
+ *
111
+ * @access public
112
+ * @since 3.0
113
+ */
114
+ public function settings( $item_values = false, $action = 'render' ) {
115
+ $values = $this->get_values( $item_values );
116
+ $fields = $this->fields( $values );
117
+ ditty_fields( $fields, $values, $action );
118
+ }
119
+
120
+ /**
121
+ * Get values to populate the metabox
122
+ *
123
+ * @access public
124
+ * @since 3.0
125
+ */
126
+ public function get_values( $item_values=false ) {
127
+ $defaults = $this->default_settings();
128
+ if ( ! $item_values ) {
129
+ return $defaults;
130
+ }
131
+ $values = wp_parse_args( $item_values, $defaults );
132
+ return $values;
133
+ }
134
+
135
+ /**
136
+ * Get values to populate the metabox
137
+ *
138
+ * @access public
139
+ * @since 3.0
140
+ */
141
+ public function get_layout_variation_types() {
142
+ $layout_variations = array(
143
+ 'default' => array(
144
+ 'template' => 'default',
145
+ 'label' => __( 'Default', 'ditty-news-ticker' ),
146
+ 'description' => __( 'Default variation.', 'ditty-news-ticker' ),
147
+ ),
148
+ );
149
+ return apply_filters( 'ditty_item_type_variation_types', $layout_variations, $this );
150
+ }
151
+
152
+ /**
153
+ * Get values to populate the metabox
154
+ *
155
+ * @access public
156
+ * @since 3.0
157
+ */
158
+ public function get_layout_variation_defaults( $type = false ) {
159
+ global $ditty_layout_confirmed_defaults;
160
+ if ( ! empty( $ditty_layout_confirmed_defaults ) ) {
161
+ $ditty_layout_confirmed_defaults = array();
162
+ }
163
+ if ( ! isset( $ditty_layout_confirmed_defaults[$this->get_type()] ) ) {
164
+ $ditty_layout_confirmed_defaults[$this->get_type()] = array();
165
+
166
+ $all_variation_defaults = ditty_settings( 'variation_defaults' );
167
+ $variation_defaults = isset( $all_variation_defaults[$this->get_type()] ) ? $all_variation_defaults[$this->get_type()] : array();
168
+ $variation_types = $this->get_layout_variation_types();
169
+
170
+ if ( is_array( $variation_types ) && count( $variation_types ) > 0 ) {
171
+ foreach ( $variation_types as $slug => $data ) {
172
+ $ditty_layout_confirmed_defaults[$this->get_type()][$slug] = isset( $variation_defaults[$slug] ) ? $variation_defaults[$slug] : 0;
173
+ }
174
+ }
175
+ }
176
+
177
+ if ( $type ) {
178
+ if ( isset( $ditty_layout_confirmed_defaults[$this->get_type()][$type] ) ) {
179
+ return $ditty_layout_confirmed_defaults[$this->get_type()][$type];
180
+ }
181
+ } else {
182
+ return $ditty_layout_confirmed_defaults[$this->get_type()];
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Confirm the layout variations
188
+ *
189
+ * @access public
190
+ * @since 3.0
191
+ */
192
+ public function confirm_layout_variations( $layout_value = array() ) {
193
+ $defaults = $this->get_layout_variation_defaults();
194
+ $args = shortcode_atts( $defaults, $layout_value );
195
+ return $args;
196
+ }
197
+
198
+ /**
199
+ * Get layout variation data
200
+ *
201
+ * @access public
202
+ * @since 3.0
203
+ */
204
+ public function get_layout_variation_data( $layout_value = array() ) {
205
+ $variation_types = $this->get_layout_variation_types();
206
+ $confirmed = $this->confirm_layout_variations( $layout_value );
207
+ $variation_data = array();
208
+ if ( is_array( $variation_types ) && count( $variation_types ) > 0 ) {
209
+ foreach ( $variation_types as $slug => $data ) {
210
+ $variation_data[$slug] = $data;
211
+ $variation_data[$slug]['template'] = $confirmed[$slug];
212
+ }
213
+ }
214
+ return $variation_data;
215
+ }
216
+
217
+ /**
218
+ * Update values sent from the editor
219
+ *
220
+ * @access public
221
+ * @since 3.0
222
+ */
223
+ public function sanitize_settings( $values ) {
224
+ $fields = $this->fields();
225
+ return ditty_sanitize_fields( $fields, $values, "ditty_item_type_{$this->get_type()}" );
226
+ }
227
+
228
+ /**
229
+ * Display the editor preview
230
+ *
231
+ * @since 3.0
232
+ * @access public
233
+ * @var string $preview The editor list display of a item
234
+ */
235
+ public function editor_preview( $value ) {
236
+ return '';
237
+ }
238
+ }
includes/class-ditty-item.php ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ditty Item Class
4
+ *
5
+ * @package Ditty
6
+ * @subpackage Classes/Ditty Item
7
+ * @copyright Copyright (c) 2021, Metaphor Creations
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 3.0
10
+ */
11
+ class Ditty_Item {
12
+
13
+ private $item_id;
14
+ private $item_uniq_id;
15
+ private $ditty_id;
16
+ private $item_type;
17
+ private $layout_value;
18
+ private $item_value;
19
+ private $item_index;
20
+ private $icon;
21
+ private $label;
22
+ private $item_type_object;
23
+
24
+ /**
25
+ * Get things started
26
+ * @access public
27
+ * @since 3.0
28
+ */
29
+ public function __construct( $id = false ) {
30
+ $this->item_id = -1;
31
+ $this->item_uniq_id = -1;
32
+ $this->item_type = 'default';
33
+ $this->layout_value = false;
34
+ $this->icon = 'fas fa-exclamation-circle';
35
+ $this->label = __( 'No text set...', 'ditty-news-ticker' );
36
+ $this->item_value = '';
37
+ $this->index = 0;
38
+
39
+ if ( is_ditty_post() ) {
40
+ $this->ditty_id = isset( $_GET['post'] ) ? $_GET['post'] : false;
41
+ }
42
+ if ( is_array( $id ) ) {
43
+ $meta = $this->parse_draft_data( $id['item_id'], $id );
44
+ } elseif ( is_object( $id ) ) {
45
+ $meta = $this->parse_draft_data( $id->item_id, $id );
46
+ } elseif ( is_numeric( $id ) ) {
47
+ $meta = $this->parse_draft_data( $id, Ditty()->db_items->get( $id ) );
48
+ } elseif ( strpos( $id, 'new-' ) !== false ) {
49
+ $meta = $this->parse_draft_data( $id );
50
+ }
51
+ if ( $meta ) {
52
+ $this->construct_from_meta( $meta );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Parse the draft data
58
+ * @access public
59
+ * @since 3.0
60
+ * @return int $id
61
+ */
62
+ public function parse_draft_data( $item_id, $meta = array() ) {
63
+ $draft_values = ditty_draft_item_get_data( $item_id );
64
+
65
+ if ( is_object( $meta ) ) {
66
+ $meta = ( array ) $meta;
67
+ }
68
+ if ( ! $draft_values ) {
69
+ return $meta;
70
+ }
71
+ $meta['item_id'] = isset( $draft_values['item_id'] ) ? $draft_values['item_id'] : ( isset( $meta['item_id'] ) ? $meta['item_id'] : $this->item_id );
72
+ $meta['ditty_id'] = isset( $draft_values['ditty_id'] ) ? $draft_values['ditty_id'] : ( isset( $meta['ditty_id'] ) ? $meta['ditty_id'] : $this->ditty_id );
73
+ $meta['item_type'] = isset( $draft_values['item_type'] ) ? $draft_values['item_type'] : ( isset( $meta['item_type'] ) ? $meta['item_type'] : $this->item_type );
74
+ $meta['item_value'] = isset( $draft_values['item_value'] ) ? $draft_values['item_value'] : ( isset( $meta['item_value'] ) ? $meta['item_value'] : $this->item_value );
75
+ $meta['layout_value'] = isset( $draft_values['layout_value'] ) ? $draft_values['layout_value'] : ( isset( $meta['layout_value'] ) ? $meta['layout_value'] : $this->layout_value );
76
+ $meta['item_index'] = isset( $draft_values['item_index'] ) ? $draft_values['item_index'] : ( isset( $meta['item_index'] ) ? $meta['item_index'] : $this->item_index );
77
+ return $meta;
78
+ }
79
+
80
+ /**
81
+ * Construct the class from meta
82
+ * @access public
83
+ * @since 3.0
84
+ * @return int $id
85
+ */
86
+ public function construct_from_meta( $meta ) {
87
+ if ( ! $meta ) {
88
+ return false;
89
+ }
90
+ if ( is_object( $meta ) ) {
91
+ $meta = ( array ) $meta;
92
+ }
93
+ if ( is_array( $meta ) ) {
94
+ $this->item_id = isset( $meta['item_id'] ) ? $meta['item_id'] : $this->item_id;
95
+ $this->item_uniq_id = isset( $meta['item_uniq_id'] ) ? $meta['item_uniq_id'] : $this->item_id;
96
+ $this->ditty_id = isset( $meta['ditty_id'] ) ? $meta['ditty_id'] : $this->ditty_id;
97
+ $this->item_type = isset( $meta['item_type'] ) ? $meta['item_type'] : $this->item_type;
98
+ $this->layout_value = isset( $meta['layout_value'] ) ? maybe_unserialize( $meta['layout_value'] ) : $this->layout_value;
99
+ $this->item_value = isset( $meta['item_value'] ) ? maybe_unserialize( $meta['item_value'] ) : false;
100
+ $this->item_index = isset( $meta['item_index'] ) ? $meta['item_index'] : $this->item_index;
101
+ if ( $item_type_object = $this->get_type_object() ) {
102
+ $this->icon = $item_type_object->get_icon();
103
+ $this->label = $item_type_object->get_label();
104
+ $this->layout_value = $item_type_object->confirm_layout_variations( $this->layout_value );
105
+ }
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Return the database data for the item
111
+ * @access public
112
+ * @since 3.0
113
+ * @return string $db_data
114
+ */
115
+ public function get_db_data() {
116
+ $db_data = array(
117
+ 'item_id' => $this->get_id(),
118
+ 'item_type' => $this->get_type(),
119
+ 'item_value' => $this->get_value(),
120
+ 'ditty_id' => $this->get_ditty_id(),
121
+ 'layout_value' => $this->get_layout_value(),
122
+ 'item_index' => $this->get_index(),
123
+ );
124
+ return $db_data;
125
+ }
126
+
127
+ /**
128
+ * Return the item id
129
+ * @access public
130
+ * @since 3.0
131
+ * @return int $id
132
+ */
133
+ public function get_id() {
134
+ return $this->item_id;
135
+ }
136
+
137
+ /**
138
+ * Set the item id
139
+ * @access public
140
+ * @since 3.0
141
+ * @return int $id
142
+ */
143
+ public function set_id( $item_id ) {
144
+ $this->item_id = $item_id;
145
+ return $this->item_id;
146
+ }
147
+
148
+ /**
149
+ * Return the item base id
150
+ * @access public
151
+ * @since 3.0
152
+ * @return int $id
153
+ */
154
+ public function get_uniq_id() {
155
+ return $this->item_uniq_id;
156
+ }
157
+
158
+ /**
159
+ * Return the Ditty id
160
+ * @access public
161
+ * @since 3.0
162
+ * @return int $ditty_id
163
+ */
164
+ public function get_ditty_id() {
165
+ return $this->ditty_id;
166
+ }
167
+
168
+ /**
169
+ * Return the Ditty id
170
+ * @access public
171
+ * @since 3.0
172
+ * @return int $ditty_id
173
+ */
174
+ public function set_ditty_id( $ditty_id ) {
175
+ $this->ditty_id = $ditty_id;
176
+ return $this->ditty_id;
177
+ }
178
+
179
+ /**
180
+ * Return the item type object
181
+ * @access public
182
+ * @since 3.0
183
+ * @return int $item_type_object
184
+ */
185
+ public function get_type_object() {
186
+ if ( ! $this->item_type_object ) {
187
+ $this->item_type_object = ditty_item_type_object( $this->item_type );
188
+ }
189
+ return $this->item_type_object;
190
+ }
191
+
192
+ /**
193
+ * Return the item type settings fields
194
+ * @access public
195
+ * @since 3.0
196
+ * @return int $ditty_id
197
+ */
198
+ public function get_setting_fields() {
199
+ $item_type_object = $this->get_type_object();
200
+ return $item_type_object->settings( $this->get_value() );
201
+ }
202
+
203
+ /**
204
+ * Return the item type
205
+ * @access public
206
+ * @since 3.0
207
+ * @return string $type
208
+ */
209
+ public function get_type() {
210
+ return $this->item_type;
211
+ }
212
+
213
+ /**
214
+ * Set the item type
215
+ * @access public
216
+ * @since 3.0
217
+ * @return null
218
+ */
219
+ public function set_item_type( $item_type ) {
220
+ $item_types = ditty_item_types();
221
+ if ( ! isset( $item_types[$item_type] ) ) {
222
+ return false;
223
+ }
224
+ if ( $item_type == $this->item_type ) {
225
+ return false;
226
+ }
227
+ $this->item_type = $item_type;
228
+
229
+ if ( $item_type_object = ditty_item_type_object( $this->item_type ) ) {
230
+ $this->item_type_object = $item_type_object;
231
+ $this->icon = $item_type_object->get_icon();
232
+ $this->label = $item_type_object->get_label();
233
+ $this->layout_value = $item_type_object->get_layout_variation_defaults();
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Return the item layout value
239
+ *
240
+ * @access public
241
+ * @since 3.0
242
+ * @return array $layout_value
243
+ */
244
+ public function get_layout_value() {
245
+ return $this->layout_value;
246
+ }
247
+
248
+ /**
249
+ * Set the item layout value
250
+ *
251
+ * @access public
252
+ * @since 3.0
253
+ * @return null
254
+ */
255
+ public function set_layout_value( $layout_value ) {
256
+ $this->layout_value = $layout_value;
257
+ }
258
+
259
+ /**
260
+ * Return the item value
261
+ * @access public
262
+ * @since 3.0
263
+ * @return string $label
264
+ */
265
+ public function get_value() {
266
+ return stripslashes_deep( maybe_unserialize( $this->item_value ) );
267
+ }
268
+
269
+ /**
270
+ * Set the item value
271
+ * @access public
272
+ * @since 3.0
273
+ * @return array $sanitized_item_value
274
+ */
275
+ public function set_item_value( $item_value = array() ) {
276
+ if ( $item_type_object = $this->get_type_object() ) {
277
+ $sanitized_item_value = $item_type_object->sanitize_settings( $item_value );
278
+ $this->item_value = maybe_serialize( $sanitized_item_value );
279
+ return $sanitized_item_value;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Return the item index
285
+ * @access public
286
+ * @since 3.0
287
+ * @return int $item_index
288
+ */
289
+ public function get_index() {
290
+ if ( $this->item_index ) {
291
+ return $this->item_index;
292
+ } else {
293
+ return 0;
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Set the item value
299
+ * @access public
300
+ * @since 3.0
301
+ * @return int $item_index
302
+ */
303
+ public function set_item_index( $item_index ) {
304
+ $this->item_index = $item_index;
305
+ return $this->item_index;
306
+ }
307
+
308
+ /**
309
+ * Return the item icon
310
+ * @access public
311
+ * @since 3.0
312
+ * @return string $icon
313
+ */
314
+ public function get_icon() {
315
+ return $this->icon;
316
+ }
317
+
318
+ /**
319
+ * Return the item label
320
+ * @access public
321
+ * @since 3.0
322
+ * @return string $label
323
+ */
324
+ public function get_label() {
325
+ return $this->label;
326
+ }
327
+
328
+ /**
329
+ * Get the current item values
330
+ *
331
+ * @access public
332
+ * @since 3.0
333
+ */
334
+ public function get_values() {
335
+ $values = array(
336
+ 'item_id' => $this->get_id(),
337
+ 'ditty_id' => $this->get_ditty_id(),
338
+ 'item_type' => $this->get_type(),
339
+ 'item_value' => $this->get_value(),
340
+ 'layout_value' => $this->get_layout_value(),
341
+ );
342
+ return $values;
343
+ }
344
+
345
+ /**
346
+ * Return all custom meta for the item
347
+ * @access public
348
+ * @since 3.0
349
+ * @return string meta
350
+ */
351
+ public function custom_meta() {
352
+ return ditty_item_custom_meta( $this->item_id );
353
+ }
354
+
355
+ /**
356
+ * Return the item preview
357
+ * @access public
358
+ * @since 3.0
359
+ * @return string $label
360
+ */
361
+ public function get_preview() {
362
+ if ( $item_type_object = $this->get_type_object() ) {
363
+ return stripslashes( $item_type_object->editor_preview( $this->get_value() ) );
364
+ } else {
365
+ return sprintf( __( '<strong>%s</strong> item type does not exist!', 'ditty-news-ticker' ), $this->get_type() );
366
+ }
367
+ }
368
+
369
+ /**
370
+ * Setup the edito item classes
371
+ * @access public
372
+ * @since 3.0
373
+ * @return string $classes
374
+ */
375
+ public function get_editor_classes() {
376
+ $classes = array();
377
+ $classes[] = 'ditty-data-list__item';
378
+ $classes[] = 'ditty-editor-item';
379
+ $classes[] = 'ditty-editor-item--' . esc_attr( $this->get_type() );
380
+ if ( ! $this->get_type_object() ) {
381
+ $classes[] = 'ditty-editor-item--error';
382
+ }
383
+ if ( apply_filters( 'ditty_editor_item_disabled', false, $this->get_id() ) ) {
384
+ $classes[] = 'ditty-editor-item--disabled';
385
+ }
386
+ $classes = apply_filters( 'ditty_editor_item_classes', $classes, $this );
387
+ return implode( ' ', $classes );
388
+ }
389
+
390
+ /**
391
+ * Render the admin edit row
392
+ * @access public
393
+ * @since 3.0
394
+ * @return html
395
+ */
396
+ public function render_editor_list_item( $render='echo' ) {
397
+ if ( 'return' == $render ) {
398
+ ob_start();
399
+ }
400
+ $atts = array(
401
+ 'id' => 'ditty-editor-item--' . $this->get_id(),
402
+ 'class' => $this->get_editor_classes(),
403
+ 'data-ditty_id' => $this->get_ditty_id(),
404
+ 'data-item_id' => $this->get_id(),
405
+ 'data-item_type' => $this->get_type(),
406
+ 'data-item_value' => json_encode( $this->get_value() ),
407
+ 'data-layout_value' => json_encode( $this->get_layout_value() ),
408
+ );
409
+ ?>
410
+ <div <?php echo ditty_attr_to_html( $atts ); ?>>
411
+ <?php do_action( 'ditty_editor_item_elements', $this ); ?>
412
+ </div>
413
+ <?php
414
+ if ( 'return' == $render ) {
415
+ return trim( ob_get_clean() );
416
+ }
417
+ }
418
+
419
+ /**
420
+ * Return the display meta
421
+ *
422
+ * @access public
423
+ * @since 3.0
424
+ * @return array $display_meta
425
+ */
426
+ // public function get_display_meta() {
427
+ // $item_type_object = $this->get_type_object();
428
+ // if ( ! $item_type_object ) {
429
+ // return false;
430
+ // }
431
+ // $display_meta = $item_type_object->prepare_items( $this->get_values() );
432
+ // return $display_meta;
433
+ // }
434
+
435
+ /**
436
+ * Return the display items
437
+ *
438
+ * @access public
439
+ * @since 3.0
440
+ * @return array $display_items
441
+ */
442
+ public function get_display_items() {
443
+ $display_meta = ditty_prepare_display_items( $this->get_values() );
444
+ $display_items = array();
445
+ if ( is_array( $display_meta ) && count( $display_meta ) > 0 ) {
446
+ foreach ( $display_meta as $i => $meta ) {
447
+ $display_item = new Ditty_Display_Item( $meta );
448
+ if ( $data = $display_item->compile_data() ) {
449
+ $display_items[] = $data;
450
+ }
451
+ }
452
+ }
453
+ return $display_items;
454
+ }
455
+
456
+ }
includes/class-ditty-items.php ADDED
@@ -0,0 +1,486 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ditty Items
4
+ *
5
+ * @package Ditty
6
+ * @subpackage Classes/Ditty Items
7
+ * @copyright Copyright (c) 2021, Metaphor Creations
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 3.0
10
+ */
11
+ class Ditty_Items {
12
+
13
+
14
+ /**
15
+ * Get things started
16
+ * @access public
17
+ * @since 3.0
18
+ */
19
+ public function __construct() {
20
+ // Include external class files
21
+ //add_action( 'plugins_loaded', array( $this, 'includes' ), 1 );
22
+
23
+ // General item filters
24
+ add_filter( 'ditty_type_css_selectors', array( $this, 'global_css_selectors' ) );
25
+
26
+ // Editor elements
27
+ add_action( 'ditty_editor_tabs', array( $this, 'editor_tab' ), 5, 2 );
28
+ add_action( 'ditty_editor_panels', array( $this, 'editor_items_panel' ), 10, 2 );
29
+ add_action( 'ditty_editor_panels', array( $this, 'editor_item_types_panel' ), 10, 2 );
30
+
31
+ // Item elements
32
+ add_action( 'ditty_editor_item_elements', array( $this, 'editor_item_icon' ), 5 );
33
+ add_action( 'ditty_editor_item_elements', array( $this, 'editor_item_label' ), 10 );
34
+ add_action( 'ditty_editor_item_elements', array( $this, 'editor_item_edit' ), 15 );
35
+ add_action( 'ditty_editor_item_elements', array( $this, 'editor_item_layout' ), 20 );
36
+ add_action( 'ditty_editor_item_elements', array( $this, 'editor_item_clone' ), 25 );
37
+ add_action( 'ditty_editor_item_elements', array( $this, 'editor_item_delete' ), 30 );
38
+ add_action( 'ditty_editor_item_elements', array( $this, 'editor_item_move' ), 35 );
39
+
40
+ // Ajax
41
+ //add_action( 'wp_ajax_ditty_editor_item_types', array( $this, 'editor_item_types_ajax' ) );
42
+ //add_action( 'wp_ajax_nopriv_ditty_editor_item_types', array( $this, 'editor_item_types_ajax' ) );
43
+ add_action( 'wp_ajax_ditty_editor_item_type_update', array( $this, 'editor_item_type_update_ajax' ) );
44
+ add_action( 'wp_ajax_nopriv_ditty_editor_item_type_update', array( $this, 'editor_item_type_update_ajax' ) );
45
+
46
+ add_action( 'wp_ajax_ditty_editor_item_fields', array( $this, 'editor_fields_ajax' ) );
47
+ add_action( 'wp_ajax_nopriv_ditty_editor_item_fields', array( $this, 'editor_fields_ajax' ) );
48
+
49
+ add_action( 'wp_ajax_ditty_editor_item_update', array( $this, 'editor_item_update_ajax' ) );
50
+ add_action( 'wp_ajax_nopriv_ditty_editor_item_update', array( $this, 'editor_item_update_ajax' ) );
51
+
52
+ add_action( 'wp_ajax_ditty_editor_item_add', array( $this, 'editor_item_add_ajax' ) );
53
+ add_action( 'wp_ajax_nopriv_ditty_editor_item_add', array( $this, 'editor_item_add_ajax' ) );
54
+ add_action( 'wp_ajax_ditty_editor_item_clone', array( $this, 'editor_item_clone_ajax' ) );
55
+ add_action( 'wp_ajax_nopriv_ditty_editor_item_clone', array( $this, 'editor_item_clone_ajax' ) );
56
+ add_action( 'wp_ajax_ditty_editor_item_index_update', array( $this, 'editor_item_index_update_ajax' ) );
57
+ add_action( 'wp_ajax_nopriv_ditty_editor_item_index_update', array( $this, 'editor_item_index_update_ajax' ) );
58
+ }
59
+
60
+ /**
61
+ * Load the required dependencies for the item types.
62
+ *
63
+ * @access private
64
+ * @since 3.0
65
+ */
66
+ // public function includes() {
67
+ // require_once DITTY_DIR . 'includes/class-ditty-item-type.php';
68
+ // $item_types = ditty_item_types();
69
+ // if ( is_array( $item_types ) && count( $item_types ) > 0 ) {
70
+ // foreach ( $item_types as $i => $type ) {
71
+ // if ( isset( $type['class_path'] ) ) {
72
+ // require_once $type['class_path'];
73
+ // }
74
+ // }
75
+ // }
76
+ // }
77
+
78
+ /**
79
+ * Add global css selectors for item types
80
+ *
81
+ * @access private
82
+ * @since 3.0
83
+ * @return array $selectors
84
+ */
85
+ public function global_css_selectors( $selectors ) {
86
+ $globals = array(
87
+ 'elements' => array(
88
+ 'selector' => '.ditty-item__elements',
89
+ 'description' => __( 'The item elements container', 'ditty-news-ticker' ),
90
+ ),
91
+ );
92
+
93
+ return $globals + $selectors;
94
+ }
95
+
96
+ /**
97
+ * Add the editor item icon
98
+ *
99
+ * @since 3.0
100
+ */
101
+ public function editor_item_icon( $item ) {
102
+ if ( current_user_can( 'edit_ditty_items' ) ) {
103
+ echo '<a href="#" class="ditty-data-list__item__icon protip" data-pt-title="' . __( 'Change Type', 'ditty-news-ticker' ) . '" data-pt-position="top-left"><i class="' . $item->get_icon() . '" data-class="' . $item->get_icon() . '"></i></a>';
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Add the editor item label
109
+ *
110
+ * @since 3.0
111
+ */
112
+ public function editor_item_label( $item ) {
113
+ ?>
114
+ <span class="ditty-data-list__item__label"><?php echo $item->get_preview(); ?></span>
115
+ <?php
116
+ }
117
+
118
+ /**
119
+ * Add the editor move button
120
+ *
121
+ * @since 3.0
122
+ */
123
+ public function editor_item_move( $item ) {
124
+ if ( current_user_can( 'edit_ditty_items' ) ) {
125
+ echo '<a href="#" class="ditty-data-list__item__move protip" data-pt-title="' . __( 'Re-arrange', 'ditty-news-ticker' ) . '"><i class="fas fa-bars" data-class="fas fa-bars"></i></a>';
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Add the editor edit button
131
+ *
132
+ * @since 3.0
133
+ */
134
+ public function editor_item_edit( $item ) {
135
+ if ( current_user_can( 'edit_ditty_items' ) ) {
136
+ echo '<a href="#" class="ditty-data-list__item__edit protip" data-pt-title="' . __( 'Edit Item', 'ditty-news-ticker' ) . '"><i class="fas fa-edit" data-class="fas fa-edit"></i></a>';
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Add the editor layout button
142
+ *
143
+ * @since 3.0
144
+ */
145
+ public function editor_item_layout( $item ) {
146
+ if ( current_user_can( 'edit_ditty_items' ) ) {
147
+ echo '<a href="#" class="ditty-data-list__item__layout protip" data-pt-title="' . __( 'Edit Layout', 'ditty-news-ticker' ) . '"><i class="fas fa-pencil-ruler" data-class="fas fa-pencil-ruler"></i></a>';
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Add the editor clone button
153
+ *
154
+ * @since 3.0
155
+ */
156
+ public function editor_item_clone( $item ) {
157
+ if ( current_user_can( 'publish_ditty_items' ) ) {
158
+ echo '<a href="#" class="ditty-data-list__item__clone protip" data-pt-title="' . __( 'Clone', 'ditty-news-ticker' ) . '"><i class="fas fa-clone" data-class="fas fa-clone"></i></a>';
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Add the editor delete button
164
+ *
165
+ * @since 3.0
166
+ */
167
+ public function editor_item_delete( $item ) {
168
+ if ( current_user_can( 'delete_ditty_items' ) ) {
169
+ echo '<a href="#" class="ditty-data-list__item__delete protip" data-pt-title="' . __( 'Delete', 'ditty-news-ticker' ) . '"><i class="fas fa-trash-alt" data-class="fas fa-trash-alt"></i></a>';
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Add to the editor tabs
175
+ *
176
+ * @access public
177
+ * @since 3.0
178
+ * @param $html
179
+ */
180
+ public function editor_tab( $tabs, $ditty_id ) {
181
+ if ( ! current_user_can( 'edit_ditty_items' ) ) {
182
+ return false;
183
+ }
184
+ $tabs['items'] = array(
185
+ 'icon' => 'fas fa-stream',
186
+ 'label' => __( 'Items', 'ditty-news-ticker' ),
187
+ );
188
+ return $tabs;
189
+ }
190
+
191
+ /**
192
+ * Add the editor items panel
193
+ *
194
+ * @access public
195
+ * @since 3.0
196
+ * @param $html
197
+ */
198
+ public function editor_items_panel( $panels, $ditty_id ) {
199
+ if ( ! current_user_can( 'edit_dittys' ) ) {
200
+ return false;
201
+ }
202
+ ob_start();
203
+ ?>
204
+ <div class="ditty-editor-options ditty-metabox">
205
+ <div class="ditty-editor-options__contents">
206
+ <div class="ditty-editor-options__header">
207
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--end">
208
+ <a class="ditty-editor-options__add ditty-button ditty-button--small" href="#"><i class="fas fa-plus-circle"></i> <?php _e( 'Add Item', 'ditty-news-ticker' ); ?></a>
209
+ </div>
210
+ </div>
211
+ <div class="ditty-data-list">
212
+ <div class="ditty-data-list__items">
213
+ <?php
214
+ $items_meta = ditty_items_meta( $ditty_id );
215
+ if ( is_array( $items_meta ) && count( $items_meta ) > 0 ) {
216
+ foreach ( $items_meta as $i => $meta ) {
217
+ $editor_item = new Ditty_Item( $meta );
218
+ echo $editor_item->render_editor_list_item( 'return' );
219
+ }
220
+ }
221
+ ?>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+ <?php
227
+ $panels['items'] = ob_get_clean();
228
+ return $panels;
229
+ }
230
+
231
+ /**
232
+ * Add the editor item types panel
233
+ *
234
+ * @access public
235
+ * @since 3.0
236
+ */
237
+ public function editor_item_types_panel( $panels, $ditty_id ) {
238
+ if ( ! current_user_can( 'edit_dittys' ) ) {
239
+ return false;
240
+ }
241
+ ob_start();
242
+ ?>
243
+ <div class="ditty-editor-options ditty-metabox" data-ditty_id="<?php echo $ditty_id; ?>">
244
+ <div class="ditty-editor-options__contents">
245
+ <div class="ditty-editor-options__header">
246
+ <h3 class="ditty-editor-options__title"><?php _e( 'Item Types', 'ditty-news-ticker' ); ?></h3>
247
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--end">
248
+ <a href="#" class="ditty-editor-options__back protip" data-pt-title="<?php _e( 'Go Back', 'ditty-news-ticker' ); ?>"><i class="fas fa-chevron-right" data-class="fas fa-chevron-right"></i></a>
249
+ </div>
250
+ </div>
251
+ <div class="ditty-data-list">
252
+ <div class="ditty-data-list__items">
253
+ <?php
254
+ $item_types = ditty_item_types();
255
+ if ( is_array( $item_types ) && count( $item_types ) > 0 ) {
256
+ foreach ( $item_types as $slug => $item_type ) {
257
+ ?>
258
+ <div class="ditty-editor-item-type ditty-data-list__item protip" data-item_type="<?php echo $slug; ?>" data-pt-title="<?php echo $item_type['description']; ?>" data-pt-position="top-left">
259
+ <span class="ditty-data-list__item__icon"><i class="<?php echo $item_type['icon']; ?>"></i></span>
260
+ <span class="ditty-data-list__item__label"><?php echo $item_type['label']; ?></span>
261
+ </div>
262
+ <?php
263
+ }
264
+ }
265
+ ?>
266
+ </div>
267
+ </div>
268
+ </div>
269
+ </div>
270
+ <?php
271
+ $panels['item_types'] = ob_get_clean();
272
+ return $panels;
273
+ }
274
+
275
+ /**
276
+ * Return a item values to edit
277
+ *
278
+ * @access public
279
+ * @since 3.0
280
+ * @param json.
281
+ */
282
+ public function editor_fields_ajax() {
283
+ check_ajax_referer( 'ditty', 'security' );
284
+ $item_id_ajax = isset( $_POST['item_id'] ) ? $_POST['item_id'] : false;
285
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
286
+ if ( ! current_user_can( 'edit_ditty_items' ) || ! $item_id_ajax ) {
287
+ wp_die();
288
+ }
289
+ ditty_set_draft_values( $draft_values_ajax );
290
+
291
+ $editor_item = new Ditty_Item( $item_id_ajax );
292
+ if ( ! $editor_item ) {
293
+ wp_die();
294
+ }
295
+ $atts = array(
296
+ 'class' => "ditty-editor-options ditty-editor-options--{$editor_item->get_type()} ditty-metabox",
297
+ 'data-item_id' => $editor_item->get_id(),
298
+ 'data-item_type' => $editor_item->get_type(),
299
+ 'data-ditty_id' => $editor_item->get_ditty_id(),
300
+ );
301
+ ?>
302
+ <form <?php echo ditty_attr_to_html( $atts ); ?> />
303
+ <div class="ditty-editor-options__contents">
304
+ <div class="ditty-editor-options__header">
305
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--start">
306
+ <a href="#" class="ditty-editor-options__back"><i class="fas fa-chevron-left" data-class="fas fa-chevron-left"></i></a>
307
+ </div>
308
+ <h3 class="ditty-editor-options__title"><?php echo $editor_item->get_preview(); ?></h3>
309
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--end">
310
+ <a href="#" class="ditty-editor-options__preview"><i class="fas fa-sync-alt" data-class="fas fa-sync-alt"></i></a>
311
+ </div>
312
+ </div>
313
+ <div class="ditty-editor-options__body">
314
+ <?php
315
+ echo $editor_item->get_setting_fields();
316
+ ?>
317
+ </div>
318
+ </div>
319
+ </form>
320
+ <?php
321
+ wp_die();
322
+ }
323
+
324
+ /**
325
+ * Add a item via ajax
326
+ *
327
+ * @since 3.0
328
+ */
329
+ public function editor_item_add_ajax() {
330
+ check_ajax_referer( 'ditty', 'security' );
331
+ $ditty_id_ajax = isset( $_POST['ditty_id'] ) ? intval( $_POST['ditty_id'] ) : false;
332
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
333
+ if ( ! current_user_can( 'edit_dittys' ) || ! $ditty_id_ajax ) {
334
+ return false;
335
+ }
336
+ ditty_set_draft_values( $draft_values_ajax );
337
+
338
+ $new_meta = ditty_get_new_item_meta( $ditty_id_ajax );
339
+ $editor_item = new Ditty_Item( $new_meta );
340
+ $data = array(
341
+ 'display_items' => $editor_item->get_display_items(),
342
+ 'editor_item' => $editor_item->render_editor_list_item( 'return' ),
343
+ 'draft_id' => $editor_item->get_id(),
344
+ 'draft_data' => $editor_item->get_db_data(),
345
+ 'draft_meta' => $editor_item->custom_meta(),
346
+ );
347
+ wp_send_json( $data );
348
+ }
349
+
350
+ /**
351
+ * Clone a item via ajax
352
+ *
353
+ * @since 3.0
354
+ */
355
+ public function editor_item_clone_ajax() {
356
+ check_ajax_referer( 'ditty', 'security' );
357
+ $item_id_ajax = isset( $_POST['item_id'] ) ? sanitize_text_field( $_POST['item_id'] ) : false;
358
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
359
+ if ( ! current_user_can( 'publish_ditty_items' ) || ! $item_id_ajax ) {
360
+ wp_die();
361
+ }
362
+ ditty_set_draft_values( $draft_values_ajax );
363
+
364
+ $editor_item = new Ditty_Item( $item_id_ajax );
365
+ $draft_id = uniqid( 'new-' );
366
+ $draft_index = $editor_item->get_index() + 1;
367
+ $editor_item->set_id( $draft_id );
368
+ $editor_item->set_item_index( $draft_index );
369
+ $data = array(
370
+ 'editor_item' => $editor_item->render_editor_list_item( 'return' ),
371
+ 'display_items' => $editor_item->get_display_items(),
372
+ 'draft_id' => $draft_id,
373
+ 'draft_data' => $editor_item->get_db_data(),
374
+ 'draft_meta' => $editor_item->custom_meta(),
375
+ );
376
+ wp_send_json( $data );
377
+ }
378
+
379
+ /**
380
+ * Update the item via ajax
381
+ *
382
+ * @since 3.0
383
+ */
384
+ public function editor_item_update_ajax() {
385
+ check_ajax_referer( 'ditty', 'security' );
386
+ $item_id_ajax = isset( $_POST['item_id'] ) ? $_POST['item_id'] : false;
387
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
388
+ if ( ! current_user_can( 'edit_ditty_items' ) || ! $item_id_ajax ) {
389
+ return false;
390
+ }
391
+ ditty_set_draft_values( $draft_values_ajax );
392
+ unset( $_POST['action'] );
393
+ unset( $_POST['draft_values'] );
394
+ unset( $_POST['security'] );
395
+ unset( $_POST['item_id'] );
396
+
397
+ $editor_item = new Ditty_Item( $item_id_ajax );
398
+ $editor_item->set_item_value( $_POST );
399
+
400
+ // Find updated values
401
+ $value_updates = array();
402
+ $sanitized_values = $editor_item->get_value();
403
+ if ( is_array( $sanitized_values ) && count( $sanitized_values ) > 0 ) {
404
+ foreach ( $sanitized_values as $key => $value ) {
405
+ if ( is_array( $value ) ) {
406
+ if ( strlen( maybe_serialize( $value ) ) !== strlen( maybe_serialize( $_POST[$key] ) ) ) {
407
+ $value_updates[$key] = $value;
408
+ }
409
+ } else {
410
+ if ( isset( $_POST[$key] ) && $value !== $_POST[$key] ) {
411
+ $value_updates[$key] = $value;
412
+ }
413
+ }
414
+ }
415
+ }
416
+
417
+ $json_data = array(
418
+ 'editor_item' => $editor_item->render_editor_list_item( 'return' ),
419
+ 'display_items' => $editor_item->get_display_items(),
420
+ 'draft_id' => $editor_item->get_id(),
421
+ 'draft_data' => $editor_item->get_db_data(),
422
+ 'draft_meta' => $editor_item->custom_meta(),
423
+ 'value_updates' => $value_updates,
424
+ );
425
+
426
+ wp_send_json( $json_data );
427
+ }
428
+
429
+ /**
430
+ * Update a item's type
431
+ *
432
+ * @access public
433
+ * @since 3.0
434
+ * @param json.
435
+ */
436
+ public function editor_item_type_update_ajax() {
437
+ check_ajax_referer( 'ditty', 'security' );
438
+ $item_id_ajax = isset( $_POST['item_id'] ) ? $_POST['item_id'] : false;
439
+ $item_type_ajax = isset( $_POST['item_type'] ) ? $_POST['item_type'] : false;
440
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
441
+ if ( ! current_user_can( 'edit_ditty_items' ) || ! $item_id_ajax ) {
442
+ wp_die();
443
+ }
444
+ ditty_set_draft_values( $draft_values_ajax );
445
+
446
+ $editor_item = new Ditty_Item( $item_id_ajax );
447
+ $editor_item->set_item_type( $item_type_ajax );
448
+ $data = array(
449
+ 'editor_item' => $editor_item->render_editor_list_item( 'return' ),
450
+ 'display_items' => $editor_item->get_display_items(),
451
+ 'draft_id' => $item_id_ajax,
452
+ 'draft_data' => $editor_item->get_db_data(),
453
+ );
454
+ wp_send_json( $data );
455
+ }
456
+
457
+ /**
458
+ * Update the order of items
459
+ *
460
+ * @since 3.0
461
+ */
462
+ public function editor_item_index_update_ajax() {
463
+ check_ajax_referer( 'ditty', 'security' );
464
+ if ( ! current_user_can( 'edit_ditty_items' ) ) {
465
+ return false;
466
+ }
467
+
468
+ $ditty_id_ajax = isset( $_POST['ditty_id'] ) ? $_POST['ditty_id'] : false;
469
+ $item_ids_ajax = isset( $_POST['item_ids'] ) ? $_POST['item_ids'] : false;
470
+ $success = false;
471
+
472
+ if ( is_array( $item_ids_ajax ) && count( $item_ids_ajax ) > 0 ) {
473
+ foreach ( $item_ids_ajax as $index => $item_id ) {
474
+ $editor_item = new Ditty_Item( $item_id );
475
+ //$editor_item->init_draft( $ditty_id_ajax, $item_id );
476
+ $editor_item->set_item_index( $index );
477
+ }
478
+ }
479
+ wp_send_json(
480
+ array(
481
+ 'success' => true,
482
+ )
483
+ );
484
+ }
485
+
486
+ }
includes/class-ditty-layout.php ADDED
@@ -0,0 +1,444 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ditty Layout Class
4
+ *
5
+ * @package Ditty
6
+ * @subpackage Classes/Ditty Layout
7
+ * @copyright Copyright (c) 2021, Metaphor Creations
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 3.0
10
+ */
11
+ use Thunder\Shortcode\HandlerContainer\HandlerContainer;
12
+ use Thunder\Shortcode\Parser\RegularParser;
13
+ use Thunder\Shortcode\Processor\Processor;
14
+ use Thunder\Shortcode\Shortcode\ShortcodeInterface;
15
+ use Thunder\Shortcode\Syntax\CommonSyntax;
16
+ use Thunder\Shortcode\Syntax\Syntax;
17
+ use Thunder\Shortcode\Syntax\SyntaxBuilder;
18
+
19
+ class Ditty_Layout {
20
+
21
+ private $css;
22
+ private $css_compiled;
23
+ private $css_selectors;
24
+ private $description;
25
+ private $html;
26
+ private $label;
27
+ private $layout_tags;
28
+ private $layout_id;
29
+ private $item_type;
30
+ private $item_value;
31
+ private $version;
32
+
33
+ /**
34
+ * Get things started
35
+ * @access public
36
+ * @since 3.0
37
+ */
38
+ public function __construct( $layout_id, $item_type = false, $item_value = array() ) {
39
+ $this->item_value = $item_value;
40
+ $this->item_type = $item_type;
41
+
42
+ // If this is a new layout
43
+ if ( is_string( $layout_id ) && false !== strpos( $layout_id, 'new-' ) ) {
44
+ $this->parse_draft_data( $layout_id );
45
+
46
+ // Else, this is an existing layout
47
+ } elseif ( get_post( $layout_id ) ) {
48
+ $this->construct_from_id( $layout_id );
49
+ $this->parse_draft_data( $layout_id );
50
+ }
51
+ return $this;
52
+ }
53
+
54
+ /**
55
+ * Construct the class from meta
56
+ * @access public
57
+ * @since 3.0
58
+ * @return int $id
59
+ */
60
+ public function parse_draft_data( $layout_id ) {
61
+ $this->layout_id = $layout_id;
62
+ $draft_values = ditty_draft_layout_get( $layout_id );
63
+ if ( ! $draft_values ) {
64
+ return false;
65
+ }
66
+ $this->label = isset( $draft_values['label'] ) ? $draft_values['label'] : $this->label;
67
+ $this->description = isset( $draft_values['description'] ) ? $draft_values['description'] : $this->description;
68
+ $this->html = isset( $draft_values['html'] ) ? $draft_values['html'] : $this->html;
69
+ $this->css = isset( $draft_values['css'] ) ? $draft_values['css'] : $this->css;
70
+ $this->version = isset( $draft_values['version'] ) ? $draft_values['version'] : $this->version;
71
+ }
72
+
73
+ /**
74
+ * Construct class from ID
75
+ *
76
+ * @access public
77
+ * @since 3.0
78
+ */
79
+ public function construct_from_id( $layout_id ) {
80
+ if ( 'publish' == get_post_status( $layout_id ) ) {
81
+ $this->layout_id = $layout_id;
82
+ $this->label = get_the_title( $layout_id );
83
+ $this->description = get_post_meta( $layout_id, '_ditty_layout_description', true );
84
+ $this->html = get_post_meta( $layout_id, '_ditty_layout_html', true );
85
+ $this->css = get_post_meta( $layout_id, '_ditty_layout_css', true );
86
+ $this->version = get_post_meta( $layout_id, '_ditty_layout_version', true );
87
+ } else {
88
+ $this->label = __( 'Ditty Layout does not exist.', 'ditty-news-ticker' );
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Return the layout id
94
+ * @access public
95
+ * @since 3.0
96
+ * @return int $layout_id
97
+ */
98
+ public function get_layout_id() {
99
+ return $this->layout_id;
100
+ }
101
+
102
+ /**
103
+ * Set the layout id
104
+ * @access public
105
+ * @since 3.0
106
+ * @return int $id
107
+ */
108
+ public function set_layout_id( $layout_id ) {
109
+ $this->layout_id = $layout_id;
110
+ return $this->layout_id;
111
+ }
112
+
113
+ /**
114
+ * Return the item type
115
+ * @access public
116
+ * @since 3.0
117
+ * @return string $item_type
118
+ */
119
+ public function get_item_type() {
120
+ return $this->item_type;
121
+ }
122
+
123
+ /**
124
+ * Return the html tags
125
+ * @access public
126
+ * @since 3.0
127
+ * @return int $id
128
+ */
129
+ public function get_layout_tags() {
130
+ if ( ! $this->layout_tags ) {
131
+ $this->layout_tags = ditty_layout_tags( $this->get_item_type() );
132
+ }
133
+ return $this->layout_tags;
134
+ }
135
+
136
+ /**
137
+ * Return the html tags list
138
+ * @access public
139
+ * @since 3.0
140
+ * @return html $tags_list
141
+ */
142
+ public function get_tags_list() {
143
+ $tags_list = '';
144
+ $tags = apply_filters( 'ditty_layout_tags_list', $this->get_layout_tags(), $this->get_item_type(), 'html' );
145
+ if ( is_array( $tags ) && count( $tags ) > 0 ) {
146
+ $tags_list .= '<ul class="ditty-editor-options__tags__list ditty-editor-options__tags__list--' . $this->get_item_type() . '">';
147
+ foreach ( $tags as $data ) {
148
+ $class = ( isset( $data['class'] ) && '' != $data['class'] ) ? ' ' . esc_attr( $data['class'] ) : '';
149
+ $atts = array(
150
+ 'class' => 'ditty-editor-options__tag protip' . $class,
151
+ 'data-pt-title' => $data['description'],
152
+ 'data-atts' => ( isset( $data['atts'] ) ) ? htmlentities( json_encode( $data['atts'] ) ) : false,
153
+ );
154
+ $tags_list .= '<li ' . ditty_attr_to_html( $atts ) . '>{' . $data['tag'] . '}</li>';
155
+ }
156
+ $tags_list .= '</ul>';
157
+ }
158
+ return $tags_list;
159
+ }
160
+
161
+ /**
162
+ * Return the css selectors
163
+ * @access public
164
+ * @since 3.0
165
+ * @return int $id
166
+ */
167
+ public function get_css_selectors_list() {
168
+ $tags = apply_filters( 'ditty_layout_tags_list', $this->get_layout_tags(), $this->get_item_type(), 'css' );
169
+ $selectors_list = '';
170
+ if ( is_array( $tags ) && count( $tags ) > 0 ) {
171
+ $selectors_list .= '<ul class="ditty-editor-options__tags__list ditty-editor-options__tags__list--' . $this->get_item_type() . '">';
172
+ $selectors_list .= '<li class="ditty-editor-options__tag">.ditty-item__elements</li>';
173
+ foreach ( $tags as $data ) {
174
+ $selectors_list .= '<li class="ditty-editor-options__tag">.ditty-item__' . $data['tag'] . '</li>';
175
+ }
176
+ $selectors_list .= '</ul>';
177
+ }
178
+ return $selectors_list;
179
+ }
180
+
181
+ /**
182
+ * Return the layout label
183
+ * @access public
184
+ * @since 3.0
185
+ * @return string $label
186
+ */
187
+ public function get_label() {
188
+ return $this->label;
189
+ }
190
+
191
+ /**
192
+ * Set the layout label
193
+ * @access public
194
+ * @since 3.0
195
+ * @return string $label
196
+ */
197
+ public function set_label( $label ) {
198
+ if ( $label != $this->label ) {
199
+ $sanitized_label = sanitize_text_field( $label );
200
+ $this->label = $sanitized_label;
201
+ return $this->label;
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Return the version
207
+ * @access public
208
+ * @since 3.0
209
+ * @return string $version
210
+ */
211
+ public function get_version() {
212
+ return $this->version;
213
+ }
214
+
215
+ /**
216
+ * Set the version
217
+ * @access public
218
+ * @since 3.0
219
+ * @return string $version
220
+ */
221
+ public function remove_version() {
222
+ $this->version = false;
223
+ }
224
+
225
+ /**
226
+ * Return the layout description
227
+ * @access public
228
+ * @since 3.0
229
+ * @return string $description
230
+ */
231
+ public function get_description() {
232
+ return $this->description;
233
+ }
234
+
235
+ /**
236
+ * Return the layout html
237
+ * @access public
238
+ * @since 3.0
239
+ * @return string $html
240
+ */
241
+ public function get_html() {
242
+ return stripslashes( $this->html );
243
+ }
244
+
245
+ /**
246
+ * Set the layout html
247
+ * @access public
248
+ * @since 3.0
249
+ * @return string $html
250
+ */
251
+ public function set_html( $html ) {
252
+ $sanitized_html = wp_kses_post( $html );
253
+ $this->html = $sanitized_html;
254
+ return $this->html;
255
+ }
256
+
257
+ /**
258
+ * Return the layout css
259
+ * @access public
260
+ * @since 3.0
261
+ * @return string $html
262
+ */
263
+ public function get_css() {
264
+ return stripslashes( $this->css );
265
+ }
266
+
267
+ /**
268
+ * Return the compiled layout css
269
+ * @access public
270
+ * @since 3.0
271
+ * @return string $html
272
+ */
273
+ public function get_css_compiled() {
274
+ if ( empty( $this->css_compiled ) ) {
275
+ $this->css_compiled = Ditty()->layouts->compile_layout_style( $this->css, $this->layout_id );
276
+ }
277
+ return $this->css_compiled;
278
+ }
279
+
280
+ /**
281
+ * Set the layout html
282
+ * @access public
283
+ * @since 3.0
284
+ * @return string $html
285
+ */
286
+ public function set_css( $css ) {
287
+ $sanitized_css = wp_kses_post( $css );
288
+ $this->css = $sanitized_css;
289
+ $this->css_compiled = null;
290
+ return $this->css;
291
+ }
292
+
293
+ /**
294
+ * Return the passed item value
295
+ * @access public
296
+ * @since 3.0
297
+ * @return string $html
298
+ */
299
+ public function get_value() {
300
+ return $this->item_value;
301
+ }
302
+
303
+ /**
304
+ * Set the item value
305
+ * @access public
306
+ * @since 3.0
307
+ * @return string $html
308
+ */
309
+ public function set_item_value( $item_value ) {
310
+ $this->item_value = $item_value;
311
+ }
312
+
313
+ /**
314
+ * Return all custom meta for the layout
315
+ * @access public
316
+ * @since 3.0
317
+ * @return array $custom_meta
318
+ */
319
+ public function custom_meta() {
320
+ return array(
321
+ 'label' => $this->get_label(),
322
+ 'description' => $this->get_description(),
323
+ 'html' => $this->get_html(),
324
+ 'css' => $this->get_css(),
325
+ );
326
+ }
327
+
328
+ /**
329
+ * Setup the layout classes
330
+ * @access public
331
+ * @since 3.0
332
+ * @return string $classes
333
+ */
334
+ public function get_classes() {
335
+ $classes = array();
336
+ $classes[] = 'ditty-layout';
337
+ $classes[] = 'ditty-layout--' . esc_attr( $this->get_layout_id() );
338
+ $classes[] = 'ditty-item-type--' . esc_attr( $this->get_item_type() );
339
+ $classes = apply_filters( 'ditty-layout-classes', $classes );
340
+ return implode( ' ', $classes );
341
+ }
342
+
343
+ /**
344
+ * Render the admin edit row
345
+ * @access public
346
+ * @since 3.0
347
+ * @return html
348
+ */
349
+ public function render_editor_list_item( $render='echo' ) {
350
+ if ( 'return' == $render ) {
351
+ ob_start();
352
+ }
353
+ $atts = array(
354
+ 'id' => "ditty-editor-layout--{$this->get_layout_id()}",
355
+ 'class' => 'ditty-editor-layout ditty-data-list__item',
356
+ 'data-layout_id' => $this->get_layout_id(),
357
+ 'data-layout_version' => $this->get_version(),
358
+ );
359
+ ?>
360
+ <div <?php echo ditty_attr_to_html( $atts ); ?>>
361
+ <?php do_action( 'ditty_editor_layout_elements', $this ); ?>
362
+ </div>
363
+ <?php
364
+ if ( 'return' == $render ) {
365
+ return trim( ob_get_clean() );
366
+ }
367
+ }
368
+
369
+ /**
370
+ * Parse layout atts
371
+ *
372
+ * @access private
373
+ * @since 3.0
374
+ * @var array $parsed_atts
375
+ */
376
+ private function parse_atts( $atts = array(), $s ) {
377
+ $parsed_atts = array();
378
+ if ( is_array( $atts ) && count( $atts ) > 0 ) {
379
+ foreach ( $atts as $key => $value ) {
380
+ if ( $custom_value = $s->getParameter( $key ) ) {
381
+ $parsed_atts[$key] = $custom_value;
382
+ } else {
383
+ $parsed_atts[$key] = $value;
384
+ }
385
+ }
386
+ }
387
+ return $parsed_atts;
388
+ }
389
+
390
+ /**
391
+ * Render a layout tag
392
+ *
393
+ * @access private
394
+ * @since 3.0
395
+ * @return html
396
+ */
397
+ private function render_tag( $tag, $item_type, $data, $atts = array(), $custom_wrapper = false ) {
398
+ if ( ! $output = apply_filters( "ditty_layout_tag_{$tag}", false, $item_type, $data, $atts ) ) {
399
+ return false;
400
+ }
401
+ if ( isset( $atts['wpautop'] ) && 'true' == strval( $atts['wpautop'] ) ) {
402
+ $output = wpautop( $output );
403
+ }
404
+ return ditty_layout_render_tag( $output, "ditty-item__{$tag}", $item_type, $data, $atts, $custom_wrapper );
405
+ }
406
+
407
+ /**
408
+ * Render the layout
409
+ * @access public
410
+ * @since 3.0
411
+ * @return html
412
+ */
413
+ public function render() {
414
+ $tags = $this->get_layout_tags();
415
+ $html = $this->get_html();
416
+ $value = $this->get_value();
417
+
418
+ // Return an error if there is one
419
+ if ( isset( $value['ditty_feed_error'] ) ) {
420
+ return $value['ditty_feed_error'];
421
+ }
422
+
423
+ $handlers = new HandlerContainer();
424
+ if ( is_array( $tags ) && count( $tags ) > 0 ) {
425
+ foreach ( $tags as $i => $tag ) {
426
+ $handlers->add( $tag['tag'], function( ShortcodeInterface $s ) use ( $tag, $value ) {
427
+ $defaults = isset( $tag['atts'] ) ? $tag['atts'] : array();
428
+ $atts = $this->parse_atts( $defaults, $s );
429
+ $atts = apply_filters( 'ditty_layout_tag_atts', $atts, $tag['tag'], $this->get_item_type(), $value );
430
+ $content = $s->getContent();
431
+ if ( isset( $tag['func'] ) && function_exists( $tag['func'] ) ) {
432
+ return call_user_func( $tag['func'], $this->get_item_type(), $value, $atts, $content );
433
+ } else {
434
+ return $this->render_tag( $tag['tag'], $this->get_item_type(), $value, $atts, $content );
435
+ }
436
+ } );
437
+ }
438
+ }
439
+ $syntax = new Syntax( '{', '}', '/', '=', '"' ); // created explicitly
440
+ $processor = new Processor( new RegularParser( $syntax ), $handlers );
441
+
442
+ return stripslashes( $processor->process( $html ) );
443
+ }
444
+ }
includes/class-ditty-layouts.php ADDED
@@ -0,0 +1,1039 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ditty Layouts
4
+ *
5
+ * @package Ditty News Layouts
6
+ * @subpackage Classes/Ditty Layouts
7
+ * @copyright Copyright (c) 2021, Metaphor Creations
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ * @since 3.0
10
+ */
11
+
12
+ use ScssPhp\ScssPhp\Compiler;
13
+ use Padaliyajay\PHPAutoprefixer\Autoprefixer;
14
+
15
+ class Ditty_Layouts {
16
+
17
+ private $new_layouts;
18
+ private $updated_layouts;
19
+
20
+ /**
21
+ * Get things started
22
+ * @access public
23
+ * @since 3.0
24
+ */
25
+ public function __construct() {
26
+
27
+ // WP metabox hooks
28
+ add_action( 'add_meta_boxes', array( $this, 'metaboxes' ) );
29
+ add_action( 'save_post', array( $this, 'metabox_save' ) );
30
+
31
+ // General hooks
32
+ add_filter( 'post_row_actions', array( $this, 'modify_list_row_actions' ), 10, 2 );
33
+ add_action( 'ditty_editor_update', array( $this, 'update_drafts' ), 10, 2 );
34
+ add_filter( 'ditty_item_db_data', array( $this, 'modify_ditty_item_db_data'), 10, 2 );
35
+ add_filter( 'ditty_editor_save_data', array( $this, 'editor_add_save_data'), 10, 2 );
36
+
37
+ // Layout elements
38
+ add_action( 'ditty_editor_layout_elements', array( $this, 'editor_layout_icon' ), 5 );
39
+ add_action( 'ditty_editor_layout_elements', array( $this, 'editor_layout_label' ), 10 );
40
+ add_action( 'ditty_editor_layout_elements', array( $this, 'editor_layout_edit_html' ), 15 );
41
+ add_action( 'ditty_editor_layout_elements', array( $this, 'editor_layout_edit_css' ), 20 );
42
+ add_action( 'ditty_editor_layout_elements', array( $this, 'editor_layout_clone' ), 25 );
43
+ add_action( 'ditty_editor_layout_elements', array( $this, 'editor_layout_delete' ), 30 );
44
+
45
+ // Ajax
46
+ add_action( 'wp_ajax_ditty_editor_layout_variations', array( $this, 'editor_layout_variations_ajax' ) );
47
+ add_action( 'wp_ajax_nopriv_ditty_editor_layout_variations', array( $this, 'editor_layout_variations_ajax' ) );
48
+ add_action( 'wp_ajax_ditty_editor_layouts', array( $this, 'editor_layouts_ajax' ) );
49
+ add_action( 'wp_ajax_nopriv_ditty_editor_layouts', array( $this, 'editor_layouts_ajax' ) );
50
+ add_action( 'wp_ajax_ditty_editor_select_layout', array( $this, 'editor_select_layout_ajax' ) );
51
+ add_action( 'wp_ajax_nopriv_ditty_editor_select_layout', array( $this, 'editor_select_layout_ajax' ) );
52
+
53
+ add_action( 'wp_ajax_ditty_editor_layout_clone', array( $this, 'editor_clone_ajax' ) );
54
+ add_action( 'wp_ajax_nopriv_ditty_editor_layout_clone', array( $this, 'editor_clone_ajax' ) );
55
+
56
+ add_action( 'wp_ajax_ditty_editor_layout_fields', array( $this, 'editor_fields_ajax' ) );
57
+ add_action( 'wp_ajax_nopriv_ditty_editor_layout_fields', array( $this, 'editor_fields_ajax' ) );
58
+ add_action( 'wp_ajax_ditty_editor_layout_update', array( $this, 'editor_update_ajax' ) );
59
+ add_action( 'wp_ajax_nopriv_ditty_editor_layout_update', array( $this, 'editor_update_ajax' ) );
60
+
61
+ add_action( 'wp_ajax_ditty_install_layout', array( $this, 'install_layout' ) );
62
+ }
63
+
64
+ /**
65
+ * Install default layouts
66
+ *
67
+ * @access private
68
+ * @since 3.0
69
+ */
70
+ public function install_default( $layout_template = false, $layout_version = false ) {
71
+ $args = array(
72
+ 'template' => $layout_template,
73
+ 'version' => $layout_version,
74
+ 'fields' => 'ids',
75
+ );
76
+ if ( $layouts = ditty_layouts_posts( $args ) ) {
77
+ return end( $layouts );
78
+ }
79
+
80
+ $templates = ditty_layout_templates();
81
+ if ( ! isset( $templates[$layout_template] ) ) {
82
+ return false;
83
+ }
84
+ $postarr = array(
85
+ 'post_type' => 'ditty_layout',
86
+ 'post_status' => 'publish',
87
+ 'post_title' => $templates[$layout_template]['label'],
88
+ );
89
+ if ( $new_layout_id = wp_insert_post( $postarr ) ) {
90
+ update_post_meta( $new_layout_id, '_ditty_layout_template', esc_attr( $layout_template ) );
91
+ if ( isset( $templates[$layout_template]['description'] ) ) {
92
+ update_post_meta( $new_layout_id, '_ditty_layout_description', wp_kses_post( $templates[$layout_template]['description'] ) );
93
+ }
94
+ if ( isset( $templates[$layout_template]['html'] ) ) {
95
+ update_post_meta( $new_layout_id, '_ditty_layout_html', wp_kses_post( $templates[$layout_template]['html'] ) );
96
+ }
97
+ if ( isset( $templates[$layout_template]['css'] ) ) {
98
+ update_post_meta( $new_layout_id, '_ditty_layout_css', wp_kses_post( $templates[$layout_template]['css'] ) );
99
+ }
100
+ if ( isset( $templates[$layout_template]['version'] ) ) {
101
+ update_post_meta( $new_layout_id, '_ditty_layout_version', wp_kses_post( $templates[$layout_template]['version'] ) );
102
+ }
103
+ }
104
+ return $new_layout_id;
105
+ }
106
+
107
+ /**
108
+ * Install a layout via ajax
109
+ *
110
+ * @access public
111
+ * @since 3.0
112
+ */
113
+ public function install_layout() {
114
+ check_ajax_referer( 'ditty', 'security' );
115
+ $layout_template_ajax = isset( $_POST['layout_template'] ) ? $_POST['layout_template'] : false;
116
+ $layout_version_ajax = isset( $_POST['layout_version'] ) ? $_POST['layout_version'] : false;
117
+
118
+ if ( ! current_user_can( 'publish_ditty_layouts' ) || ! $layout_template_ajax ) {
119
+ wp_die();
120
+ }
121
+ $layout_id = $this->install_default( $layout_template_ajax, $layout_version_ajax );
122
+
123
+ $args = array(
124
+ 'type' => 'button',
125
+ 'label' => __( 'Installed', 'ditty-ticker' ),
126
+ 'link' => '#',
127
+ 'size' => 'small',
128
+ 'input_class' => 'ditty-default-layout-view',
129
+ 'field_only' => true,
130
+ 'atts' => array(
131
+ 'disabled' => 'disabled',
132
+ ),
133
+ );
134
+ $button = ditty_field( $args );
135
+
136
+ $data = array(
137
+ 'layout_id' => $layout_id,
138
+ 'button' => $button,
139
+ );
140
+ wp_send_json( $data );
141
+ }
142
+
143
+ /**
144
+ * List the layout variation defaults
145
+ *
146
+ * @access public
147
+ * @since 3.0
148
+ * @param html
149
+ */
150
+ public function variation_defaults() {
151
+ $html = '';
152
+ $item_types = ditty_item_types();
153
+ $variation_types = ditty_layout_variation_types();
154
+ $settings = ditty_settings( 'variation_defaults' );
155
+ $layout_options = $this->select_field_options( __( 'Choose a Layout', 'ditty-news-ticker' ) );
156
+
157
+ if ( is_array( $variation_types ) && count( $variation_types ) > 0 ) {
158
+ $html .= '<div id="ditty-layout-variation-defaults">';
159
+ $html .= '<h3>' . __( 'Layout Variations', 'ditty-news-ticker' ) . '</h3>';
160
+ $html .= '<ul>';
161
+ foreach ( $variation_types as $item_type => $item_type_variations ) {
162
+ if ( ! isset( $item_types[$item_type] ) ) {
163
+ continue;
164
+ }
165
+ $html .= '<li class="ditty-layout-variation-defaults__item_type">';
166
+ if ( is_array( $item_type_variations ) && count( $item_type_variations ) > 0 ) {
167
+ $fields = array();
168
+ foreach ( $item_type_variations as $variation_id => $item_type_variation ) {
169
+ $fields[] = array(
170
+ 'id' => "variation_default_{$item_type}_{$variation_id}",
171
+ 'type' => 'select',
172
+ 'name' => $item_type_variation['label'],
173
+ 'desc' => $item_type_variation['description'],
174
+ 'options' => $layout_options,
175
+ 'std' => ( isset( $settings[$item_type] ) && isset( $settings[$item_type][$variation_id] ) ) ? $settings[$item_type][$variation_id] : false,
176
+ );
177
+ }
178
+ $args = array(
179
+ 'id' => 'variation_defaults',
180
+ 'type' => 'group',
181
+ 'name' => "<i class='{$item_types[$item_type]['icon']}'></i> " . $item_types[$item_type]['label'],
182
+ 'collapsible' => true,
183
+ 'multiple_fields' => true,
184
+ 'fields' => $fields,
185
+ //'class' => 'ditty-field--variation_defaults',
186
+ );
187
+ $html .= ditty_field( $args );
188
+ }
189
+ $html .= '</li>';
190
+ }
191
+ $html .= '</ul>';
192
+ $html .= '</div>';
193
+ }
194
+
195
+ return $html;
196
+ }
197
+
198
+ /**
199
+ * List the layout templates
200
+ *
201
+ * @access public
202
+ * @since 3.0
203
+ * @param html
204
+ */
205
+ public function layout_templates_list() {
206
+ $html = '';
207
+ $layout_templates = ditty_layout_templates();
208
+ if ( is_array( $layout_templates ) && count( $layout_templates ) > 0 ) {
209
+ $html .= '<div id="ditty-layout-templates">';
210
+ $html .= '<h3>' . __( 'Layout Templates', 'ditty-news-ticker' ) . '</h3>';
211
+ $html .= '<ul id="ditty-templates-list__templates">';
212
+ foreach ( $layout_templates as $template_slug => $template_data ) {
213
+ $args = array(
214
+ 'template' => $template_slug,
215
+ 'fields' => 'ids',
216
+ 'return' => 'versions',
217
+ );
218
+ $layout_versions = ditty_layouts_posts( $args );
219
+ $html .= '<li class="ditty-templates-list__template">';
220
+ $html .= '<div class="ditty-templates-list__template__heading">';
221
+ $html .= '<h4 class="ditty-templates-list__template__label">';
222
+ $html .= $template_data['label'] . " <small class='ditty-layout-version'>(v{$template_data['version']})</small>";
223
+ $html .= '</h4>';
224
+ $html .= '<p class="ditty-templates-list__template__description">' . $template_data['description'] . '</p>';
225
+ $html .= '</div>';
226
+
227
+ $args = array(
228
+ 'type' => 'button',
229
+ 'label' => __( 'Installed', 'ditty-ticker' ),
230
+ 'link' => '#',
231
+ 'size' => 'small',
232
+ 'input_class' => 'ditty-default-layout-view',
233
+ 'field_only' => true,
234
+ );
235
+ if ( $layout_versions ) {
236
+ if ( in_array( $template_data['version'], $layout_versions ) ) {
237
+ $args['label'] = __( 'Installed', 'ditty-ticker' );
238
+ $args['atts'] = array(
239
+ 'disabled' => 'disabled',
240
+ );
241
+ } else {
242
+ $args['label'] = sprintf( __( 'Install Version %s', 'ditty-ticker' ), $template_data['version'] );
243
+ $args['input_class'] = 'ditty-default-layout-install';
244
+ $args['icon_after'] = 'fas fa-download';
245
+ $args['atts'] = array(
246
+ 'data-layout_template' => $template_slug,
247
+ 'data-layout_version' => $template_data['version'],
248
+ );
249
+ }
250
+ } else {
251
+ $args['label'] = __( 'Install Template', 'ditty-ticker' );
252
+ $args['input_class'] = 'ditty-default-layout-install';
253
+ $args['icon_after'] = 'fas fa-download';
254
+ $args['atts'] = array(
255
+ 'data-layout_template' => $template_slug,
256
+ 'data-layout_version' => $template_data['version'],
257
+ );
258
+ }
259
+ $html .= ditty_field( $args );
260
+ $html .= '</li>';
261
+ }
262
+ $html .= '</ul>';
263
+ $html .= '</div>';
264
+ }
265
+
266
+ return $html;
267
+ }
268
+
269
+ /**
270
+ * Add the post ID to the list row actions
271
+ *
272
+ * @since 3.0
273
+ * @return void
274
+ */
275
+ public function modify_list_row_actions( $actions, $post ) {
276
+ if ( $post->post_type == 'ditty_layout' ) {
277
+ //$id_string = sprintf( __( 'ID: %d', 'ditty-news-ticker' ), $post->ID );
278
+ $id_array = array(
279
+ 'id' => sprintf( __( 'ID: %d', 'ditty-news-ticker' ), $post->ID ),
280
+ );
281
+ $actions = array_merge( $id_array, $actions );
282
+ }
283
+ return $actions;
284
+ }
285
+
286
+ /**
287
+ * Add metaboxes
288
+ *
289
+ * @since 3.0
290
+ * @return void
291
+ */
292
+ public function metaboxes() {
293
+ add_meta_box( 'ditty-layout-info', __( 'Layout Info', 'ditty-news-ticker' ), array( $this, 'metabox_layout_info' ), 'ditty_layout', 'side', 'high' );
294
+ add_meta_box( 'ditty-layout-html', __( 'Layout HTML', 'ditty-news-ticker' ), array( $this, 'metabox_layout_html' ), 'ditty_layout', 'normal' );
295
+ add_meta_box( 'ditty-layout-css', __( 'Layout CSS', 'ditty-news-ticker' ), array( $this, 'metabox_layout_css' ), 'ditty_layout', 'normal' );
296
+ }
297
+
298
+ /**
299
+ * Save custom meta
300
+ *
301
+ * @since 3.0
302
+ * @return void
303
+ */
304
+ public function metabox_save( $post_id ) {
305
+ global $post;
306
+
307
+ // verify nonce
308
+ if ( ! isset( $_POST['ditty_layout_nonce'] ) || ! wp_verify_nonce( $_POST['ditty_layout_nonce'], basename( __FILE__ ) ) ) {
309
+ return $post_id;
310
+ }
311
+
312
+ // check autosave
313
+ if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_REQUEST['bulk_edit'] ) ) return $post_id;
314
+
315
+ // don't save if only a revision
316
+ if ( isset( $post->post_type ) && $post->post_type == 'revision' ) return $post_id;
317
+
318
+ // check permissions
319
+ if ( isset( $_POST['post_type'] ) && 'ditty_layout' == $_POST['post_type'] ) {
320
+ if ( ! current_user_can( 'edit_ditty_layout', $post_id ) ) {
321
+ return $post_id;
322
+ }
323
+ } elseif ( ! current_user_can( 'edit_ditty_layout', $post_id ) ) {
324
+ return $post_id;
325
+ }
326
+
327
+ $layout_description = sanitize_text_field( $_POST['_ditty_layout_description'] );
328
+ $layout_html = wp_kses_post( $_POST['_ditty_layout_html'] );
329
+ $layout_css = wp_kses_post( $_POST['_ditty_layout_css'] );
330
+
331
+ update_post_meta( $post_id, '_ditty_layout_description', $layout_description );
332
+ update_post_meta( $post_id, '_ditty_layout_html', $layout_html );
333
+ update_post_meta( $post_id, '_ditty_layout_css', $layout_css );
334
+
335
+ // Remove the version number of edited layouts
336
+ delete_post_meta( $post_id, '_ditty_layout_template' );
337
+ delete_post_meta( $post_id, '_ditty_layout_version' );
338
+ }
339
+
340
+ /**
341
+ * Add the Layout info metabox
342
+ *
343
+ * @since 3.0
344
+ * @return void
345
+ */
346
+ public function metabox_layout_info() {
347
+ global $post;
348
+ $layout_description = get_post_meta( $post->ID, '_ditty_layout_description', true );
349
+
350
+ $fields = array();
351
+ $fields['description'] = array(
352
+ 'type' => 'textarea',
353
+ 'id' => '_ditty_layout_description',
354
+ 'name' => __( 'Description', 'ditty-news-ticker' ),
355
+ 'std' => $layout_description,
356
+ );
357
+ ditty_fields( $fields );
358
+ echo '<input type="hidden" name="ditty_layout_nonce" value="' . wp_create_nonce( basename( __FILE__ ) ) . '" />';
359
+ }
360
+
361
+ /**
362
+ * Add the Layout html metabox
363
+ *
364
+ * @since 3.0
365
+ * @return void
366
+ */
367
+ public function metabox_layout_html() {
368
+ global $post;
369
+ $layout_html = get_post_meta( $post->ID, '_ditty_layout_html', true );
370
+ $field_args = array(
371
+ 'type' => 'code',
372
+ 'id' => '_ditty_layout_html',
373
+ 'name' => false,
374
+ 'std' => $layout_html,
375
+ );
376
+ echo ditty_field( $field_args );
377
+ }
378
+
379
+ /**
380
+ * Add the Layout css metabox
381
+ *
382
+ * @since 3.0
383
+ * @return void
384
+ */
385
+ public function metabox_layout_css() {
386
+ global $post;
387
+ $layout_css = get_post_meta( $post->ID, '_ditty_layout_css', true );
388
+ $field_args = array(
389
+ 'type' => 'code',
390
+ 'id' => '_ditty_layout_css',
391
+ 'name' => false,
392
+ 'rows' => 8,
393
+ 'std' => stripslashes( $layout_css ),
394
+ 'js_options' => array(
395
+ 'mode' => 'sass',
396
+ ),
397
+ );
398
+ echo ditty_field( $field_args );
399
+ }
400
+
401
+ /**
402
+ * Render the layout css styles
403
+ *
404
+ * @since 3.0
405
+ * @access public
406
+ * @var string $css
407
+ */
408
+ public function compile_layout_style( $css, $layout_id ) {
409
+ $styles = '';
410
+
411
+ if ( is_numeric( $layout_id ) ) {
412
+ $styles .= '.ditty-layout--' .$layout_id . '{';
413
+ $styles .= html_entity_decode( $css );
414
+ $styles .= '}';
415
+ if ( is_ditty_post() ) {
416
+ $styles .= '#poststuff .ditty-layout--' . $layout_id . '{';
417
+ $styles .= html_entity_decode( $css );
418
+ $styles .= '}';
419
+ }
420
+ } else {
421
+ $styles .= '.ditty-layout--' . $layout_id . '{';
422
+ $styles .= html_entity_decode( $css );
423
+ $styles .= '}';
424
+ if ( is_ditty_post() ) {
425
+ $styles .= '#poststuff .ditty-layout--' . $layout_id . '{';
426
+ $styles .= html_entity_decode( $css );
427
+ $styles .= '}';
428
+ }
429
+ }
430
+
431
+ // Compile the sass & remove whitespace
432
+ try {
433
+ $scss = new Compiler();
434
+ $compiled_styles = $scss->compile( $styles );
435
+ } catch ( \Exception $e ) {
436
+ return false;
437
+ }
438
+
439
+ // Add auto-prefixes
440
+ $autoprefixer = new Autoprefixer( $compiled_styles );
441
+ $prefixed_css = $autoprefixer->compile();
442
+
443
+ // Remove multiple white-spaces, tabs and new-lines
444
+ $final_css = preg_replace( '/\s+/S', ' ', $prefixed_css );
445
+ return wp_kses_post( trim( $final_css ) );
446
+ }
447
+
448
+ /**
449
+ * Return an array of all layouts for select fields
450
+ *
451
+ * @access private
452
+ * @since 3.0
453
+ * @param array $options.
454
+ */
455
+ private function select_field_options( $placeholder = false ) {
456
+ $options = array();
457
+ if ( $placeholder ) {
458
+ $options[''] = $placeholder;
459
+ }
460
+ if ( $layouts = ditty_layouts_posts() ) {
461
+ foreach ( $layouts as $layout_post ) {
462
+ $title = $layout_post->post_title;
463
+ if ( $version = get_post_meta( $layout_post->ID, '_ditty_layout_version', true ) ) {
464
+ $title .= " (v{$version})";
465
+ }
466
+ $options[$layout_post->ID] = $title;
467
+ }
468
+ }
469
+ return $options;
470
+ }
471
+
472
+ /**
473
+ * Add the editor item icon
474
+ *
475
+ * @since 3.0
476
+ */
477
+ public function editor_layout_icon( $layout ) {
478
+ echo '<span class="ditty-data-list__item__icon"><i class="fas fa-pencil-ruler" data-class="fas fa-pencil-ruler"></i></span>';
479
+ }
480
+
481
+ /**
482
+ * Add the editor item label
483
+ *
484
+ * @since 3.0
485
+ */
486
+ public function editor_layout_label( $layout ) {
487
+ $version = $layout->get_version();
488
+ $version_string = '';
489
+ if ( $version ) {
490
+ $version_string = " <small class='ditty-layout-version'>(v{$version})</small>";
491
+ }
492
+ ?>
493
+ <span class="ditty-data-list__item__label"><?php echo $layout->get_label(); ?><?php echo $version_string; ?></span>
494
+ <?php
495
+ }
496
+
497
+ /**
498
+ * Add the editor edit html button
499
+ *
500
+ * @since 3.0
501
+ */
502
+ public function editor_layout_edit_html( $layout ) {
503
+ if ( current_user_can( 'edit_ditty_layouts' ) ) {
504
+ echo '<a href="#" class="ditty-data-list__item__edit_html protip" data-pt-title="' . __( 'Edit HTML', 'ditty-news-ticker' ) . '"><i class="fas fa-code" data-class="fas fa-code"></i></a>';
505
+ }
506
+ }
507
+
508
+ /**
509
+ * Add the editor edit css button
510
+ *
511
+ * @since 3.0
512
+ */
513
+ public function editor_layout_edit_css( $layout ) {
514
+ if ( current_user_can( 'edit_ditty_layouts' ) ) {
515
+ echo '<a href="#" class="ditty-data-list__item__edit_css protip" data-pt-title="' . __( 'Edit CSS', 'ditty-news-ticker' ) . '"><i class="fas fa-eye" data-class="fas fa-eye"></i></a>';
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Add the editor clone button
521
+ *
522
+ * @since 3.0
523
+ */
524
+ public function editor_layout_clone( $layout ) {
525
+ if ( current_user_can( 'publish_ditty_layouts' ) ) {
526
+ echo '<a href="#" class="ditty-data-list__item__clone protip" data-pt-title="' . __( 'Clone', 'ditty-news-ticker' ) . '"><i class="fas fa-clone" data-class="fas fa-clone"></i></a>';
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Add the editor delete button
532
+ *
533
+ * @since 3.0
534
+ */
535
+ public function editor_layout_delete( $layout ) {
536
+ if ( current_user_can( 'delete_ditty_layouts' ) ) {
537
+ echo '<a href="#" class="ditty-data-list__item__delete protip" data-pt-title="' . __( 'Delete', 'ditty-news-ticker' ) . '"><i class="fas fa-trash-alt" data-class="fas fa-trash-alt"></i></a>';
538
+ }
539
+ }
540
+
541
+ /**
542
+ * Ditty Layout Variations list panel
543
+ * @access public
544
+ * @since 3.0
545
+ */
546
+ public function editor_layout_variations_ajax() {
547
+ check_ajax_referer( 'ditty', 'security' );
548
+ if ( ! current_user_can( 'edit_ditty_layouts' ) ) {
549
+ wp_die();
550
+ }
551
+ $ditty_id_ajax = isset( $_POST['ditty_id'] ) ? $_POST['ditty_id'] : false;
552
+ $item_type_ajax = isset( $_POST['item_type'] ) ? $_POST['item_type'] : false;
553
+ $item_label_ajax = isset( $_POST['item_label'] ) ? $_POST['item_label'] : false;
554
+ $layout_value_ajax = isset( $_POST['layout_value'] ) ? $_POST['layout_value'] : false;
555
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
556
+ ditty_set_draft_values( $draft_values_ajax );
557
+
558
+ if ( is_array( $layout_value_ajax ) ) {
559
+ $layout_value = $layout_value_ajax;
560
+ } else {
561
+ $layout_value = json_decode( stripslashes( $layout_value_ajax ), true );
562
+ }
563
+ ?>
564
+ <div class="ditty-editor-options ditty-metabox">
565
+ <div class="ditty-editor-options__contents">
566
+ <div class="ditty-editor-options__header">
567
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--start">
568
+ <a href="#" class="ditty-editor-options__back"><i class="fas fa-chevron-left" data-class="fas fa-chevron-left"></i></a>
569
+ </div>
570
+ <h3 class="ditty-editor-options__title"><?php echo sprintf( __( 'Layout: <span>%s</span>', 'ditty-news-ticker' ), stripslashes( $item_label_ajax ) ); ?></h3>
571
+ </div>
572
+ <div class="ditty-data-list">
573
+ <div class="ditty-data-list__items">
574
+ <?php
575
+ if ( $item_type_object = ditty_item_type_object( $item_type_ajax ) ) {
576
+ $variations = $item_type_object->get_layout_variation_data( $layout_value );
577
+ if ( is_array( $variations ) && count( $variations ) > 0 ) {
578
+ foreach ( $variations as $id => $data ) {
579
+ $layout_id = $data['template'];
580
+ $layout = new Ditty_Layout( $layout_id );
581
+ $version = $layout->get_version();
582
+ $version_string = '';
583
+ if ( $version ) {
584
+ $version_string = " <small class='ditty-layout-version'>(v{$version})</small>";
585
+ }
586
+ $atts = array(
587
+ 'class' => "ditty-layout-variation ditty-layout-variation--{$id} ditty-data-list__item",
588
+ 'data-layout_variation_id' => $id,
589
+ 'data-layout_variation_label' => $data['label'],
590
+ 'data-layout_id' => $layout_id,
591
+ 'data-item_type' => $item_type_ajax,
592
+ );
593
+ ?>
594
+ <div <?php echo ditty_attr_to_html( $atts ); ?>>
595
+ <div class="ditty-layout-variation__content">
596
+ <span class="ditty-layout-variation__label"><?php printf( __( 'Variation: %s', 'ditty-news-ticker' ), $data['label'] ); ?></span>
597
+ <span class="ditty-layout-variation__template"><?php echo wp_sprintf( __( 'Template: <span>%s</span>%s', 'ditty-news-ticker' ), $layout->get_label(), $version_string ); ?></span>
598
+ <div class="ditty-layout-variation__buttons">
599
+ <a href="#" class="ditty-layout-variation__edit_html protip" data-pt-title="<?php _e( 'Edit HTML', 'ditty-news-ticker' ); ?>"><i class="fas fa-code" data-class="fas fa-code"></i></a>
600
+ <a href="#" class="ditty-layout-variation__edit_css protip" data-pt-title="<?php _e( 'Edit CSS', 'ditty-news-ticker' ); ?>"><i class="fas fa-eye" data-class="fas fa-eye"></i></a>
601
+ </div>
602
+ </div>
603
+ <a href="#" class="ditty-layout-variation__change protip" data-pt-title="<?php _e( 'Change Template', 'ditty-news-ticker' ); ?>"><i class="fas fa-exchange-alt" data-class="fas fa-exchange-alt"></i></a>
604
+ </div>
605
+ <?php
606
+ }
607
+ }
608
+ }
609
+ ?>
610
+ </div>
611
+ </div>
612
+ </div>
613
+ </div>
614
+ <?php
615
+ wp_die();
616
+ }
617
+
618
+ /**
619
+ * Ditty Layout list panel
620
+ * @access public
621
+ * @since 3.0
622
+ */
623
+ public function editor_layouts_ajax() {
624
+ check_ajax_referer( 'ditty', 'security' );
625
+ if ( ! current_user_can( 'edit_ditty_layouts' ) ) {
626
+ wp_die();
627
+ }
628
+ $ditty_id_ajax = isset( $_POST['ditty_id'] ) ? $_POST['ditty_id'] : false;
629
+ $item_type_ajax = isset( $_POST['item_type'] ) ? $_POST['item_type'] : false;
630
+ $variation_id_ajax = isset( $_POST['variation_id'] ) ? $_POST['variation_id'] : false;
631
+ $variation_label_ajax = isset( $_POST['variation_label'] ) ? $_POST['variation_label'] : false;
632
+ $layout_id_ajax = isset( $_POST['layout_id'] ) ? $_POST['layout_id'] : false;
633
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
634
+ ditty_set_draft_values( $draft_values_ajax );
635
+ ?>
636
+ <div class="ditty-editor-options ditty-metabox">
637
+ <div class="ditty-editor-options__contents">
638
+ <div class="ditty-editor-options__header">
639
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--start">
640
+ <a href="#" class="ditty-editor-options__back"><i class="fas fa-chevron-left" data-class="fas fa-chevron-left"></i></a>
641
+ </div>
642
+ <h3 class="ditty-editor-options__title"><?php echo sprintf( __( 'Variation: <span>%s</span>', 'ditty-news-ticker' ), stripslashes( $variation_label_ajax ) ); ?></h3>
643
+ </div>
644
+ <div class="ditty-data-list">
645
+ <div class="ditty-data-list__items" data-active="<?php echo $layout_id_ajax; ?>">
646
+ <?php
647
+ $args = array(
648
+ 'fields' => 'ids',
649
+ );
650
+ $layouts = ditty_layouts_posts( $args );
651
+ $drafts = ditty_draft_layout_get();
652
+ if ( ! is_array( $drafts ) ) {
653
+ $drafts = array();
654
+ }
655
+ if ( is_array( $layouts ) && count( $layouts ) > 0 ) {
656
+ foreach ( $layouts as $layout_id ) {
657
+ if ( isset( $drafts[$layout_id] ) && 'DELETE' == $drafts[$layout_id] ) {
658
+ continue;
659
+ }
660
+ $layout = new Ditty_Layout( $layout_id );
661
+ echo $layout->render_editor_list_item( 'return' );
662
+ }
663
+ }
664
+ if ( is_array( $drafts ) && count( $drafts ) > 0 ) {
665
+ foreach ( $drafts as $layout_id => $data ) {
666
+ if ( is_string( $layout_id ) && false !== strpos( $layout_id, 'new-' ) ) {
667
+ $layout = new Ditty_Layout( $layout_id );
668
+ echo $layout->render_editor_list_item( 'return' );
669
+ }
670
+ }
671
+ }
672
+ ?>
673
+ </div>
674
+ </div>
675
+ </div>
676
+ </div>
677
+ <?php
678
+ wp_die();
679
+ }
680
+
681
+ /**
682
+ * Update the item's layout
683
+ * @access public
684
+ * @since 3.0
685
+ */
686
+ public function editor_select_layout_ajax() {
687
+ check_ajax_referer( 'ditty', 'security' );
688
+ $layout_id_ajax = isset( $_POST['layout_id'] ) ? $_POST['layout_id'] : false;
689
+ $item_id_ajax = isset( $_POST['item_id'] ) ? $_POST['item_id'] : false;
690
+ $ditty_id_ajax = isset( $_POST['ditty_id'] ) ? $_POST['ditty_id'] : false;
691
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
692
+ if ( ! current_user_can( 'edit_ditty_items' ) || ! $item_id_ajax || ! $layout_id_ajax ) {
693
+ wp_die();
694
+ }
695
+ ditty_set_draft_values( $draft_values_ajax );
696
+ $editor_item = new Ditty_Item( $item_id_ajax );
697
+ $editor_layout = new Ditty_Layout( $layout_id_ajax );
698
+ $data = array(
699
+ 'editor_item' => $editor_item->render_editor_list_item( 'return' ),
700
+ 'display_items' => $editor_item->get_display_items(),
701
+ //'display_items' => ditty_display_items( $editor_item->get_ditty_id(), 'force' ),
702
+ 'layout_label' => $editor_layout->get_label(),
703
+ 'layout_css' => $editor_layout->get_css_compiled(),
704
+ );
705
+ wp_send_json( $data );
706
+ }
707
+
708
+ /**
709
+ * Return the html field to edit
710
+ *
711
+ * @access public
712
+ * @since 3.0
713
+ * @param json.
714
+ */
715
+ public function editor_fields_ajax() {
716
+ check_ajax_referer( 'ditty', 'security' );
717
+ $edit_type_ajax = isset( $_POST['edit_type'] ) ? sanitize_text_field( $_POST['edit_type'] ) : false;
718
+ $layout_id_ajax = isset( $_POST['layout_id'] ) ? sanitize_text_field( $_POST['layout_id'] ) : false;
719
+ $layout_title_ajax = isset( $_POST['layout_title'] ) ? sanitize_text_field( $_POST['layout_title'] ) : false;
720
+ $item_type_ajax = isset( $_POST['item_type'] ) ? sanitize_text_field( $_POST['item_type'] ) : false;
721
+ $item_id_ajax = isset( $_POST['item_id'] ) ? sanitize_text_field( $_POST['item_id'] ) : false;
722
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
723
+ if ( ! current_user_can( 'edit_ditty_layouts' ) ) {
724
+ wp_die();
725
+ }
726
+ ditty_set_draft_values( $draft_values_ajax );
727
+ if ( ! $layout = new Ditty_Layout( $layout_id_ajax, $item_type_ajax ) ) {
728
+ wp_die();
729
+ }
730
+
731
+ $quick_change = '';
732
+ $textarea_val = '';
733
+ $tags_list = '';
734
+ $html_tags = '';
735
+
736
+ $title = $layout->get_label();
737
+ if ( $layout_title_ajax && ( $title !== $layout_title_ajax ) ) {
738
+ $layout->set_label( $layout_title_ajax );
739
+ $title = $layout_title_ajax;
740
+ }
741
+
742
+ switch( $edit_type_ajax ) {
743
+ case 'html':
744
+ $textarea_val = stripslashes( $layout->get_html() );
745
+ $tags_list = $layout->get_tags_list();
746
+ $quick_change = '<a href="#" class="ditty-editor-options__edit-css protip" data-pt-title="' . __( 'Edit CSS', 'ditty-news-ticker' ) . '"><i class="fas fa-eye" data-class="fas fa-eye"></i></a>';
747
+ break;
748
+ case 'css':
749
+ $textarea_val = stripslashes( $layout->get_css() );
750
+ $tags_list = $layout->get_css_selectors_list();
751
+ $quick_change = '<a href="#" class="ditty-editor-options__edit-html protip" data-pt-title="' . __( 'Edit HTML', 'ditty-news-ticker' ) . '"><i class="fas fa-code" data-class="fas fa-code"></i></a>';
752
+ break;
753
+ default:
754
+ break;
755
+ }
756
+ ob_start();
757
+ ?>
758
+ <form class="ditty-editor-options ditty-metabox" data-layout_id="<?php echo $layout_id_ajax; ?>" data-item_type="<?php echo $item_type_ajax; ?>">
759
+ <div class="ditty-editor-options__contents">
760
+ <div class="ditty-editor-options__header">
761
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--start">
762
+ <a href="#" class="ditty-editor-options__back"><i class="fas fa-chevron-left" data-class="fas fa-chevron-left"></i></a>
763
+ </div>
764
+ <input class="ditty-editor-options__title" type="text" name="title" placeholder="<?php _e( 'Title Goes Here...', 'ditty-news-ticker' ); ?>" value="<?php echo $title; ?>" />
765
+ <div class="ditty-editor-options__buttons ditty-editor-options__buttons--end">
766
+ <?php echo $quick_change; ?>
767
+ <a href="#" class="ditty-editor-options__preview"><i class="fas fa-sync-alt" data-class="fas fa-sync-alt"></i></a>
768
+ </div>
769
+ </div>
770
+ <div class="ditty-editor-options__body">
771
+ <textarea class="ditty-editor-options__code" name="_ditty_layout_code" cols="80" rows="8"><?php echo $textarea_val; ?></textarea>
772
+ </div>
773
+ <div class="ditty-editor-options__footer">
774
+ <div class="ditty-editor-options__tags">
775
+ <h3><?php _e( 'Tags', 'ditty-news-ticker' ); ?><?php if ( 'html' == $edit_type_ajax ) { echo ' *'; } ?></h3>
776
+ <?php echo $tags_list; ?>
777
+ <?php if ( 'html' == $edit_type_ajax ) {
778
+ echo '<p style="margin-bottom:0;"><small>* ' . __( 'Hold the shift key when clicking the tag to paste all default attributes', 'ditty-news-ticker' ) . '</small></p>';
779
+ } ?>
780
+ </div>
781
+ </div>
782
+ </div>
783
+ </form>
784
+ <?php
785
+ $form = ob_get_clean();
786
+ wp_send_json(
787
+ array(
788
+ 'form' => $form,
789
+ 'html' => $layout->get_html(),
790
+ )
791
+ );
792
+ }
793
+
794
+ /**
795
+ * Update the layout meta
796
+ *
797
+ * @access public
798
+ * @since 3.0
799
+ * @param json.
800
+ */
801
+ public function editor_update_ajax() {
802
+ check_ajax_referer( 'ditty', 'security' );
803
+ $edit_type_ajax = isset( $_POST['edit_type'] ) ? sanitize_text_field( $_POST['edit_type'] ) : false;
804
+ $layout_id_ajax = isset( $_POST['layout_id'] ) ? sanitize_text_field( $_POST['layout_id'] ) : false;
805
+ $title_ajax = isset( $_POST['title'] ) ? sanitize_text_field( $_POST['title'] ) : false;
806
+ $item_ids_ajax = isset( $_POST['item_ids'] ) ? $_POST['item_ids'] : array();
807
+ $code_ajax = isset( $_POST['_ditty_layout_code'] ) ? wp_kses_post( $_POST['_ditty_layout_code'] ) : false;
808
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
809
+ $display_items = array();
810
+ if ( ! current_user_can( 'edit_ditty_layouts' ) ) {
811
+ wp_die();
812
+ }
813
+ ditty_set_draft_values( $draft_values_ajax );
814
+ ditty_draft_layout_update( $layout_id_ajax, $edit_type_ajax, $code_ajax );
815
+ if ( ! $editor_layout = new Ditty_Layout( $layout_id_ajax ) ) {
816
+ wp_die();
817
+ }
818
+
819
+ switch( $edit_type_ajax ) {
820
+ case 'html':
821
+ $code = $editor_layout->set_html( $code_ajax );
822
+
823
+ // Get updated items
824
+ $item_ids = array_unique( $item_ids_ajax );
825
+ if ( is_array( $item_ids ) && count( $item_ids ) > 0 ) {
826
+ foreach ( $item_ids as $i => $item_id ) {
827
+ $editor_item = new Ditty_Item( $item_id );
828
+ $display_items = array_merge( $display_items, $editor_item->get_display_items() );
829
+ }
830
+ }
831
+ break;
832
+ case 'css':
833
+ $editor_layout->set_css( $code_ajax );
834
+ $code = $editor_layout->get_css_compiled();
835
+ break;
836
+ default:
837
+ break;
838
+ }
839
+
840
+ if ( $title_ajax ) {
841
+ $editor_layout->set_label( $title_ajax );
842
+ }
843
+
844
+ wp_send_json(
845
+ array(
846
+ 'label' => $editor_layout->get_label(),
847
+ 'code' => $code,
848
+ 'display_items' => $display_items,
849
+ 'draft_id' => $editor_layout->get_layout_id(),
850
+ 'draft_meta' => $editor_layout->custom_meta(),
851
+ )
852
+ );
853
+ }
854
+
855
+ /**
856
+ * Clone a layout via ajax
857
+ *
858
+ * @since 3.0
859
+ */
860
+ public function editor_clone_ajax() {
861
+ check_ajax_referer( 'ditty', 'security' );
862
+ $layout_id_ajax = isset( $_POST['layout_id'] ) ? sanitize_text_field( $_POST['layout_id'] ) : false;
863
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
864
+ if ( ! current_user_can( 'publish_ditty_layouts' ) || ! $layout_id_ajax ) {
865
+ wp_send_json( array() );
866
+ }
867
+ ditty_set_draft_values( $draft_values_ajax );
868
+
869
+ // Get an instance of the source layout
870
+ $editor_layout = new Ditty_Layout( $layout_id_ajax );
871
+ $draft_id = uniqid( 'new-' );
872
+ $draft_label = sprintf( __( '%s Clone', 'ditty-news-ticker' ), $editor_layout->get_label() );
873
+ $editor_layout->set_layout_id( $draft_id );
874
+ $editor_layout->set_label( $draft_label );
875
+ $editor_layout->remove_version();
876
+ $data = array(
877
+ 'editor_layout' => $editor_layout->render_editor_list_item( 'return' ),
878
+ 'draft_id' => $draft_id,
879
+ 'draft_meta' => $editor_layout->custom_meta(),
880
+ );
881
+ wp_send_json( $data );
882
+ }
883
+
884
+ /**
885
+ * Return the temporary new layout IDs
886
+ *
887
+ * @access public
888
+ * @since 3.0
889
+ * @param array $new_layouts
890
+ */
891
+ private function get_new_layouts() {
892
+ if ( empty( $this->new_layouts ) ) {
893
+ $this->new_layouts = array();
894
+ }
895
+ return $this->new_layouts;
896
+ }
897
+
898
+ /**
899
+ * Return the temporary new layout IDs
900
+ *
901
+ * @access public
902
+ * @since 3.0
903
+ * @param array $new_layouts
904
+ */
905
+ private function get_updated_layouts() {
906
+ if ( empty( $this->updated_layouts ) ) {
907
+ $this->updated_layouts = array();
908
+ }
909
+ return $this->updated_layouts;
910
+ }
911
+
912
+ /**
913
+ * Update the temporary new layout IDs
914
+ *
915
+ * @access public
916
+ * @since 3.0
917
+ * @param array $new_displays
918
+ */
919
+ private function update_new_layouts( $new_id, $post_id ) {
920
+ $new_layouts = $this->get_new_layouts();
921
+ $new_layouts[$new_id] = $post_id;
922
+ $this->new_layouts = $new_layouts;
923
+ }
924
+
925
+ /**
926
+ * Modify a Ditty's draft meta
927
+ *
928
+ * @access public
929
+ * @since 3.0
930
+ * @param json.
931
+ */
932
+ public function modify_ditty_item_db_data( $item_data, $ditty_id ) {
933
+ if ( isset( $item_data['layout_value'] ) ) {
934
+ $layout_value = maybe_unserialize( $item_data['layout_value'] );
935
+ $new_layouts = $this->get_new_layouts();
936
+ $updated_layouts = $this->get_updated_layouts();
937
+ $updated_layout_value = array();
938
+ if ( is_array( $layout_value ) && count( $layout_value ) > 0 ) {
939
+ foreach ( $layout_value as $type => $id ) {
940
+ if ( false !== strpos( $id, 'new-' ) ) {
941
+ if ( isset( $new_layouts[$id] ) ) {
942
+ $updated_layout_value[$type] = $new_layouts[$id];
943
+ $updated_layouts[$id] = $new_layouts[$id];
944
+ }
945
+ } else {
946
+ $updated_layout_value[$type] = $id;
947
+ }
948
+ }
949
+ }
950
+ $item_data['layout_value'] = maybe_serialize( $updated_layout_value );
951
+ $this->updated_layouts = $updated_layouts;
952
+ }
953
+ return $item_data;
954
+ }
955
+
956
+ /**
957
+ * Add to the editor save data
958
+ *
959
+ * @access public
960
+ * @since 3.0
961
+ * @param json.
962
+ */
963
+ public function editor_add_save_data( $json_data, $ditty_id ) {
964
+ $updated_layouts = $this->get_updated_layouts();
965
+ if ( is_array( $updated_layouts ) && count( $updated_layouts ) > 0 ) {
966
+ $json_data['ditty_new_layout_ids'] = $updated_layouts;
967
+ }
968
+ return $json_data;
969
+ }
970
+
971
+ /**
972
+ * Save layout draft values on Ditty update
973
+ *
974
+ * @access public
975
+ * @since 3.0
976
+ */
977
+ public function update_drafts( $ditty_id, $draft_values ) {
978
+ if ( ! current_user_can( 'edit_ditty_layouts' ) ) {
979
+ return false;
980
+ }
981
+
982
+ $add_to_live_update = false;
983
+
984
+ if ( isset( $draft_values['layouts'] ) && is_array( $draft_values['layouts'] ) && count( $draft_values['layouts'] ) > 0 ) {
985
+ foreach ( $draft_values['layouts'] as $layout_id => $layout_data ) {
986
+
987
+ $add_to_live_update = true;
988
+
989
+ // Delete a layout
990
+ if ( 'DELETE' == $layout_data ) {
991
+ wp_trash_post( $layout_id );
992
+ continue;
993
+
994
+ } elseif( is_array( $layout_data ) ) {
995
+
996
+ // Add or update a layout
997
+ if ( false !== strpos( $layout_id, 'new-' ) ) {
998
+ $postarr = array(
999
+ 'post_type' => 'ditty_layout',
1000
+ 'post_status' => 'publish',
1001
+ 'post_title' => $layout_data['label'],
1002
+ );
1003
+ $updated_layout_id = wp_insert_post( $postarr );
1004
+ $this->update_new_layouts( $layout_id, $updated_layout_id );
1005
+ $layout_id = $updated_layout_id;
1006
+ } else {
1007
+ if ( isset( $layout_data['label'] ) ) {
1008
+ $postarr = array(
1009
+ 'ID' => $layout_id,
1010
+ 'post_title' => $layout_data['label'],
1011
+ );
1012
+ wp_update_post( $postarr );
1013
+ }
1014
+ }
1015
+
1016
+ // Update a layout description
1017
+ if ( isset( $layout_data['description'] ) ) {
1018
+ update_post_meta( $layout_id, '_ditty_layout_description', wp_kses_post( $layout_data['description'] ) );
1019
+ }
1020
+
1021
+ // Update a layout html
1022
+ if ( isset( $layout_data['html'] ) ) {
1023
+ update_post_meta( $layout_id, '_ditty_layout_html', wp_kses_post( $layout_data['html'] ) );
1024
+ }
1025
+
1026
+ // Update a layout css
1027
+ if ( isset( $layout_data['css'] ) ) {
1028
+ update_post_meta( $layout_id, '_ditty_layout_css', wp_kses_post( $layout_data['css'] ) );
1029
+ }
1030
+
1031
+ // Remove the version number of edited layouts
1032
+ delete_post_meta( $layout_id, '_ditty_layout_version' );
1033
+ delete_post_meta( $layout_id, '_ditty_layout_template' );
1034
+ }
1035
+ }
1036
+ }
1037
+ }
1038
+
1039
+ }
includes/class-ditty-loader.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Register all actions and filters for the plugin
5
+ *
6
+ * @link https://www.metaphorcreations.com
7
+ * @since 3.0
8
+ *
9
+ * @package Ditty
10
+ * @subpackage Ditty/includes
11
+ */
12
+
13
+ /**
14
+ * Register all actions and filters for the plugin.
15
+ *
16
+ * Maintain a list of all hooks that are registered throughout
17
+ * the plugin, and register them with the WordPress API. Call the
18
+ * run function to execute the list of actions and filters.
19
+ *
20
+ * @package Ditty
21
+ * @subpackage Ditty/includes
22
+ * @author Metaphor Creations <joe@metaphorcreations.com>
23
+ */
24
+ class Ditty_Loader {
25
+
26
+ /**
27
+ * The array of actions registered with WordPress.
28
+ *
29
+ * @since 3.0
30
+ * @access protected
31
+ * @var array $actions The actions registered with WordPress to fire when the plugin loads.
32
+ */
33
+ protected $actions;
34
+
35
+ /**
36
+ * The array of filters registered with WordPress.
37
+ *
38
+ * @since 3.0
39
+ * @access protected
40
+ * @var array $filters The filters registered with WordPress to fire when the plugin loads.
41
+ */
42
+ protected $filters;
43
+
44
+ /**
45
+ * Initialize the collections used to maintain the actions and filters.
46
+ *
47
+ * @since 3.0
48
+ */
49
+ public function __construct() {
50
+
51
+ $this->actions = array();
52
+ $this->filters = array();
53
+
54
+ }
55
+
56
+ /**
57
+ * Add a new action to the collection to be registered with WordPress.
58
+ *
59
+ * @since 3.0
60
+ * @param string $hook The name of the WordPress action that is being registered.
61
+ * @param object $component A reference to the instance of the object on which the action is defined.
62
+ * @param string $callback The name of the function definition on the $component.
63
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
64
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
65
+ */
66
+ public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
67
+ $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
68
+ }
69
+
70
+ /**
71
+ * Add a new filter to the collection to be registered with WordPress.
72
+ *
73
+ * @since 3.0
74
+ * @param string $hook The name of the WordPress filter that is being registered.
75
+ * @param object $component A reference to the instance of the object on which the filter is defined.
76
+ * @param string $callback The name of the function definition on the $component.
77
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
78
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1
79
+ */
80
+ public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
81
+ $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
82
+ }
83
+
84
+ /**
85
+ * A utility function that is used to register the actions and hooks into a single
86
+ * collection.
87
+ *
88
+ * @since 3.0
89
+ * @access private
90
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
91
+ * @param string $hook The name of the WordPress filter that is being registered.
92
+ * @param object $component A reference to the instance of the object on which the filter is defined.
93
+ * @param string $callback The name of the function definition on the $component.
94
+ * @param int $priority The priority at which the function should be fired.
95
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
96
+ * @return array The collection of actions and filters registered with WordPress.
97
+ */
98
+ private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
99
+
100
+ $hooks[] = array(
101
+ 'hook' => $hook,
102
+ 'component' => $component,
103
+ 'callback' => $callback,
104
+ 'priority' => $priority,
105
+ 'accepted_args' => $accepted_args
106
+ );
107
+
108
+ return $hooks;
109
+
110
+ }
111
+
112
+ /**
113
+ * Register the filters and actions with WordPress.
114
+ *
115
+ * @since 3.0
116
+ */
117
+ public function run() {
118
+
119
+ foreach ( $this->filters as $hook ) {
120
+ add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
121
+ }
122
+
123
+ foreach ( $this->actions as $hook ) {
124
+ add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
125
+ }
126
+
127
+ }
128
+
129
+ }
includes/class-ditty-roles.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Register custom roles and capabilities
5
+ *
6
+ * @link https://www.metaphorcreations.com
7
+ * @since 3.0
8
+ *
9
+ * @package Ditty
10
+ * @subpackage Ditty/includes
11
+ */
12
+
13
+ /**
14
+ * Register custom roles and capabilities
15
+ *
16
+ * Setup custom defined roles and capabilities for
17
+ * post types and settings.
18
+ *
19
+ * @since 3.0
20
+ * @package Ditty
21
+ * @subpackage Ditty/includes
22
+ * @author Metaphor Creations <joe@metaphorcreations.com>
23
+ */
24
+ class Ditty_Roles {
25
+
26
+ /**
27
+ * Add capabilities
28
+ *
29
+ * @since 3.0
30
+ * @global WP_Roles $wp_roles
31
+ * @return void
32
+ */
33
+ public function add_caps() {
34
+ global $wp_roles;
35
+
36
+ if ( class_exists( 'WP_Roles' ) ) {
37
+ if ( ! isset( $wp_roles ) ) {
38
+ $wp_roles = new WP_Roles();
39
+ }
40
+ }
41
+
42
+ if ( is_object( $wp_roles ) ) {
43
+
44
+ $wp_roles->add_cap( 'administrator', 'manage_ditty_settings' );
45
+
46
+ // Add the main post type capabilities
47
+ $capabilities = $this->get_core_caps();
48
+ foreach ( $capabilities as $cap_group ) {
49
+ foreach ( $cap_group as $cap ) {
50
+ $wp_roles->add_cap( 'administrator', $cap );
51
+ $wp_roles->add_cap( 'author', $cap );
52
+ $wp_roles->add_cap( 'editor', $cap );
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Gets the core post type capabilities
60
+ *
61
+ * @since 3.0
62
+ * @return array $capabilities Core post type capabilities
63
+ */
64
+ public function get_core_caps() {
65
+
66
+ $capabilities = array();
67
+
68
+ $capability_types = array( 'ditty', 'ditty_layout', 'ditty_display' );
69
+
70
+ foreach ( $capability_types as $capability_type ) {
71
+ $capabilities[$capability_type] = array(
72
+ // Post type
73
+ "edit_{$capability_type}",
74
+ "read_{$capability_type}",
75
+ "delete_{$capability_type}",
76
+ "edit_{$capability_type}s",
77
+ "edit_others_{$capability_type}s",
78
+ "publish_{$capability_type}s",
79
+ "read_private_{$capability_type}s",
80
+ "delete_{$capability_type}s",
81
+ "delete_private_{$capability_type}s",
82
+ "delete_published_{$capability_type}s",
83
+ "delete_others_{$capability_type}s",
84
+ "edit_private_{$capability_type}s",
85
+ "edit_published_{$capability_type}s",
86
+ );
87
+ }
88
+
89
+ $capabilities['ditty_item'] = array(
90
+ 'edit_ditty_items',
91
+ 'publish_ditty_items',
92
+ 'delete_ditty_items',
93
+ );
94
+
95
+ return $capabilities;
96
+ }
97
+
98
+
99
+ /**
100
+ * Remove core post type capabilities (called on uninstall)
101
+ *
102
+ * @since 3.0
103
+ * @return void
104
+ */
105
+ public function remove_caps() {
106
+
107
+ global $wp_roles;
108
+
109
+ if ( class_exists( 'WP_Roles' ) ) {
110
+ if ( ! isset( $wp_roles ) ) {
111
+ $wp_roles = new WP_Roles();
112
+ }
113
+ }
114
+
115
+ if ( is_object( $wp_roles ) ) {
116
+
117
+ /** Administrator Capabilities */
118
+ $wp_roles->remove_cap( 'administrator', 'manage_ditty_settings' );
119
+
120
+ /** Remove the Main Post Type Capabilities */
121
+ $capabilities = $this->get_core_caps();
122
+
123
+ foreach ( $capabilities as $cap_group ) {
124
+ foreach ( $cap_group as $cap ) {
125
+ $wp_roles->remove_cap( 'administrator', $cap );
126
+ $wp_roles->remove_cap( 'author', $cap );
127
+ $wp_roles->remove_cap( 'editor', $cap );
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ }
includes/class-ditty-singles.php ADDED
@@ -0,0 +1,718 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Singles Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Singles
8
+ * @copyright Copyright (c) 2021, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+
13
+ class Ditty_Singles {
14
+
15
+ /**
16
+ * Types
17
+ *
18
+ * @since 3.0
19
+ */
20
+ public $types = array();
21
+
22
+ /**
23
+ * Get things started
24
+ * @access public
25
+ * @since 3.0
26
+ */
27
+ public function __construct() {
28
+
29
+ // WP metabox hooks
30
+ add_action( 'edit_form_top', array( $this, 'edit_preview' ) );
31
+
32
+ // General hooks
33
+ add_filter( 'post_row_actions', array( $this, 'modify_list_row_actions' ), 10, 2 );
34
+
35
+ // Editor elements
36
+ add_action( 'ditty_editor_tabs', array( $this, 'editor_tab' ), 100, 2 );
37
+ add_action( 'ditty_editor_panels', array( $this, 'editor_settings_panel' ), 10, 2 );
38
+
39
+ // Ditty post modifications
40
+ add_action( 'admin_menu', array( $this, 'remove_metaboxes' ) );
41
+ add_filter( 'get_user_option_screen_layout_ditty', array( $this, 'force_post_layout' ) );
42
+ add_filter( 'screen_options_show_screen', array( $this, 'remove_screen_options' ), 10, 2 );
43
+
44
+
45
+
46
+ add_shortcode( 'ditty', array( $this, 'do_shortcode' ) );
47
+
48
+ // Ajax
49
+ add_action( 'wp_ajax_ditty_init', array( $this, 'init_ajax' ) );
50
+ add_action( 'wp_ajax_nopriv_ditty_init', array( $this, 'init_ajax' ) );
51
+ add_action( 'wp_ajax_ditty_live_updates', array( $this, 'live_updates_ajax' ) );
52
+ add_action( 'wp_ajax_nopriv_ditty_live_updates', array( $this, 'live_updates_ajax' ) );
53
+
54
+ // Editor Ajax
55
+ add_action( 'wp_ajax_ditty_editor_settings_update', array( $this, 'editor_settings_update_ajax' ) );
56
+ add_action( 'wp_ajax_nopriv_ditty_editor_settings_update', array( $this, 'editor_settings_update_ajax' ) );
57
+ add_action( 'wp_ajax_ditty_editor_save', array( $this, 'editor_save_ajax' ) );
58
+ add_action( 'wp_ajax_nopriv_ditty_editor_save', array( $this, 'editor_save_ajax' ) );
59
+ }
60
+
61
+ /**
62
+ * Add to the editor tabs
63
+ *
64
+ * @access public
65
+ * @since 3.0
66
+ * @param $html
67
+ */
68
+ public function editor_tab( $tabs, $ditty_id ) {
69
+ if ( ! current_user_can( 'edit_dittys' ) ) {
70
+ return false;
71
+ }
72
+ $tabs['settings'] = array(
73
+ 'icon' => 'fas fa-cog',
74
+ 'label' => __( 'Settings', 'ditty-news-ticker' ),
75
+ );
76
+ return $tabs;
77
+ }
78
+
79
+ /**
80
+ * Add the editor item types panel
81
+ *
82
+ * @access public
83
+ * @since 3.0
84
+ */
85
+ public function editor_settings_panel( $panels, $ditty_id ) {
86
+ if ( ! current_user_can( 'edit_dittys' ) ) {
87
+ return false;
88
+ }
89
+ ob_start();
90
+ ?>
91
+ <form class="ditty-editor-options ditty-metabox" data-ditty_id="<?php echo $ditty_id; ?>">
92
+ <div class="ditty-editor-options__contents">
93
+ <div class="ditty-editor-options__body">
94
+ <?php
95
+ $title = ( 'auto-draft' === get_post_status( $ditty_id ) ) ? sprintf( __( 'Ditty %d', 'ditty-news-ticker' ), $ditty_id ) : get_the_title( $ditty_id );
96
+ $status = get_post_status( $ditty_id );
97
+ $settings = get_post_meta( $ditty_id, '_ditty_settings', true );
98
+ if ( 'auto-draft' == $status ) {
99
+ $status = 'publish';
100
+ }
101
+ $shortcode = "[ditty id={$ditty_id}]";
102
+ $fields = array(
103
+ 'title' => array(
104
+ 'type' => 'text',
105
+ 'id' => 'title',
106
+ 'name' => __( 'Title', 'ditty-news-ticker' ),
107
+ 'std' => $title,
108
+ 'placeholder' => ditty_strings( 'add_title' ),
109
+ ),
110
+ 'shortcode' => array(
111
+ 'type' => 'text',
112
+ 'id' => 'shortcode',
113
+ 'name' => __( 'Shortcode', 'ditty-news-ticker' ),
114
+ 'std' => $shortcode,
115
+ ),
116
+ 'status' => array(
117
+ 'type' => 'radio',
118
+ 'id' => 'status',
119
+ 'name' => __( 'Status', 'ditty-news-ticker' ),
120
+ 'options' => [
121
+ 'publish' => __( 'Active', 'ditty-news-ticker' ),
122
+ 'draft' => __( 'Disabled', 'ditty-news-ticker' ),
123
+ ],
124
+ 'inline' => true,
125
+ 'std' => ( 'publish' != $status ) ? 'draft' : $status,
126
+ ),
127
+ 'ajax_loading' => array(
128
+ 'type' => 'radio',
129
+ 'id' => 'ajax_loading',
130
+ 'name' => __( 'Ajax Loading', 'ditty-news-ticker' ),
131
+ 'options' => [
132
+ 'no' => __( 'No', 'ditty-news-ticker' ),
133
+ 'yes' => __( 'Yes', 'ditty-news-ticker' ),
134
+ ],
135
+ 'inline' => true,
136
+ 'std' => isset( $settings['ajax_loading'] ) ? $settings['ajax_loading'] : 'no',
137
+ ),
138
+ 'live_updates' => array(
139
+ 'type' => 'radio',
140
+ 'id' => 'live_updates',
141
+ 'name' => __( 'Live Updates', 'ditty-news-ticker' ),
142
+ 'options' => [
143
+ 'no' => __( 'No', 'ditty-news-ticker' ),
144
+ 'yes' => __( 'Yes', 'ditty-news-ticker' ),
145
+ ],
146
+ 'inline' => true,
147
+ 'std' => isset( $settings['live_updates'] ) ? $settings['live_updates'] : 'no',
148
+ ),
149
+ 'preview_settings' => array(
150
+ 'type' => 'group',
151
+ 'id' => 'preview_settings',
152
+ 'collapsible' => true,
153
+ 'default_state' => 'expanded',
154
+ 'multiple_fields' => true,
155
+ 'name' => __( 'Preview Settings', 'ditty-news-ticker' ),
156
+ 'help' => __( 'Configure the editor preview style.', 'ditty-news-ticker' ),
157
+ 'fields' => array(
158
+ 'previewBg' => array(
159
+ 'type' => 'color',
160
+ 'id' => 'previewBg',
161
+ 'name' => __( 'Preview Background Color', 'ditty-news-ticker' ),
162
+ 'help' => __( 'Set a custom background color for the preview area while editing.', 'ditty-news-ticker' ),
163
+ 'std' => isset( $settings['previewBg'] ) ? $settings['previewBg'] : false,
164
+ ),
165
+ 'previewPadding' => array(
166
+ 'type' => 'spacing',
167
+ 'id' => 'previewPadding',
168
+ 'name' => __( 'Preview Padding', 'ditty-news-ticker' ),
169
+ 'std' => isset( $settings['previewPadding'] ) ? $settings['previewPadding'] : false,
170
+ ),
171
+ ),
172
+ ),
173
+ );
174
+ ditty_fields( $fields );
175
+ ?>
176
+ </div>
177
+ </div>
178
+ </form>
179
+ <?php
180
+ $panels['settings'] = ob_get_clean();
181
+ return $panels;
182
+ }
183
+
184
+ /**
185
+ * Add the edit page preview
186
+ * @access public
187
+ * @since 3.0
188
+ */
189
+ public function edit_preview() {
190
+ global $post;
191
+ if ( 'ditty' != $post->post_type ) {
192
+ return false;
193
+ }
194
+ $title = ( 'auto-draft' === get_post_status( $post->ID ) ) ? sprintf( __( 'Ditty %d', 'ditty-news-ticker' ), $post->ID ) : $post->post_title;
195
+ $settings = get_post_meta( $post->ID, '_ditty_settings', true );
196
+ $style = '';
197
+ if ( is_array( $settings ) && isset( $settings['previewBg'] ) ) {
198
+ $style .= "background-color:{$settings['previewBg']};";
199
+ }
200
+ if ( is_array( $settings ) && isset( $settings['previewPadding'] ) && is_array( $settings['previewPadding'] ) ) {
201
+ if ( isset( $settings['previewPadding']['paddingTop'] ) ) {
202
+ $style .= "padding-top:{$settings['previewPadding']['paddingTop']};";
203
+ }
204
+ if ( isset( $settings['previewPadding']['paddingBottom'] ) ) {
205
+ $style .= "padding-bottom:{$settings['previewPadding']['paddingBottom']};";
206
+ }
207
+ if ( isset( $settings['previewPadding']['paddingLeft'] ) ) {
208
+ $style .= "padding-left:{$settings['previewPadding']['paddingLeft']};";
209
+ }
210
+ if ( isset( $settings['previewPadding']['paddingRight'] ) ) {
211
+ $style .= "padding-right:{$settings['previewPadding']['paddingRight']};";
212
+ }
213
+ }
214
+ ?>
215
+ <div id="ditty-page" class="wrap">
216
+ <div id="ditty-page__header">
217
+ <h2><span class="ditty-post__title"><?php echo $title; ?></span></h2>
218
+ </div>
219
+ <div id="ditty-page__content">
220
+ <div id="ditty-editor">
221
+ <div id="ditty-editor__settings"></div>
222
+ <div id="ditty-editor__preview" style="<?php echo $style; ?>">
223
+ <?php
224
+ $display = get_post_meta( $post->ID, '_ditty_display', true );
225
+ if ( ! $display || ! ditty_display_exists( $display ) ) {
226
+ $display = ditty_default_display( $post->ID );
227
+ }
228
+ $atts = array(
229
+ 'id' => $post->ID,
230
+ 'display' => $display,
231
+ 'uniqid' => 'ditty-preview-' . $post->ID,
232
+ 'class' => 'ditty-preview',
233
+ 'show_editor' => 1,
234
+ 'load_type' => '',
235
+ );
236
+ echo ditty_render( $atts );
237
+ ?>
238
+ <div id="ditty-preview__overlay" class="ditty-updating-overlay">
239
+ <div class="ditty-updating-overlay__inner">
240
+ <i class="fas fa-sync-alt fa-spin"></i>
241
+ </div>
242
+ </div>
243
+ </div>
244
+ </div>
245
+ </div>
246
+ </div><!-- /.wrap -->
247
+ <?php
248
+ }
249
+
250
+ /**
251
+ * Add the post ID to the list row actions
252
+ *
253
+ * @since 3.0
254
+ * @return void
255
+ */
256
+ public function modify_list_row_actions( $actions, $post ) {
257
+ if ( $post->post_type == 'ditty' ) {
258
+ //$id_string = sprintf( __( 'ID: %d', 'ditty-news-ticker' ), $post->ID );
259
+ $id_array = array(
260
+ 'id' => sprintf( __( 'ID: %d', 'ditty-news-ticker' ), $post->ID ),
261
+ );
262
+ $actions = array_merge( $id_array, $actions );
263
+ }
264
+ return $actions;
265
+ }
266
+
267
+ /**
268
+ * Remove the submit div
269
+ *
270
+ * @since 3.0
271
+ * @return void
272
+ */
273
+ public function remove_metaboxes() {
274
+ remove_meta_box( 'submitdiv', 'ditty', 'side' );
275
+ remove_meta_box( 'authordiv', 'ditty', 'side' );
276
+ }
277
+
278
+ /**
279
+ * Force a single column layout
280
+ *
281
+ * @since 3.0
282
+ * @return void
283
+ */
284
+ public function force_post_layout() {
285
+ return '1';
286
+ }
287
+
288
+ /**
289
+ * Remove screen options
290
+ *
291
+ * @since 3.0
292
+ * @return void
293
+ */
294
+ public function remove_screen_options( $show_screen, $hook ) {
295
+ if ( 'ditty' === $hook->post_type && 'post' === $hook->base ) {
296
+ return false;
297
+ }
298
+ return $show_screen;
299
+ }
300
+
301
+ /**
302
+ * Display the Ditty via shortcode
303
+ *
304
+ * @since 3.0
305
+ * @access public
306
+ * @var html
307
+ */
308
+ public function do_shortcode( $atts ) {
309
+ if ( ! is_admin() ) {
310
+ return ditty_render( $atts );
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Return an array of Dittys for select fields
316
+ *
317
+ * @access public
318
+ * @since 3.0
319
+ * @param array $options.
320
+ */
321
+ public function select_field_options() {
322
+ $options = array();
323
+ $args = array(
324
+ 'posts_per_page' => -1,
325
+ 'orderby' => 'post_title',
326
+ 'order' => 'ASC',
327
+ 'post_type' => 'ditty',
328
+ );
329
+ $posts = get_posts( $args );
330
+ if ( is_array( $posts ) && count( $posts ) > 0 ) {
331
+ foreach ( $posts as $i => $post ) {
332
+ $options[$post->ID] = $post->post_title;
333
+ }
334
+ }
335
+ return $options;
336
+ }
337
+
338
+ /**
339
+ * Parse custom display settings
340
+ *
341
+ * @access public
342
+ * @since 3.0
343
+ */
344
+ public function parse_custom_display_settings( $args, $display_settings ) {
345
+ if ( '' != $display_settings && 'false' != $display_settings ) {
346
+ parse_str( html_entity_decode( $display_settings ), $custom_display_settings );
347
+ if ( is_array( $custom_display_settings ) && count( $custom_display_settings ) > 0 ) {
348
+ foreach ( $custom_display_settings as $key => $value ) {
349
+ $parts = explode( '|', $value );
350
+ if ( is_array( $parts ) && count( $parts ) > 0 ) {
351
+ foreach ( $parts as $subvalue ) {
352
+ $subparts = explode( ':', $subvalue );
353
+ if ( count( $subparts ) > 1 ) {
354
+ if ( ! isset( $args[$key] ) ) {
355
+ $args[$key] = array();
356
+ }
357
+ if ( is_array( $args[$key] ) ) {
358
+ $args[$key][$subparts[0]] = $subparts[1];
359
+ }
360
+ } else {
361
+ $args[$key] = $subparts[0];
362
+ }
363
+ }
364
+ }
365
+ }
366
+ }
367
+ }
368
+ return $args;
369
+ }
370
+
371
+ /**
372
+ * Return data for a Ditty to load via ajax
373
+ *
374
+ * @access public
375
+ * @since 3.0
376
+ */
377
+ public function init_ajax() {
378
+ check_ajax_referer( 'ditty', 'security' );
379
+ $id_ajax = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : false;
380
+ $display_ajax = isset( $_POST['display'] ) ? esc_attr( $_POST['display'] ) : false;
381
+ $display_settings_ajax = isset( $_POST['display_settings'] ) ? esc_attr( $_POST['display_settings'] ) : false;
382
+ $editor_ajax = isset( $_POST['editor'] ) ? intval( $_POST['editor'] ) : false;
383
+ $load_type = isset( $_POST['loud_type'] ) ? intval( $_POST['loud_type'] ) : '';
384
+
385
+ // Get the display attributes
386
+ if ( ! $display_ajax ) {
387
+ $display_ajax = get_post_meta( $id_ajax, '_ditty_display', true );
388
+ }
389
+ if ( ! $display_ajax || '' == $display_ajax || ! ditty_display_exists( $display_ajax ) ) {
390
+ $display_ajax = ditty_default_display( $id_ajax );
391
+ }
392
+
393
+ $display = new Ditty_Display( $display_ajax );
394
+
395
+ // Setup the ditty values
396
+ $status = get_post_status( $id_ajax );
397
+ $args = $display->get_values();
398
+ $args['id'] = $id_ajax;
399
+ $args['title'] = ( 'auto-draft' == $status ) ? '' : get_the_title( $id_ajax );
400
+ $args['status'] = $status;
401
+ $args['display'] = $display->get_display_id();
402
+ $args['showEditor'] = $editor_ajax;
403
+
404
+ $items = ditty_display_items( $id_ajax, $load_type );
405
+ if ( ! is_array( $items ) ) {
406
+ $items = array();
407
+ }
408
+ $args['items'] = $items;
409
+ $args = $this->parse_custom_display_settings( $args, $display_settings_ajax );
410
+
411
+ do_action( 'ditty_init', $id_ajax );
412
+
413
+ $data = array(
414
+ 'display_type' => $display->get_display_type(),
415
+ 'args' => $args,
416
+ );
417
+ wp_send_json( $data );
418
+ }
419
+
420
+ /**
421
+ * Return data for a Ditty to load via ajax
422
+ *
423
+ * @access public
424
+ * @since 3.0
425
+ */
426
+ public function init( $atts ) {
427
+ if ( ! $atts['data-id'] ) {
428
+ return false;
429
+ }
430
+
431
+ $ditty_id = $atts['data-id'];
432
+ $uniqid = $atts['data-uniqid'];
433
+ $display_id = isset( $atts['data-display'] ) ? $atts['data-display'] : false;
434
+ $display_settings = isset( $atts['data-display_settings'] ) ? $atts['data-display_settings'] : false;
435
+ $show_editor = isset( $atts['data-show_editor'] ) ? $atts['data-show_editor'] : false;
436
+ $load_type = isset( $atts['load_type'] ) ? $atts['load_type'] : '';
437
+
438
+ // Get the display attributes
439
+ if ( ! $display_id ) {
440
+ $display_id = get_post_meta( $ditty_id, '_ditty_display', true );
441
+ }
442
+ if ( ! $display_id || '' == $display_id || ! ditty_display_exists( $display_id ) ) {
443
+ $display_id = ditty_default_display( $ditty_id );
444
+ }
445
+ $display = new Ditty_Display( $display_id );
446
+
447
+ // Setup the ditty values
448
+ $status = get_post_status( $ditty_id );
449
+ $args = $display->get_values();
450
+
451
+ $args['id'] = $ditty_id;
452
+ $args['title'] = ( 'auto-draft' == $status ) ? '' : get_the_title( $ditty_id );
453
+ $args['status'] = $status;
454
+ $args['display'] = $display->get_display_id();
455
+ $args['showEditor'] = $show_editor;
456
+
457
+ $items = ditty_display_items( $ditty_id, $load_type );
458
+ if ( ! is_array( $items ) ) {
459
+ $items = array();
460
+ }
461
+ $args['items'] = $items;
462
+ $args = $this->parse_custom_display_settings( $args, $display_settings );
463
+
464
+ do_action( 'ditty_init', $ditty_id );
465
+
466
+ ?>
467
+ $( 'div[data-uniqid="<?php echo $uniqid; ?>"]' ).ditty_<?php echo $display->get_display_type(); ?>(<?php echo json_encode( $args ); ?>);
468
+ <?php
469
+ }
470
+
471
+ /**
472
+ * Return live updates
473
+ *
474
+ * @access public
475
+ * @since 3.0
476
+ */
477
+ public function live_updates_ajax() {
478
+ check_ajax_referer( 'ditty', 'security' );
479
+ $live_ids = isset( $_POST['live_ids'] ) ? $_POST['live_ids'] : false;
480
+ if ( ! $live_ids ) {
481
+ wp_die();
482
+ }
483
+ $updated_items = array();
484
+ if ( is_array( $live_ids ) && count( $live_ids ) > 0 ) {
485
+ foreach ( $live_ids as $ditty_id => $timestamp ) {
486
+ $updated_items[$ditty_id] = ditty_display_items( $ditty_id );
487
+ }
488
+ }
489
+ $data = array(
490
+ 'updated_items' => $updated_items,
491
+ );
492
+ wp_send_json( $data );
493
+ }
494
+
495
+ /**
496
+ * Update the settings via ajax
497
+ *
498
+ * @since 3.0
499
+ */
500
+ public function editor_settings_update_ajax() {
501
+ check_ajax_referer( 'ditty', 'security' );
502
+ $ditty_id_ajax = isset( $_POST['ditty_id'] ) ? $_POST['ditty_id'] : false;
503
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
504
+ if ( ! current_user_can( 'edit_dittys' ) || ! $ditty_id_ajax ) {
505
+ return false;
506
+ }
507
+ ditty_set_draft_values( $draft_values_ajax );
508
+ unset( $_POST['action'] );
509
+ unset( $_POST['draft_values'] );
510
+ unset( $_POST['security'] );
511
+ wp_send_json( $_POST );
512
+ }
513
+
514
+ /**
515
+ * Sanitize setting values before saving to the database
516
+ *
517
+ * @access public
518
+ * @since 3.0
519
+ */
520
+ public function sanitize_settings( $settings ) {
521
+ $sanitized_settings = array();
522
+ $sanitized_settings['ajax_loading'] = isset( $settings['ajax_loading'] ) ? esc_attr( $settings['ajax_loading'] ) : 'no';
523
+ $sanitized_settings['live_updates'] = isset( $settings['live_updates'] ) ? esc_attr( $settings['live_updates'] ) : 'no';
524
+ $sanitized_settings['previewBg'] = isset( $settings['previewBg'] ) ? sanitize_text_field( $settings['previewBg'] ) : false;
525
+ $sanitized_padding = array();
526
+ if ( isset( $settings['previewPadding'] ) && is_array( $settings['previewPadding'] ) && count( $settings['previewPadding'] ) > 0 ) {
527
+ foreach ( $settings['previewPadding'] as $key => $value ) {
528
+ $sanitized_padding[$key] = sanitize_text_field( $value );
529
+ }
530
+ }
531
+ $sanitized_settings['previewPadding'] = $sanitized_padding;
532
+ return $sanitized_settings;
533
+ }
534
+
535
+ /**
536
+ * Sanitize item values before saving to the database
537
+ *
538
+ * @access public
539
+ * @since 3.0
540
+ */
541
+ public function sanitize_item_data( $item_data ) {
542
+ $item_type = isset( $item_data['item_type'] ) ? $item_data['item_type'] : false;
543
+ $item_value = isset( $item_data['item_value'] ) ? $item_data['item_value'] : false;
544
+ $layout_value = isset( $item_data['layout_value'] ) ? $item_data['layout_value'] : false;
545
+
546
+ // Sanitize values by item type
547
+ $sanitized_item_value = false;
548
+ if ( $item_type && $item_value ) {
549
+ if ( $item_type_object = ditty_item_type_object( $item_type ) ) {
550
+ $sanitized_item_value = $item_type_object->sanitize_settings( $item_value );
551
+ }
552
+ }
553
+
554
+ // Sanitize the layout values
555
+ $sanitized_layout_value = false;
556
+ if ( is_array( $layout_value ) && count( $layout_value ) > 0 ) {
557
+ foreach ( $layout_value as $variation => $layout ) {
558
+ $sanitized_layout_value[esc_attr( $variation )] = esc_attr( $layout );
559
+ }
560
+ }
561
+
562
+ $sanitized_item = array();
563
+ if ( isset( $item_data['ditty_id'] ) ) {
564
+ $sanitized_item['ditty_id'] = intval( $item_data['ditty_id'] );
565
+ }
566
+ if ( isset( $item_data['item_id'] ) ) {
567
+ $sanitized_item['item_id'] = intval( $item_data['item_id'] );
568
+ }
569
+ if ( isset( $item_data['item_index'] ) ) {
570
+ $sanitized_item['item_index'] = intval( $item_data['item_index'] );
571
+ }
572
+ if ( isset( $item_data['item_type'] ) ) {
573
+ $sanitized_item['item_type'] = esc_attr( $item_data['item_type'] );
574
+ }
575
+ if ( isset( $item_data['item_value'] ) ) {
576
+ $sanitized_item['item_value'] = maybe_serialize( $sanitized_item_value );
577
+ }
578
+ if ( isset( $item_data['layout_id'] ) ) {
579
+ $sanitized_item['layout_id'] = esc_attr( $item_data['layout_id'] );
580
+ }
581
+ if ( isset( $item_data['layout_value'] ) ) {
582
+ $sanitized_item['layout_value'] = maybe_serialize( $sanitized_layout_value );
583
+ }
584
+ return $sanitized_item;
585
+ }
586
+
587
+ /**
588
+ * Save draft values on Ditty editor update
589
+ *
590
+ * @access public
591
+ * @since 3.0
592
+ */
593
+ public function editor_save_ajax() {
594
+ check_ajax_referer( 'ditty', 'security' );
595
+ $ditty_id_ajax = isset( $_POST['ditty_id'] ) ? $_POST['ditty_id'] : false;
596
+ $return_items_ajax = isset( $_POST['return_items'] ) ? $_POST['return_items'] : false;
597
+ $draft_values_ajax = isset( $_POST['draft_values'] ) ? $_POST['draft_values'] : false;
598
+ if ( ! current_user_can( 'edit_dittys' ) || ! $ditty_id_ajax ) {
599
+ wp_die();
600
+ }
601
+ $add_display = false;
602
+ $add_item = false;
603
+
604
+ do_action( 'ditty_editor_update', $ditty_id_ajax, $draft_values_ajax );
605
+
606
+ //ChromePhp::log( '$draft_values_ajax:', $draft_values_ajax );
607
+
608
+ $json_data = array();
609
+
610
+ $ditty_post_data = array();
611
+ if ( 'auto-draft' == get_post_status( $ditty_id_ajax ) ) {
612
+ $ditty_post_data['post_title'] = sprintf( __( 'Ditty %d', 'ditty-news-ticker' ), $ditty_id_ajax );
613
+ $ditty_post_data['post_status'] = 'publish';
614
+ }
615
+ if ( isset( $draft_values_ajax['settings'] ) ) {
616
+ if ( isset( $draft_values_ajax['settings']['title'] ) ) {
617
+ $ditty_post_data['post_title'] = $draft_values_ajax['settings']['title'];
618
+ }
619
+ if ( isset( $draft_values_ajax['settings']['status'] ) ) {
620
+ $ditty_post_data['post_status'] = esc_attr( $draft_values_ajax['settings']['status'] );
621
+ }
622
+ $sanitized_settings = $this->sanitize_settings( $draft_values_ajax['settings'] );
623
+ update_post_meta( $ditty_id_ajax, '_ditty_settings', $sanitized_settings );
624
+ }
625
+
626
+ // Publish the ditty if this is a new post
627
+ if ( 'auto-draft' == get_post_status( $ditty_id_ajax ) ) {
628
+ $ditty_post_data['post_type'] = 'ditty';
629
+ $ditty_post_data['ID'] = $ditty_id_ajax;
630
+ wp_update_post( $ditty_post_data );
631
+ $json_data['new_ditty_url'] = get_edit_post_link( $ditty_id_ajax );
632
+ $add_display = true;
633
+ $add_item = true;
634
+
635
+ // Update the ditty title
636
+ } elseif( ! empty( $ditty_post_data ) ) {
637
+ $ditty_post_data['ID'] = $ditty_id_ajax;
638
+ wp_update_post( $ditty_post_data );
639
+ }
640
+
641
+
642
+ // Sanitize default post meta
643
+ $ditty_post_meta = ( isset( $draft_values_ajax['post_meta'] ) && is_array( $draft_values_ajax['post_meta'] ) ) ? $draft_values_ajax['post_meta'] : false;
644
+ if ( $ditty_post_meta ) {
645
+ if ( is_array( $ditty_post_meta ) && count( $ditty_post_meta ) > 0 ) {
646
+ foreach ( $ditty_post_meta as $meta_key => $meta_value ) {
647
+ if ( '_ditty_display' == $meta_key ) {
648
+ $add_display = false;
649
+ }
650
+ $meta_value = apply_filters( 'ditty_post_meta_update', $meta_value, $meta_key, $ditty_id_ajax );
651
+ update_post_meta( $ditty_id_ajax, $meta_key, sanitize_text_field( $meta_value ) );
652
+ }
653
+ }
654
+ }
655
+
656
+ // If this is a new post and no display has been selected
657
+ if ( $add_display ) {
658
+ $default_display = ditty_default_display( $ditty_id_ajax );
659
+ update_post_meta( $ditty_id_ajax, '_ditty_display', $default_display );
660
+ }
661
+
662
+ // Update items
663
+ if ( isset( $draft_values_ajax['items'] ) && is_array( $draft_values_ajax['items'] ) && count( $draft_values_ajax['items'] ) > 0 ) {
664
+ foreach ( $draft_values_ajax['items'] as $item_id => $item_data ) {
665
+
666
+ if ( 'DELETE' == $item_data ) {
667
+
668
+ Ditty()->db_items->delete( $item_id );
669
+ // TODO: Delete all meta associated to item
670
+ continue;
671
+
672
+ } elseif( is_array( $item_data ) ) {
673
+
674
+ // Add or update a item
675
+ if ( isset( $item_data['data'] ) ) {
676
+ $sanitized_item_data = $this->sanitize_item_data( $item_data['data'] );
677
+ if ( false !== strpos( $item_id, 'new-' ) ) {
678
+ if ( $new_item_id = Ditty()->db_items->insert( apply_filters( 'ditty_item_db_data', $sanitized_item_data, $ditty_id_ajax ), 'item' ) ) {
679
+ if ( ! isset( $json_data['ditty_new_item_ids'] ) ) {
680
+ $json_data['ditty_new_item_ids'] = array();
681
+ }
682
+ $json_data['ditty_new_item_ids'][$item_id] = $new_item_id;
683
+ $item_id = $new_item_id;
684
+ }
685
+ } else {
686
+ Ditty()->db_items->update( $item_id, apply_filters( 'ditty_item_db_data', $sanitized_item_data, $ditty_id_ajax ), 'item_id' );
687
+ }
688
+ }
689
+
690
+ // Add or update item meta
691
+ // TODO: Sanitize item meta on save
692
+ if ( isset( $item_data['meta'] ) && is_array( $item_data['meta'] ) && count( $item_data['meta'] ) > 0 ) {
693
+ foreach ( $item_data['meta'] as $meta_key => $meta_value ) {
694
+ if ( 'delete_meta' == $meta_value ) {
695
+ ditty_item_delete_meta( $item_id, $meta_key );
696
+ } else {
697
+ ditty_item_update_meta( $item_id, $meta_key, $meta_value );
698
+ }
699
+ }
700
+ }
701
+ }
702
+ }
703
+ } elseif ( $add_item ) {
704
+ $item = ditty_get_new_item_meta( $ditty_id_ajax );
705
+ unset( $item['item_id'] );
706
+ $sanitized_item_data = $this->sanitize_item_data( $item );
707
+ Ditty()->db_items->insert( apply_filters( 'ditty_item_db_data', $sanitized_item_data, $ditty_id_ajax ), 'item' );
708
+ }
709
+
710
+ $display_items = ditty_display_items( $ditty_id_ajax, 'force' );
711
+ if ( boolval( $return_items_ajax ) ) {
712
+ $json_data['display_items'] = $display_items;
713
+ }
714
+ $json_data = apply_filters( 'ditty_editor_save_data', $json_data, $ditty_id_ajax );
715
+ wp_send_json( $json_data );
716
+ }
717
+
718
+ }
includes/class-ditty.php ADDED
@@ -0,0 +1,630 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The core plugin class.
4
+ *
5
+ * This is used to define internationalization, admin-specific hooks, and
6
+ * public-facing site hooks.
7
+ *
8
+ * Also maintains the unique identifier of this plugin as well as the current
9
+ * version of the plugin.
10
+ *
11
+ * @since 3.0
12
+ * @package Ditty
13
+ * @subpackage Ditty/includes
14
+ * @author Metaphor Creations <joe@metaphorcreations.com>
15
+ */
16
+ class Ditty {
17
+
18
+ /**
19
+ * The one true Ditty
20
+ *
21
+ * @since 3.0
22
+ * @var Ditty
23
+ */
24
+ private static $instance;
25
+
26
+ /**
27
+ * The loader that's responsible for maintaining and registering all hooks that power
28
+ * the plugin.
29
+ *
30
+ * @since 3.0
31
+ * @access protected
32
+ * @var Ditty_Loader $loader Maintains and registers all hooks for the plugin.
33
+ */
34
+ protected $loader;
35
+
36
+ /**
37
+ * The unique identifier of this plugin.
38
+ *
39
+ * @since 3.0
40
+ * @access protected
41
+ * @var string $plugin_name The string used to uniquely identify this plugin.
42
+ */
43
+ protected $plugin_name;
44
+
45
+ /**
46
+ * The current version of the plugin.
47
+ *
48
+ * @since 3.0
49
+ * @access protected
50
+ * @var string $version The current version of the plugin.
51
+ */
52
+ protected $version;
53
+
54
+ /**
55
+ * Ditty singles object.
56
+ *
57
+ * @since 3.0
58
+ * @access public
59
+ * @var object Ditty_Singles
60
+ */
61
+ public $singles;
62
+
63
+ /**
64
+ * Ditty items object.
65
+ *
66
+ * @since 3.0
67
+ * @access public
68
+ * @var object Ditty_Items
69
+ */
70
+ public $items;
71
+
72
+ /**
73
+ * Ditty layouts object.
74
+ *
75
+ * @since 3.0
76
+ * @access public
77
+ * @var object Ditty_Displays
78
+ */
79
+ public $layouts;
80
+
81
+ /**
82
+ * Ditty displays object.
83
+ *
84
+ * @since 3.0
85
+ * @access public
86
+ * @var object Ditty_Displays
87
+ */
88
+ public $displays;
89
+
90
+ /**
91
+ * Ditty editor object.
92
+ *
93
+ * @since 3.0
94
+ * @access public
95
+ * @var object Ditty_Editor
96
+ */
97
+ public $editor;
98
+
99
+ /**
100
+ * Ditty database items object.
101
+ *
102
+ * @since 3.0
103
+ * @access public
104
+ * @var object Ditty_DB_Items
105
+ */
106
+ public $db_items;
107
+
108
+ /**
109
+ * Ditty database item meta object.
110
+ *
111
+ * @since 3.0
112
+ * @access public
113
+ * @var object Ditty_DB_Item_Meta
114
+ */
115
+ public $db_item_meta;
116
+
117
+ /**
118
+ * Ditty extensions object.
119
+ *
120
+ * @since 3.0
121
+ * @access public
122
+ * @var object Ditty_Extensions
123
+ */
124
+ public $extensions;
125
+
126
+ /**
127
+ * Ditty error object.
128
+ *
129
+ * @since 3.0
130
+ * @access public
131
+ * @var object Ditty_Errors
132
+ */
133
+ public $errors;
134
+
135
+
136
+ /**
137
+ * Main Ditty Instance.
138
+ *
139
+ * Insures that only one instance of Ditty exists in memory at any one
140
+ * time. Also prevents needing to define globals all over the place.
141
+ *
142
+ * @since 3.0
143
+ * @static
144
+ * @staticvar array $instance
145
+ * @uses Ditty::setup_constants() Setup the constants needed.
146
+ * @uses Ditty::includes() Include the required files.
147
+ * @uses Ditty::load_textdomain() load the language files.
148
+ * @see DITTY()
149
+ * @return object|Ditty The one true Ditty
150
+ */
151
+ public static function instance() {
152
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Ditty ) ) {
153
+ self::$instance = new Ditty;
154
+
155
+ self::$instance->plugin_name = 'ditty-news-ticker';
156
+ self::$instance->version = WP_DEBUG ? time() : DITTY_VERSION;
157
+
158
+ self::$instance->includes();
159
+ self::$instance->set_locale();
160
+ self::$instance->define_global_hooks();
161
+ self::$instance->run();
162
+
163
+ self::$instance->db_items = new Ditty_DB_Items();
164
+ self::$instance->db_item_meta = new Ditty_DB_Item_Meta();
165
+ self::$instance->displays = new Ditty_Displays();
166
+ self::$instance->editor = new Ditty_Editor();
167
+ self::$instance->errors = new Ditty_Errors();
168
+ self::$instance->extensions = new Ditty_Extensions();
169
+ self::$instance->layouts = new Ditty_Layouts();
170
+ self::$instance->singles = new Ditty_Singles();
171
+ self::$instance->items = new Ditty_Items();
172
+ }
173
+
174
+ return self::$instance;
175
+ }
176
+
177
+ /**
178
+ * Throw error on object clone.
179
+ *
180
+ * The whole idea of the singleton design pattern is that there is a single
181
+ * object therefore, we don't want the object to be cloned.
182
+ *
183
+ * @since 3.0
184
+ * @access protected
185
+ * @return void
186
+ */
187
+ public function __clone() {
188
+ // Cloning instances of the class is forbidden.
189
+ _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'ditty-news-ticker' ), '1.0' );
190
+ }
191
+
192
+ /**
193
+ * Disable unserializing of the class.
194
+ *
195
+ * @since 3.0
196
+ * @access protected
197
+ * @return void
198
+ */
199
+ public function __wakeup() {
200
+ // Unserializing instances of the class is forbidden.
201
+ _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'ditty-news-ticker' ), '1.0' );
202
+ }
203
+
204
+ /**
205
+ * Load the required dependencies for this plugin.
206
+ *
207
+ * Include the following files that make up the plugin:
208
+ *
209
+ * - Ditty_Loader. Orchestrates the hooks of the plugin.
210
+ * - Ditty_i18n. Defines internationalization functionality.
211
+ * - Ditty_Admin. Defines all hooks for the admin area.
212
+ * - Ditty_Public. Defines all hooks for the public side of the site.
213
+ *
214
+ * Create an instance of the loader which will be used to register the hooks
215
+ * with WordPress.
216
+ *
217
+ * @since 3.0
218
+ * @access private
219
+ */
220
+ private function includes() {
221
+
222
+ //require_once DITTY_DIR . 'eddsl/eddsl.php';
223
+ if ( ! class_exists( 'ChromePhp' ) && defined( 'WP_DEBUG' ) && true === WP_DEBUG ) {
224
+ require_once DITTY_DIR . 'includes/libs/ChromePhp.php';
225
+ }
226
+ require_once DITTY_DIR . 'vendor/autoload.php';
227
+
228
+ // Add custom fields
229
+ require_once DITTY_DIR . 'includes/fields/ditty-field.php';
230
+ require_once DITTY_DIR . 'includes/fields/ditty-field-button.php';
231
+ require_once DITTY_DIR . 'includes/fields/ditty-field-checkbox.php';
232
+ require_once DITTY_DIR . 'includes/fields/ditty-field-checkboxes.php';
233
+ require_once DITTY_DIR . 'includes/fields/ditty-field-code.php';
234
+ require_once DITTY_DIR . 'includes/fields/ditty-field-color.php';
235
+ require_once DITTY_DIR . 'includes/fields/ditty-field-date.php';
236
+ require_once DITTY_DIR . 'includes/fields/ditty-field-divider.php';
237
+ require_once DITTY_DIR . 'includes/fields/ditty-field-group.php';
238
+ require_once DITTY_DIR . 'includes/fields/ditty-field-html.php';
239
+ require_once DITTY_DIR . 'includes/fields/ditty-field-image.php';
240
+ require_once DITTY_DIR . 'includes/fields/ditty-field-number.php';
241
+ require_once DITTY_DIR . 'includes/fields/ditty-field-radio.php';
242
+ require_once DITTY_DIR . 'includes/fields/ditty-field-text.php';
243
+ require_once DITTY_DIR . 'includes/fields/ditty-field-textarea.php';
244
+ require_once DITTY_DIR . 'includes/fields/ditty-field-radius.php';
245
+ require_once DITTY_DIR . 'includes/fields/ditty-field-select.php';
246
+ require_once DITTY_DIR . 'includes/fields/ditty-field-slider.php';
247
+ require_once DITTY_DIR . 'includes/fields/ditty-field-spacing.php';
248
+ require_once DITTY_DIR . 'includes/fields/ditty-field-wysiwyg.php';
249
+ require_once DITTY_DIR . 'includes/fields/helpers.php';
250
+
251
+ // Add general files
252
+ require_once DITTY_DIR . 'includes/helpers.php';
253
+ require_once DITTY_DIR . 'includes/hooks.php';
254
+ require_once DITTY_DIR . 'includes/layout-tags.php';
255
+ require_once DITTY_DIR . 'includes/layout-tag-helpers.php';
256
+ require_once DITTY_DIR . 'includes/layout-tag-hooks.php';
257
+ require_once DITTY_DIR . 'includes/layout-tag-hooks-posts.php';
258
+ require_once DITTY_DIR . 'includes/layout-templates.php';
259
+ require_once DITTY_DIR . 'includes/post-types.php';
260
+ require_once DITTY_DIR . 'includes/upgrades.php';
261
+ require_once DITTY_DIR . 'includes/widget.php';
262
+
263
+ // Add database files
264
+ require_once DITTY_DIR . 'includes/class-ditty-db.php';
265
+ require_once DITTY_DIR . 'includes/class-ditty-db-items.php';
266
+ require_once DITTY_DIR . 'includes/class-ditty-db-item-meta.php';
267
+
268
+ // Add 3rd party files
269
+ //require_once DITTY_DIR . 'includes/libs/scssphp/scss.inc.php';
270
+
271
+ // The class responsible for orchestrating the actions and filters of the core plugin.
272
+ require_once DITTY_DIR . 'includes/class-ditty-loader.php';
273
+
274
+ // The class responsible for defining internationalization functionality of the plugin.
275
+ require_once DITTY_DIR . 'includes/class-ditty-i18n.php';
276
+
277
+ // The class responsible for setting custom roles and capabalities.
278
+ require_once DITTY_DIR . 'includes/class-ditty-roles.php';
279
+
280
+ // The class responsible for defining all actions that occur in the public-facing side of the site.
281
+ require_once DITTY_DIR . 'includes/class-ditty-display.php';
282
+ require_once DITTY_DIR . 'includes/class-ditty-display-item.php';
283
+ require_once DITTY_DIR . 'includes/class-ditty-displays.php';
284
+ require_once DITTY_DIR . 'includes/class-ditty-display-type.php';
285
+ require_once DITTY_DIR . 'includes/class-ditty-display-type-ticker.php';
286
+ require_once DITTY_DIR . 'includes/class-ditty-display-type-list.php';
287
+ require_once DITTY_DIR . 'includes/class-ditty-editor.php';
288
+ require_once DITTY_DIR . 'includes/class-ditty-errors.php';
289
+ require_once DITTY_DIR . 'includes/class-ditty-extensions.php';
290
+ require_once DITTY_DIR . 'includes/class-ditty-layout.php';
291
+ require_once DITTY_DIR . 'includes/class-ditty-layouts.php';
292
+ require_once DITTY_DIR . 'includes/class-ditty-item.php';
293
+ require_once DITTY_DIR . 'includes/class-ditty-items.php';
294
+ require_once DITTY_DIR . 'includes/class-ditty-item-type.php';
295
+ require_once DITTY_DIR . 'includes/class-ditty-item-type-default.php';
296
+ require_once DITTY_DIR . 'includes/class-ditty-item-type-wp-editor.php';
297
+ require_once DITTY_DIR . 'includes/class-ditty-item-type-posts-lite.php';
298
+ require_once DITTY_DIR . 'includes/class-ditty-singles.php';
299
+
300
+ //require_once DITTY_DIR . 'blocks/ditty-block/index.php';
301
+
302
+ if ( is_admin() ) {
303
+ if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
304
+ require_once DITTY_DIR . 'includes/admin/EDD_SL_Plugin_Updater.php';
305
+ }
306
+ require_once DITTY_DIR . 'includes/admin/columns.php';
307
+ require_once DITTY_DIR . 'includes/admin/settings.php';
308
+ require_once DITTY_DIR . 'includes/admin/info.php';
309
+ }
310
+
311
+ // Possibly add Ditty News Ticker
312
+ if ( ditty_news_ticker_enabled() ) {
313
+ require_once DITTY_DIR . 'legacy/legacy.php';
314
+ }
315
+
316
+ $this->loader = new Ditty_Loader();
317
+
318
+ do_action( 'ditty_loaded' );
319
+ }
320
+
321
+ /**
322
+ * Define the locale for this plugin for internationalization.
323
+ *
324
+ * Uses the Ditty_i18n class in order to set the domain and to register the hook
325
+ * with WordPress.
326
+ *
327
+ * @since 3.0
328
+ * @access private
329
+ */
330
+ private function set_locale() {
331
+ $plugin_i18n = new Ditty_i18n();
332
+ $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
333
+ }
334
+
335
+ /**
336
+ * Register all of the hooks that have global functionality
337
+ * of the plugin.
338
+ *
339
+ * @since 3.0
340
+ * @access private
341
+ */
342
+ private function define_global_hooks() {
343
+ $this->loader->add_action( 'admin_enqueue_scripts', $this, 'enqueue_styles' );
344
+ $this->loader->add_action( 'wp_enqueue_scripts', $this, 'enqueue_styles' );
345
+ $this->loader->add_action( 'admin_enqueue_scripts', $this, 'enqueue_scripts' );
346
+ $this->loader->add_action( 'wp_enqueue_scripts', $this, 'enqueue_scripts' );
347
+ //$this->loader->add_action( 'enqueue_block_editor_assets', $this, 'enqueue_block_editor_assets' );
348
+ //$this->loader->add_action( 'enqueue_block_assets', $this, 'enqueue_block_assets' );
349
+ $this->loader->add_action( 'admin_footer', $this, 'enqueue_global_scripts', 20 );
350
+ $this->loader->add_action( 'wp_footer', $this, 'enqueue_global_scripts', 20 );
351
+ }
352
+
353
+ /**
354
+ * Run the loader to execute all of the hooks with WordPress.
355
+ *
356
+ * @since 3.0
357
+ */
358
+ public function run() {
359
+ $this->loader->run();
360
+ }
361
+
362
+ /**
363
+ * The name of the plugin used to uniquely identify it within the context of
364
+ * WordPress and to define internationalization functionality.
365
+ *
366
+ * @since 3.0
367
+ * @return string The name of the plugin.
368
+ */
369
+ public function get_plugin_name() {
370
+ return $this->plugin_name;
371
+ }
372
+
373
+ /**
374
+ * The reference to the class that orchestrates the hooks with the plugin.
375
+ *
376
+ * @since 3.0
377
+ * @return Ditty_Loader Orchestrates the hooks of the plugin.
378
+ */
379
+ public function get_loader() {
380
+ return $this->loader;
381
+ }
382
+
383
+ /**
384
+ * Retrieve the version number of the plugin.
385
+ *
386
+ * @since 3.0
387
+ * @return string The version number of the plugin.
388
+ */
389
+ public function get_version() {
390
+ return $this->version;
391
+ }
392
+
393
+ /**
394
+ * Write to the log
395
+ *
396
+ * @since 3.0
397
+ * @return null
398
+ */
399
+ public function write_log( $log ) {
400
+ if ( is_array( $log ) || is_object( $log ) ) {
401
+ error_log( print_r( $log, true ) );
402
+ } else {
403
+ error_log( $log );
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Register the stylesheets.
409
+ *
410
+ * @since 3.0
411
+ */
412
+ public function enqueue_styles() {
413
+ wp_enqueue_style( 'ditty', DITTY_URL . 'includes/css/ditty.css', array(), $this->version, 'all' );
414
+
415
+ if ( current_user_can( 'edit_dittys' ) || current_user_can( 'edit_ditty_layouts' ) ) {
416
+ wp_enqueue_style( 'fontawesome', 'https://use.fontawesome.com/releases/v5.15.3/css/all.css', false, '5.15.3', false );
417
+ wp_enqueue_style( 'wp-codemirror' );
418
+ wp_enqueue_style( 'protip', DITTY_URL . 'includes/libs/protip/protip.min.css', false, '1.4.21', false );
419
+ wp_enqueue_style( 'ion-rangeslider', DITTY_URL . 'includes/libs/ion.rangeSlider/css/ion.rangeSlider.min.css', false, '2.3.1', false );
420
+ wp_enqueue_style( 'jquery-minicolors', DITTY_URL . 'includes/libs/jquery-minicolors/jquery.minicolors.css', false, '2.3.5', false );
421
+ //wp_enqueue_style( 'jquery-ui', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css' );
422
+ }
423
+ if ( is_admin() ) {
424
+ wp_enqueue_style( 'ditty-admin', DITTY_URL . 'includes/css/ditty-admin.css', array(), $this->version, 'all' );
425
+ } else {
426
+
427
+ // Add scripts for the global Dittys
428
+ $global_ditty = ditty_settings( 'global_ditty' );
429
+ if ( is_array( $global_ditty ) && count( $global_ditty ) > 0 ) {
430
+ foreach ( $global_ditty as $i => $global_ditty ) {
431
+ if ( 'publish' === get_post_status( $global_ditty['ditty'] ) ) {
432
+ ditty_add_scripts( $global_ditty['ditty'], $global_ditty['display'] );
433
+ }
434
+ }
435
+ }
436
+ }
437
+ }
438
+
439
+ /**
440
+ * Register the JavaScript for the public-facing side of the site.
441
+ *
442
+ * @since 3.0
443
+ */
444
+ public function enqueue_scripts( $hook ) {
445
+ $min = WP_DEBUG ? '' : '.min';
446
+
447
+ wp_register_script( 'hammer', DITTY_URL . 'includes/libs/hammer.min.js', array( 'jquery' ), '2.0.8', true );
448
+ wp_register_script( 'protip', DITTY_URL . 'includes/libs/protip/protip.min.js', array( 'jquery' ), '1.4.21', true );
449
+ wp_register_script( 'ditty', DITTY_URL . 'includes/js/ditty.min.js', array( 'jquery', 'jquery-effects-core', ), $this->version, true );
450
+ wp_add_inline_script( 'ditty', 'const dittyVars = ' . json_encode( array(
451
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
452
+ 'security' => wp_create_nonce( 'ditty' ),
453
+ 'mode' => WP_DEBUG ? 'development' : 'production',
454
+ 'strings' => ditty_strings(),
455
+ 'adminStrings' => is_admin() ? ditty_admin_strings() : false,
456
+ 'globals' => ditty_get_globals(),
457
+ 'updateIcon' => 'fas fa-sync-alt fa-spin',
458
+ 'updateInterval' => ( MINUTE_IN_SECONDS * ditty_settings( 'live_refresh' ) ),
459
+ 'editor' => array(
460
+ 'ditty_layouts_sass' => ditty_settings( 'ditty_layouts_sass' ),
461
+ ),
462
+ ) ), 'before' );
463
+
464
+ wp_register_script( 'ditty-slider', DITTY_URL . 'includes/js/class-ditty-slider' . $min . '.js', array( 'jquery', 'hammer' ), $this->version, true );
465
+ wp_register_script( 'ditty-display-ticker', DITTY_URL . 'includes/js/class-ditty-display-ticker' . $min . '.js', array( 'jquery' ), $this->version, true );
466
+ wp_register_script( 'ditty-display-list', DITTY_URL . 'includes/js/class-ditty-display-list' . $min . '.js', array( 'jquery', 'ditty-slider' ), $this->version, true );
467
+
468
+ wp_enqueue_script( 'ion-rangeslider', DITTY_URL . 'includes/libs/ion.rangeSlider/js/ion.rangeSlider.min.js', array( 'jquery' ), '2.3.1', true );
469
+ wp_enqueue_script( 'jquery-minicolors', DITTY_URL . 'includes/libs/jquery-minicolors/jquery.minicolors.min.js', array( 'jquery' ), '2.3.5', true );
470
+ wp_enqueue_script( 'ditty-fields', DITTY_URL . 'includes/fields/js/ditty-fields.min.js', array(
471
+ 'jquery',
472
+ 'protip',
473
+ 'jquery-effects-core',
474
+ 'wp-codemirror',
475
+ 'ion-rangeslider',
476
+ 'jquery-minicolors',
477
+ ), $this->version, true );
478
+ wp_register_script( 'ditty-editor', DITTY_URL . 'includes/js/ditty-editor.min.js', array(
479
+ 'jquery',
480
+ 'protip',
481
+ 'iris',
482
+ 'jquery-form',
483
+ 'jquery-ui-core',
484
+ 'jquery-effects-core',
485
+ 'wp-codemirror',
486
+ 'ditty-slider',
487
+ 'ditty-fields',
488
+ ), $this->version, true );
489
+ wp_register_script( 'ditty-admin', DITTY_URL . 'includes/js/ditty-admin.min.js', array(
490
+ 'jquery',
491
+ 'jquery-ui-core',
492
+ 'jquery-ui-sortable',
493
+ 'wp-i18n',
494
+ ), $this->version, true );
495
+ wp_add_inline_script( 'ditty-admin', 'const dittyAdminVars = ' . json_encode( array(
496
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
497
+ 'security' => wp_create_nonce( 'ditty' ),
498
+ 'mode' => WP_DEBUG ? 'development' : 'production',
499
+ 'adminStrings' => is_admin() ? ditty_admin_strings() : false,
500
+ 'updateIcon' => 'fas fa-sync-alt fa-spin',
501
+ ) ), 'before' );
502
+
503
+ // wp_localize_script( 'ditty-admin', 'dittyAdminVars', array(
504
+ // 'ajaxurl' => admin_url( 'admin-ajax.php' ),
505
+ // 'security' => wp_create_nonce( 'ditty' ),
506
+ // 'adminStrings' => is_admin() ? ditty_admin_strings() : false,
507
+ // 'update_icon' => 'fas fa-sync-alt fa-spin',
508
+ // )
509
+ // );
510
+
511
+
512
+ if ( is_admin() ) {
513
+
514
+ // Make sure to enqueue the scripts in the admin
515
+ wp_enqueue_script( 'ditty-display-ticker' );
516
+ wp_enqueue_script( 'ditty-display-list' );
517
+
518
+ if ( current_user_can( 'edit_dittys' ) || current_user_can( 'edit_ditty_layouts' ) ) {
519
+ wp_enqueue_editor();
520
+ wp_enqueue_code_editor(
521
+ array(
522
+ 'type' => 'text/html'
523
+ )
524
+ );
525
+ wp_enqueue_script( 'ditty-editor' );
526
+ }
527
+ if ( current_user_can( 'manage_ditty_settings' ) ) {
528
+ wp_enqueue_script( 'ditty-admin' );
529
+ }
530
+
531
+ // Disable autosave for Ditty posts
532
+ if ( 'ditty' == get_post_type() ) {
533
+ wp_enqueue_script( 'ditty' );
534
+ wp_dequeue_script( 'autosave' );
535
+ }
536
+ }
537
+ }
538
+
539
+ /**
540
+ * Enqueue block editor only JavaScript and CSS
541
+ *
542
+ * @since 3.0
543
+ */
544
+ // public function enqueue_block_editor_assets() {
545
+ // wp_enqueue_style(
546
+ // 'ditty-blocks-editor',
547
+ // DITTY_URL . 'includes/css/blocks.editor.css',
548
+ // [ ],
549
+ // $this->version,
550
+ // );
551
+ //
552
+ // wp_enqueue_script(
553
+ // 'ditty-blocks-editor',
554
+ // DITTY_URL . 'includes/js/editor.blocks.js',
555
+ // [ 'wp-i18n', 'wp-element', 'wp-blocks', 'wp-components', 'wp-editor' ],
556
+ // $this->version,
557
+ // true,
558
+ // );
559
+ // wp_add_inline_script( 'ditty-blocks-editor', 'const dittyBlocksEditorVars = ' . json_encode( array(
560
+ // 'displays' => Ditty()->displays->get_displays_data(),
561
+ // ) ), 'before' );
562
+ // }
563
+
564
+ /**
565
+ * Enqueue front end and editor JavaScript and CSS assets
566
+ *
567
+ * @since 3.0
568
+ */
569
+ // public function enqueue_block_assets() {
570
+ // wp_enqueue_style(
571
+ // 'ditty-blocks',
572
+ // DITTY_URL . 'includes/css/blocks.style.css',
573
+ // [],
574
+ // $this->version
575
+ // );
576
+ //
577
+ // wp_enqueue_script(
578
+ // 'ditty-blocks',
579
+ // DITTY_URL . 'includes/js/frontend.blocks.js',
580
+ // [],
581
+ // $this->version,
582
+ // true,
583
+ // );
584
+ // }
585
+
586
+ /**
587
+ * Enqueue global scripts for any Ditty's displayed
588
+ *
589
+ * @since 3.0
590
+ */
591
+ public function enqueue_global_scripts() {
592
+ global $ditty_item_scripts;
593
+ if ( empty( $ditty_item_scripts ) ) {
594
+ $ditty_item_scripts = array();
595
+ }
596
+ global $ditty_display_scripts;
597
+ if ( empty( $ditty_display_scripts ) ) {
598
+ $ditty_display_scripts = array();
599
+ }
600
+ if ( is_array( $ditty_item_scripts ) && count( $ditty_item_scripts ) > 0 ) {
601
+ foreach ( $ditty_item_scripts as $i => $ditty_item_script ) {
602
+ wp_print_scripts( "ditty-{$ditty_item_script}" );
603
+ }
604
+ }
605
+ if ( is_array( $ditty_display_scripts ) && count( $ditty_display_scripts ) > 0 ) {
606
+ wp_print_scripts( 'ditty' );
607
+ foreach ( $ditty_display_scripts as $i => $ditty_display_script ) {
608
+ wp_print_scripts( "ditty-display-{$ditty_display_script}" );
609
+ }
610
+ }
611
+ global $ditty_singles;
612
+ if ( empty( $ditty_singles ) ) {
613
+ $ditty_singles = array();
614
+ }
615
+ if ( is_array( $ditty_singles ) && count( $ditty_singles ) > 0 ) {
616
+ ?>
617
+ <script id="ditty-singles">
618
+ jQuery( document ).ready( function( $ ) {
619
+ <?php
620
+ foreach ( $ditty_singles as $ditty_atts ) {
621
+ Ditty()->singles->init( $ditty_atts );
622
+ }
623
+ ?>
624
+ } );
625
+ </script>
626
+ <?php
627
+ }
628
+ }
629
+
630
+ }
includes/css/blocks.editor-min.css ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ .wp-block-metaphorcreations-ditty-block {
2
+ border: 2px solid #39b44a;
3
+ padding: 20px; }
includes/css/blocks.editor.css ADDED
@@ -0,0 +1 @@
 
1
+ .ditty-logo--white,.ditty-icon--white{fill:#FFF !important}.ditty-logo--green,.ditty-icon--green{fill:#39b44a !important}.wp-block-metaphorcreations-ditty-block{background:rgba(255,255,255,0.8);border:2px solid #39b44a;padding:20px}.wp-block-metaphorcreations-ditty-block__info{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;-ms-flex-pack:start;justify-content:flex-start}.wp-block-metaphorcreations-ditty-block__vals{font-size:14px;color:#FFF;background:#39b44a;border-radius:3px;padding:5px 10px;margin-right:5px}.wp-block-metaphorcreations-ditty-block__controls{margin-top:15px}.wp-block-metaphorcreations-ditty-block__controls label{width:60px;font-weight:bold}.wp-block-metaphorcreations-ditty-block select{padding-top:0 !important;padding-bottom:0 !important}.wp-block-metaphorcreations-ditty-block svg{max-height:60px;margin-right:10px}
includes/css/blocks.style.css ADDED
File without changes
includes/css/ditty-admin.css ADDED
@@ -0,0 +1,1622 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wp-admin.post-type-ditty .wrap {
2
+ margin-right: 2px; }
3
+
4
+ .wp-admin.post-type-ditty #poststuff {
5
+ min-width: inherit; }
6
+
7
+ .wp-admin.post-type-ditty #post-body-content {
8
+ min-width: inherit; }
9
+
10
+ .wp-admin.post-type-ditty #post-body.columns-2 #postbox-container-1 {
11
+ margin-right: -400px;
12
+ width: 380px; }
13
+
14
+ .wp-admin.post-type-ditty #poststuff #post-body.columns-2 {
15
+ margin-right: 400px; }
16
+ .wp-admin.post-type-ditty #poststuff #post-body.columns-2 #side-sortables {
17
+ width: 380px; }
18
+
19
+ .wp-admin.post-type-ditty #titlediv {
20
+ display: none; }
21
+
22
+ @media only screen and (max-width: 850px) {
23
+ .wp-admin.post-type-ditty #poststuff #post-body.columns-2 #side-sortables {
24
+ width: auto; } }
25
+
26
+ #adminmenu .menu-icon-ditty div.wp-menu-image.svg {
27
+ background-size: 16px auto; }
28
+
29
+ table.wp-list-table .type-ditty .row-actions,
30
+ table.wp-list-table .type-ditty_layout .row-actions,
31
+ table.wp-list-table .type-ditty_display .row-actions {
32
+ color: #999; }
33
+
34
+ .ditty_layout_ui--disabled #adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_layout"] {
35
+ display: none; }
36
+
37
+ .ditty_display_ui--disabled #adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_display"] {
38
+ display: none; }
39
+
40
+ .ditty-error-notice {
41
+ line-height: 1.4em;
42
+ font-weight: bold;
43
+ color: #E1362E;
44
+ background: #fbeaea;
45
+ border: 1px solid #E1362E;
46
+ border-radius: 3px;
47
+ padding: 7px 10px; }
48
+
49
+ #adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_news_ticker"],
50
+ #adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty&page=mtphr_dnt_settings"] {
51
+ background-color: rgba(255, 255, 255, 0.1);
52
+ box-shadow: -5px 0 0 0 rgba(255, 255, 255, 0.1); }
53
+
54
+ #adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_news_ticker"] {
55
+ padding-top: 8px;
56
+ margin-top: 8px; }
57
+
58
+ #adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty&page=mtphr_dnt_settings"] {
59
+ padding-bottom: 8px;
60
+ margin-bottom: -8px; }
61
+
62
+ .ditty-field {
63
+ padding: 10px 0;
64
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05); }
65
+ .ditty-field:last-of-type {
66
+ border-bottom: none; }
67
+ .ditty-field__heading {
68
+ position: relative; }
69
+ .ditty-field__label {
70
+ display: block;
71
+ font-weight: 600;
72
+ margin-bottom: 10px;
73
+ cursor: default; }
74
+ .ditty-field__help {
75
+ font-size: 0.8em; }
76
+ .ditty-field__input {
77
+ display: flex;
78
+ flex-direction: row;
79
+ align-items: center;
80
+ justify-content: flex-start;
81
+ flex-wrap: wrap;
82
+ position: relative;
83
+ margin: 5px 0; }
84
+ .ditty-field__input__container {
85
+ position: relative; }
86
+ .ditty-field__input__primary {
87
+ flex: 1; }
88
+ .ditty-field__input__before {
89
+ flex: 0 0 auto;
90
+ margin-right: 5px; }
91
+ .ditty-field__input__after {
92
+ margin-left: 5px; }
93
+ .ditty-field__input input:not([type="button"]):not([type="checkbox"]):not([type="radio"]),
94
+ .ditty-field__input select,
95
+ .ditty-field__input textarea {
96
+ width: 100%;
97
+ min-height: 0;
98
+ font-size: 14px;
99
+ line-height: 24px;
100
+ border: 1px solid #dfdfdf;
101
+ border-radius: 3px;
102
+ padding: 5px 10px;
103
+ margin: 0; }
104
+ .ditty-field__input input[type="number"] {
105
+ width: auto; }
106
+ .ditty-field__input textarea {
107
+ padding: 10px 10px; }
108
+ .ditty-field__input:hover .ditty-field__actions {
109
+ display: flex; }
110
+ .ditty-field__input__actions {
111
+ width: 100%;
112
+ display: flex;
113
+ flex-direction: row;
114
+ align-items: center;
115
+ justify-content: flex-end;
116
+ background: #FFF;
117
+ border: 1px solid #dfdfdf;
118
+ padding: 3px;
119
+ border-radius: 3px;
120
+ margin-bottom: 3px; }
121
+ .ditty-field__input__actions a {
122
+ display: block;
123
+ flex: 0 0 auto;
124
+ text-decoration: none;
125
+ color: rgba(0, 0, 0, 0.4);
126
+ margin: 0 2px;
127
+ overflow: hidden;
128
+ transition: color 0.25s ease; }
129
+ .ditty-field__input__actions a.ditty-field__input__action--arrange {
130
+ margin-right: auto; }
131
+ .ditty-field__input__actions a:hover {
132
+ color: rgba(0, 0, 0, 0.7); }
133
+ .ditty-field__input__actions a:hover i {
134
+ transform: scale(1.2); }
135
+ .ditty-field__input__actions i {
136
+ display: block;
137
+ width: 20px;
138
+ height: 20px;
139
+ text-align: center;
140
+ line-height: 20px;
141
+ transition: transform 0.3s ease; }
142
+ .ditty-field__actions__clone {
143
+ margin-bottom: 0; }
144
+
145
+ .ditty-field__label + .ditty-field__description {
146
+ margin-top: 5px; }
147
+
148
+ .ditty-field--clone-enabled .ditty-input--clone {
149
+ background: #f7f7f7;
150
+ border: 1px dashed rgba(0, 0, 0, 0.1);
151
+ padding: 5px; }
152
+
153
+ .ditty-field--clone-enabled[data-input_count="1"] > .ditty-field__input__container > .ditty-field__input > .ditty-field__input__actions .ditty-field__input__action--arrange,
154
+ .ditty-field--clone-enabled[data-input_count="1"] > .ditty-field__input__container > .ditty-field__input > .ditty-field__input__actions .ditty-field__input__action--remove {
155
+ display: none; }
156
+
157
+ .ditty-field--clone-enabled.ditty-field--clone-enabled--max > .ditty-field__clone {
158
+ display: none; }
159
+
160
+ .ditty-field--clone-enabled.ditty-field--clone-enabled--max > .ditty-field__input__container > .ditty-field__input__container > .ditty-field__input > .ditty-field__input__actions .ditty-field__input__action--add,
161
+ .ditty-field--clone-enabled.ditty-field--clone-enabled--max > .ditty-field__input__container > .ditty-field__input__container > .ditty-field__input > .ditty-field__input__actions .ditty-field__input__action--clone {
162
+ display: none; }
163
+
164
+ /* Group */
165
+ .ditty-field-type--group {
166
+ padding: 0;
167
+ border-color: rgba(0, 0, 0, 0.05); }
168
+ .ditty-field-type--group > .ditty-field__input__container {
169
+ overflow: hidden; }
170
+ .ditty-field-type--group .ditty-input--group__container {
171
+ display: flex;
172
+ flex-direction: row;
173
+ align-items: center;
174
+ justify-content: flex-start;
175
+ flex-wrap: wrap; }
176
+ .ditty-field-type--group > .ditty-field__heading {
177
+ display: flex;
178
+ flex-direction: row;
179
+ align-items: center;
180
+ justify-content: flex-start;
181
+ color: #FFF;
182
+ background: #32373C;
183
+ padding: 15px;
184
+ margin: 0; }
185
+ .ditty-field-type--group > .ditty-field__heading label {
186
+ margin-bottom: 0; }
187
+ .ditty-field-type--group .ditty-field__collapsible-toggle {
188
+ position: absolute;
189
+ right: 10px;
190
+ top: 50%;
191
+ width: 20px;
192
+ height: 20px;
193
+ display: flex;
194
+ flex-direction: row;
195
+ align-items: center;
196
+ justify-content: center;
197
+ text-decoration: none;
198
+ margin-top: -10px;
199
+ color: #FFF;
200
+ background: rgba(255, 255, 255, 0.2);
201
+ border-radius: 50%;
202
+ transition: transform .25s ease; }
203
+ .ditty-field-type--group[data-collapsible="expanded"] .ditty-field__collapsible-toggle {
204
+ transform: rotate(180deg); }
205
+
206
+ .ditty-input--group {
207
+ margin: 0; }
208
+ .ditty-input--group__container > .ditty-field {
209
+ width: 100%; }
210
+
211
+ .ditty-field-type--group-child {
212
+ margin: 0;
213
+ padding: 8px;
214
+ border-bottom: none; }
215
+
216
+ /* Checkboxes */
217
+ .ditty-field-type--checkboxes > .ditty-field__input {
218
+ margin: -2px; }
219
+
220
+ .ditty-field-type--checkboxes .ditty-input--checkboxes__group {
221
+ display: flex;
222
+ flex-direction: row;
223
+ align-items: center;
224
+ justify-content: flex-start;
225
+ flex-wrap: wrap; }
226
+ .ditty-field-type--checkboxes .ditty-input--checkboxes__group > .ditty-field {
227
+ margin: 2px; }
228
+
229
+ .ditty-field-type--checkboxes input[type="checkbox"] {
230
+ margin-top: 0; }
231
+
232
+ .ditty-field-type--checkbox input[type="checkbox"] {
233
+ margin-top: 0; }
234
+
235
+ /* Radio */
236
+ .ditty-field-type--radio .ditty-input--radio {
237
+ margin-bottom: 0; }
238
+ .ditty-field-type--radio .ditty-input--radio .ditty-field__input__primary {
239
+ display: flex;
240
+ flex-direction: column;
241
+ align-items: flex-start;
242
+ justify-content: flex-start;
243
+ min-height: 36px; }
244
+ .ditty-field-type--radio .ditty-input--radio--inline .ditty-field__input__primary {
245
+ flex-direction: row;
246
+ align-items: center; }
247
+ .ditty-field-type--radio .ditty-input--radio--inline .ditty-input--radio__option {
248
+ margin-bottom: 0;
249
+ margin-right: 15px; }
250
+ .ditty-field-type--radio .ditty-input--radio--inline .ditty-input--radio__option:last-child {
251
+ margin-right: 0; }
252
+ .ditty-field-type--radio .ditty-input--radio__option {
253
+ display: block;
254
+ margin-top: 2px;
255
+ margin-bottom: 5px; }
256
+
257
+ /* Slider */
258
+ .ditty-field-type--slider .irs--flat .irs-bar,
259
+ .ditty-field-type--slider .irs--flat .irs-from,
260
+ .ditty-field-type--slider .irs--flat .irs-to,
261
+ .ditty-field-type--slider .irs--flat .irs-single {
262
+ background-color: #19BF7C; }
263
+
264
+ .ditty-field-type--slider .irs--flat .irs-from:before,
265
+ .ditty-field-type--slider .irs--flat .irs-to:before,
266
+ .ditty-field-type--slider .irs--flat .irs-single:before {
267
+ border-top-color: #19BF7C; }
268
+
269
+ .ditty-field-type--slider .irs--flat .irs-handle > i:first-child {
270
+ background-color: #19BF7C; }
271
+
272
+ .ditty-field-type--slider .irs--flat .irs-handle {
273
+ top: 0; }
274
+
275
+ .ditty-field-type--slider .irs--flat .irs-line,
276
+ .ditty-field-type--slider .irs--flat .irs-bar {
277
+ top: 3px; }
278
+
279
+ .ditty-field-type--slider .irs-from,
280
+ .ditty-field-type--slider .irs-to,
281
+ .ditty-field-type--slider .irs-single {
282
+ top: 25px; }
283
+
284
+ .ditty-field-type--slider .irs--flat .irs-min,
285
+ .ditty-field-type--slider .irs--flat .irs-max {
286
+ top: 25px; }
287
+
288
+ .ditty-field-type--slider .irs--flat .irs-from:before,
289
+ .ditty-field-type--slider .irs--flat .irs-to:before,
290
+ .ditty-field-type--slider .irs--flat .irs-single:before {
291
+ top: -6px;
292
+ bottom: auto;
293
+ border-top-color: transparent;
294
+ border-bottom-color: #19BF7C; }
295
+
296
+ /* Color */
297
+ .ditty-field-type--color input[type="text"] {
298
+ height: auto;
299
+ padding-left: 40px !important; }
300
+
301
+ .ditty-field-type--color .minicolors-theme-default.minicolors {
302
+ width: 100%; }
303
+
304
+ .ditty-field-type--color .minicolors-theme-default .minicolors-swatch {
305
+ top: 5px;
306
+ left: 5px;
307
+ width: 26px;
308
+ height: 26px; }
309
+
310
+ /* Spacing */
311
+ .ditty-input--spacing__group {
312
+ display: flex;
313
+ flex-direction: row;
314
+ align-items: center;
315
+ justify-content: flex-start;
316
+ flex-wrap: wrap;
317
+ margin: 0 -2px; }
318
+ .ditty-input--spacing__group .ditty-field {
319
+ width: 25%;
320
+ background: transparent;
321
+ padding: 2px !important;
322
+ margin: 0; }
323
+ .ditty-input--spacing__group .ditty-field__input {
324
+ position: relative;
325
+ border-radius: 3px;
326
+ overflow: hidden; }
327
+ .ditty-input--spacing__group .ditty-field__input:before {
328
+ position: absolute;
329
+ content: '';
330
+ background: #19BF7C; }
331
+ .ditty-input--spacing__group .ditty-field:nth-child(1) .ditty-field__input:before {
332
+ top: 0;
333
+ left: 0;
334
+ height: 5px;
335
+ width: 100%; }
336
+ .ditty-input--spacing__group .ditty-field:nth-child(2) .ditty-field__input:before {
337
+ bottom: 0;
338
+ left: 0;
339
+ height: 5px;
340
+ width: 100%; }
341
+ .ditty-input--spacing__group .ditty-field:nth-child(3) .ditty-field__input:before {
342
+ top: 0;
343
+ left: 0;
344
+ width: 5px;
345
+ height: 100%; }
346
+ .ditty-input--spacing__group .ditty-field:nth-child(4) .ditty-field__input:before {
347
+ top: 0;
348
+ right: 0;
349
+ width: 5px;
350
+ height: 100%; }
351
+
352
+ /* Radius */
353
+ .ditty-input--radius__group {
354
+ display: flex;
355
+ flex-direction: row;
356
+ align-items: center;
357
+ justify-content: flex-start;
358
+ flex-wrap: wrap;
359
+ margin: 0 -2px; }
360
+ .ditty-input--radius__group .ditty-field {
361
+ width: 25%;
362
+ background: transparent;
363
+ padding: 2px !important;
364
+ margin: 0; }
365
+ .ditty-input--radius__group .ditty-field__input {
366
+ position: relative;
367
+ border-radius: 3px;
368
+ overflow: hidden; }
369
+ .ditty-input--radius__group .ditty-field__input:before {
370
+ position: absolute;
371
+ content: '';
372
+ width: 0;
373
+ height: 0;
374
+ border: 8px solid transparent; }
375
+ .ditty-input--radius__group .ditty-field:nth-child(1) .ditty-field__input:before {
376
+ top: 0;
377
+ left: 0;
378
+ border-top-color: #19BF7C;
379
+ border-left-color: #19BF7C; }
380
+ .ditty-input--radius__group .ditty-field:nth-child(2) .ditty-field__input:before {
381
+ top: 0;
382
+ right: 0;
383
+ border-top-color: #19BF7C;
384
+ border-right-color: #19BF7C; }
385
+ .ditty-input--radius__group .ditty-field:nth-child(3) .ditty-field__input:before {
386
+ bottom: 0;
387
+ left: 0;
388
+ border-bottom-color: #19BF7C;
389
+ border-left-color: #19BF7C; }
390
+ .ditty-input--radius__group .ditty-field:nth-child(4) .ditty-field__input:before {
391
+ bottom: 0;
392
+ right: 0;
393
+ border-bottom-color: #19BF7C;
394
+ border-right-color: #19BF7C; }
395
+
396
+ /* Divider */
397
+ .ditty-field-type--divider {
398
+ display: flex;
399
+ flex-direction: row;
400
+ align-items: center;
401
+ justify-content: flex-start;
402
+ color: #FFF;
403
+ background: #32373C; }
404
+ .ditty-field-type--divider .ditty-field__label {
405
+ flex: 0 0 auto;
406
+ margin-bottom: 0;
407
+ margin-right: 10px;
408
+ white-space: nowrap; }
409
+ .ditty-field-type--divider .ditty-field__input {
410
+ flex: 1; }
411
+
412
+ .ditty-input--divider__wrapper {
413
+ display: flex;
414
+ flex-direction: row;
415
+ align-items: center;
416
+ justify-content: flex-start;
417
+ flex-wrap: wrap; }
418
+
419
+ .ditty-input--divider__heading {
420
+ flex: 0 0 auto;
421
+ white-space: nowrap;
422
+ margin-right: 10px; }
423
+
424
+ .ditty-input--divider__line {
425
+ flex: 1;
426
+ background: rgba(0, 0, 0, 0.05); }
427
+
428
+ .ditty-input--divider__description {
429
+ width: 100%; }
430
+
431
+ /* Date */
432
+ .ditty-field-type--date .ditty-field__input {
433
+ position: relative; }
434
+ .ditty-field-type--date .ditty-field__input:after {
435
+ position: absolute;
436
+ top: 50%;
437
+ left: 10px;
438
+ transform: translateY(-50%);
439
+ margin-top: -1px;
440
+ font-family: 'Font Awesome 5 Pro';
441
+ content: '\f073';
442
+ font-size: 18px;
443
+ opacity: .3;
444
+ transition: opacity .25s ease; }
445
+ .ditty-field-type--date .ditty-field__input:focus-within:after {
446
+ opacity: 1; }
447
+ .ditty-field-type--date .ditty-field__input input[type="text"] {
448
+ padding-left: 32px !important; }
449
+
450
+ /* WYSIWYG */
451
+ .ditty-input--wysiwyg .wp-editor-tabs * {
452
+ box-sizing: content-box; }
453
+
454
+ /* Image */
455
+ .ditty-input--image__preview {
456
+ position: relative;
457
+ width: 100%;
458
+ height: 80px;
459
+ background: #FFF;
460
+ border: 1px solid #dfdfdf;
461
+ border-radius: 3px; }
462
+ .ditty-input--image__preview a {
463
+ position: absolute;
464
+ top: 0;
465
+ left: 0;
466
+ z-index: 9;
467
+ display: flex;
468
+ flex-direction: row;
469
+ align-items: center;
470
+ justify-content: center;
471
+ width: 100%;
472
+ height: 100%;
473
+ text-align: center;
474
+ text-decoration: none;
475
+ cursor: pointer; }
476
+ .ditty-input--image__preview a i {
477
+ color: #58ca68; }
478
+ .ditty-input--image__preview img {
479
+ display: block;
480
+ line-height: 0;
481
+ position: absolute;
482
+ top: 0;
483
+ left: 0;
484
+ width: 100%;
485
+ height: 100%;
486
+ -o-object-fit: cover;
487
+ object-fit: cover; }
488
+
489
+ .datepicker-container {
490
+ background-color: #fff;
491
+ direction: ltr;
492
+ font-size: 12px;
493
+ left: 0;
494
+ line-height: 30px;
495
+ position: fixed;
496
+ -webkit-tap-highlight-color: transparent;
497
+ top: 0;
498
+ touch-action: none;
499
+ -webkit-touch-callout: none;
500
+ -webkit-user-select: none;
501
+ -moz-user-select: none;
502
+ -ms-user-select: none;
503
+ user-select: none;
504
+ width: 210px;
505
+ z-index: -1; }
506
+ .datepicker-container::before, .datepicker-container::after {
507
+ border: 5px solid transparent;
508
+ content: " ";
509
+ display: block;
510
+ height: 0;
511
+ position: absolute;
512
+ width: 0; }
513
+
514
+ .datepicker-dropdown {
515
+ border: 1px solid #ccc;
516
+ box-shadow: 0 3px 6px #ccc;
517
+ box-sizing: content-box;
518
+ position: absolute;
519
+ z-index: 1; }
520
+
521
+ .datepicker-inline {
522
+ position: static; }
523
+
524
+ .datepicker-top-left, .datepicker-top-right {
525
+ border-top-color: #39f; }
526
+ .datepicker-top-left::before, .datepicker-top-left::after, .datepicker-top-right::before, .datepicker-top-right::after {
527
+ border-top: 0;
528
+ left: 10px;
529
+ top: -5px; }
530
+ .datepicker-top-left::before, .datepicker-top-right::before {
531
+ border-bottom-color: #39f; }
532
+ .datepicker-top-left::after, .datepicker-top-right::after {
533
+ border-bottom-color: #fff;
534
+ top: -4px; }
535
+
536
+ .datepicker-bottom-left, .datepicker-bottom-right {
537
+ border-bottom-color: #39f; }
538
+ .datepicker-bottom-left::before, .datepicker-bottom-left::after, .datepicker-bottom-right::before, .datepicker-bottom-right::after {
539
+ border-bottom: 0;
540
+ bottom: -5px;
541
+ left: 10px; }
542
+ .datepicker-bottom-left::before, .datepicker-bottom-right::before {
543
+ border-top-color: #39f; }
544
+ .datepicker-bottom-left::after, .datepicker-bottom-right::after {
545
+ border-top-color: #fff;
546
+ bottom: -4px; }
547
+
548
+ .datepicker-top-right::before, .datepicker-top-right::after, .datepicker-bottom-right::before, .datepicker-bottom-right::after {
549
+ left: auto;
550
+ right: 10px; }
551
+
552
+ .datepicker-panel > ul {
553
+ margin: 0;
554
+ padding: 0;
555
+ width: 102%; }
556
+ .datepicker-panel > ul::before, .datepicker-panel > ul::after {
557
+ content: " ";
558
+ display: table; }
559
+ .datepicker-panel > ul::after {
560
+ clear: both; }
561
+ .datepicker-panel > ul > li {
562
+ background-color: #fff;
563
+ cursor: pointer;
564
+ float: left;
565
+ height: 30px;
566
+ list-style: none;
567
+ margin: 0;
568
+ padding: 0;
569
+ text-align: center;
570
+ width: 30px; }
571
+ .datepicker-panel > ul > li:hover {
572
+ background-color: #e5f2ff; }
573
+ .datepicker-panel > ul > li.muted, .datepicker-panel > ul > li.muted:hover {
574
+ color: #999; }
575
+ .datepicker-panel > ul > li.highlighted {
576
+ background-color: #e5f2ff; }
577
+ .datepicker-panel > ul > li.highlighted:hover {
578
+ background-color: #cce5ff; }
579
+ .datepicker-panel > ul > li.picked, .datepicker-panel > ul > li.picked:hover {
580
+ color: #39f; }
581
+ .datepicker-panel > ul > li.disabled, .datepicker-panel > ul > li.disabled:hover {
582
+ background-color: #fff;
583
+ color: #ccc;
584
+ cursor: default; }
585
+ .datepicker-panel > ul > li.disabled.highlighted, .datepicker-panel > ul > li.disabled:hover.highlighted {
586
+ background-color: #e5f2ff; }
587
+ .datepicker-panel > ul > li[data-view="years prev"], .datepicker-panel > ul > li[data-view="year prev"], .datepicker-panel > ul > li[data-view="month prev"], .datepicker-panel > ul > li[data-view="years next"], .datepicker-panel > ul > li[data-view="year next"], .datepicker-panel > ul > li[data-view="month next"], .datepicker-panel > ul > li[data-view="next"] {
588
+ font-size: 18px; }
589
+ .datepicker-panel > ul > li[data-view="years current"], .datepicker-panel > ul > li[data-view="year current"], .datepicker-panel > ul > li[data-view="month current"] {
590
+ width: 150px; }
591
+ .datepicker-panel > ul[data-view="years"] > li, .datepicker-panel > ul[data-view="months"] > li {
592
+ height: 52.5px;
593
+ line-height: 52.5px;
594
+ width: 52.5px; }
595
+ .datepicker-panel > ul[data-view="week"] > li,
596
+ .datepicker-panel > ul[data-view="week"] > li:hover {
597
+ background-color: #fff;
598
+ cursor: default; }
599
+
600
+ .datepicker-hide {
601
+ display: none; }
602
+
603
+ #ditty-extensions {
604
+ box-sizing: border-box; }
605
+ #ditty-extensions * {
606
+ box-sizing: border-box; }
607
+ #ditty-extensions .ditty-extensions-grid {
608
+ display: flex;
609
+ flex-direction: row;
610
+ align-items: flex-start;
611
+ justify-content: flex-start;
612
+ flex-wrap: wrap;
613
+ margin: -5px; }
614
+ #ditty-extensions .ditty-extensions-group {
615
+ padding: 20px;
616
+ background: #FFF; }
617
+ #ditty-extensions .ditty-extensions-group > h3 {
618
+ margin-top: 0; }
619
+ #ditty-extensions .ditty-extensions-group--other {
620
+ padding: 20px;
621
+ margin-top: 40px;
622
+ background: rgba(255, 255, 255, 0.9);
623
+ border-radius: 5px; }
624
+ #ditty-extensions .ditty-extension {
625
+ width: 100%;
626
+ padding: 5px; }
627
+ #ditty-extensions .ditty-extension__note {
628
+ text-align: left;
629
+ padding: 10px;
630
+ border: 1px solid;
631
+ border-radius: 3px; }
632
+ #ditty-extensions .ditty-extension__note--warning {
633
+ background: #fff8e5;
634
+ border-color: #FEBB00; }
635
+ #ditty-extensions .ditty-extension__note--information {
636
+ background: #e5f5fa;
637
+ border-color: #159FD3; }
638
+ #ditty-extensions .ditty-extension__contents {
639
+ height: 100%;
640
+ background: #f2f2f2;
641
+ border-radius: 5px;
642
+ overflow: hidden;
643
+ box-shadow: 0 0 1px rgba(0, 0, 0, 0.2); }
644
+ #ditty-extensions .ditty-extension__header {
645
+ position: relative;
646
+ display: flex;
647
+ flex-direction: row;
648
+ align-items: center;
649
+ justify-content: flex-start;
650
+ background-color: #23282E;
651
+ background-size: cover;
652
+ background-position: center center;
653
+ padding: 20px; }
654
+ #ditty-extensions .ditty-extension__header__icon {
655
+ position: absolute;
656
+ top: 0;
657
+ left: 0;
658
+ width: 100%;
659
+ height: 100%;
660
+ display: flex;
661
+ flex-direction: row;
662
+ align-items: center;
663
+ justify-content: flex-end;
664
+ padding: 20px;
665
+ overflow: hidden; }
666
+ #ditty-extensions .ditty-extension__header__icon i {
667
+ font-size: 260px;
668
+ color: #FFF;
669
+ transform: scale(0.8) rotate(-25deg);
670
+ transition: transform .5s ease; }
671
+ #ditty-extensions .ditty-extension__header__overlay {
672
+ position: absolute;
673
+ top: 0;
674
+ left: 0;
675
+ width: 100%;
676
+ height: 100%;
677
+ background: #23282e;
678
+ -webkit-backdrop-filter: blur(5px);
679
+ backdrop-filter: blur(5px);
680
+ transition: background-color .5s ease;
681
+ border-top-left-radius: 5px;
682
+ border-top-right-radius: 5px;
683
+ overflow: hidden; }
684
+ #ditty-extensions .ditty-extension__icon {
685
+ position: relative;
686
+ flex: 0 0 auto;
687
+ display: flex;
688
+ flex-direction: column;
689
+ align-items: center;
690
+ justify-content: center;
691
+ width: 80px;
692
+ height: 80px;
693
+ font-size: 40px;
694
+ line-height: 40px;
695
+ color: #FFF;
696
+ margin-right: 10px;
697
+ background: #23282E;
698
+ border-radius: 50%;
699
+ border: 4px solid #FFF;
700
+ box-sizing: content-box;
701
+ opacity: 0;
702
+ transform: translateX(-50px);
703
+ transition: transform .5s ease, opacity .25s ease;
704
+ transition-delay: .25s;
705
+ transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); }
706
+ #ditty-extensions .ditty-extension__icon img {
707
+ width: 80px;
708
+ height: 80px;
709
+ border-radius: 50%;
710
+ -o-object-fit: cover;
711
+ object-fit: cover; }
712
+ #ditty-extensions .ditty-extension__icon__small {
713
+ position: absolute;
714
+ left: -4px;
715
+ top: -4px;
716
+ display: flex;
717
+ flex-direction: column;
718
+ align-items: center;
719
+ justify-content: center;
720
+ width: 80px;
721
+ height: 80px;
722
+ font-size: 40px;
723
+ line-height: 40px;
724
+ color: #FFF;
725
+ background: #23282E;
726
+ border-radius: 50%;
727
+ border: 4px solid #FFF;
728
+ box-sizing: content-box;
729
+ transition: transform .75s ease, border-width .75s ease;
730
+ transition-delay: .75s; }
731
+ #ditty-extensions .ditty-extension__title {
732
+ position: relative;
733
+ color: #FFF;
734
+ background: rgba(0, 0, 0, 0.8);
735
+ padding: 5px 10px;
736
+ border-radius: 5px;
737
+ margin: 0;
738
+ opacity: 0;
739
+ transition: opacity 1s ease;
740
+ transition-delay: .5s; }
741
+ #ditty-extensions .ditty-extension__preview {
742
+ padding: 20px; }
743
+ #ditty-extensions .ditty-extension__preview__link {
744
+ margin: 0; }
745
+ #ditty-extensions .ditty-extension__tabs {
746
+ display: flex;
747
+ flex-direction: row;
748
+ align-items: center;
749
+ justify-content: flex-start;
750
+ background: #32373C;
751
+ padding: 5px; }
752
+ #ditty-extensions .ditty-extension__tab {
753
+ position: relative;
754
+ display: flex;
755
+ flex-direction: column;
756
+ align-items: center;
757
+ justify-content: center;
758
+ font-weight: bold;
759
+ color: #FFF;
760
+ padding: 10px;
761
+ text-align: center;
762
+ text-decoration: none;
763
+ background-color: rgba(255, 255, 255, 0.1);
764
+ border: none;
765
+ border-radius: 3px;
766
+ transition: color .25s ease, background-color .25s ease;
767
+ margin-right: 3px; }
768
+ #ditty-extensions .ditty-extension__tab:last-child {
769
+ margin-right: 0; }
770
+ #ditty-extensions .ditty-extension__tab:hover {
771
+ background-color: rgba(255, 255, 255, 0.2); }
772
+ #ditty-extensions .ditty-extension__tab.active {
773
+ background-color: #19BF7C; }
774
+ #ditty-extensions .ditty-extension__panel {
775
+ position: relative; }
776
+ #ditty-extensions .ditty-extension__panel__sublabel {
777
+ line-height: 1.4;
778
+ text-transform: uppercase;
779
+ margin: 0; }
780
+ #ditty-extensions .ditty-extension__panel__label {
781
+ line-height: 1.4;
782
+ margin-top: 0;
783
+ margin-bottom: auto; }
784
+ #ditty-extensions .ditty-extension__form {
785
+ padding: 20px; }
786
+ #ditty-extensions .ditty-extension__form > *:first-child {
787
+ margin-top: 0; }
788
+ #ditty-extensions .ditty-extension__form > *:last-child {
789
+ margin-bottom: 0; }
790
+ #ditty-extensions .ditty-extension__form .ditty-field {
791
+ padding-left: 0;
792
+ padding-right: 0; }
793
+ #ditty-extensions .ditty-extension__form .ditty-field:first-child {
794
+ padding-top: 0; }
795
+ #ditty-extensions .ditty-extension__form .ditty-field:last-child {
796
+ padding-bottom: 0; }
797
+ #ditty-extensions .ditty-extension__license__fields {
798
+ display: flex;
799
+ flex-direction: row;
800
+ align-items: stretch;
801
+ justify-content: flex-start; }
802
+ #ditty-extensions .ditty-extension__license__input {
803
+ flex: 1;
804
+ min-width: 100px;
805
+ margin-right: 0;
806
+ border-right: none;
807
+ border-top-right-radius: 0 !important;
808
+ border-bottom-right-radius: 0 !important; }
809
+ #ditty-extensions .ditty-extension__license__submit {
810
+ width: 45px;
811
+ text-align: center;
812
+ color: #FFF;
813
+ background-color: #32373C;
814
+ margin: 0;
815
+ border-bottom-left-radius: 0;
816
+ border-top-left-radius: 0; }
817
+ #ditty-extensions .ditty-extension__license__submit:hover {
818
+ background-color: #19BF7C; }
819
+ #ditty-extensions .ditty-extension__license__refresh {
820
+ width: 45px;
821
+ text-align: center;
822
+ color: #FFF;
823
+ background-color: #68737d;
824
+ margin: 0;
825
+ border-radius: 0; }
826
+ #ditty-extensions .ditty-extension__license__refresh:hover {
827
+ background-color: #19BF7C; }
828
+ #ditty-extensions .ditty-extension__license__deactivate {
829
+ width: 45px;
830
+ text-align: center;
831
+ color: #FFF;
832
+ background-color: #32373C;
833
+ margin: 0;
834
+ border-bottom-left-radius: 0;
835
+ border-top-left-radius: 0; }
836
+ #ditty-extensions .ditty-extension__license__deactivate:hover {
837
+ background-color: #19BF7C; }
838
+ #ditty-extensions .ditty-extension__buttons .ditty-button {
839
+ color: #FFF;
840
+ margin: 10px 0 0; }
841
+ #ditty-extensions .ditty-extension__buttons .ditty-button:hover {
842
+ color: #FFF; }
843
+ #ditty-extensions .ditty-extension__buttons .ditty-button:first-child {
844
+ margin-top: 0; }
845
+ #ditty-extensions .ditty-extension__buttons .ditty-button:last-child {
846
+ margin-bottom: 0; }
847
+ #ditty-extensions .ditty-extension__buttons:empty {
848
+ display: none; }
849
+ #ditty-extensions .ditty-extension__license-notification, #ditty-extensions .ditty-extension__custom-keys-notification {
850
+ position: absolute;
851
+ top: 0;
852
+ left: 0;
853
+ width: 100%;
854
+ height: 100%;
855
+ display: flex;
856
+ flex-direction: row;
857
+ align-items: center;
858
+ justify-content: center;
859
+ text-align: center;
860
+ background: rgba(255, 255, 255, 0.8);
861
+ -webkit-backdrop-filter: blur(5px);
862
+ backdrop-filter: blur(5px);
863
+ padding: 20px; }
864
+ #ditty-extensions .ditty-extension__renewal-link {
865
+ display: block;
866
+ margin-top: 5px; }
867
+ #ditty-extensions .ditty-extension__renewal-link a {
868
+ font-weight: bold;
869
+ color: inherit; }
870
+ #ditty-extensions .ditty-extension[data-license_status="valid"] .ditty-extension__license-notification {
871
+ display: none; }
872
+ #ditty-extensions .ditty-extension[data-license_status="valid"] .ditty-extension__license__submit {
873
+ display: none; }
874
+ #ditty-extensions .ditty-extension:not([data-license_status="valid"]) .ditty-extension__license__refresh,
875
+ #ditty-extensions .ditty-extension:not([data-license_status="valid"]) .ditty-extension__license__deactivate {
876
+ display: none; }
877
+ #ditty-extensions .ditty-extension:not([data-license_status="valid"])[data-api_keys="error"] .ditty-extension__custom-keys-notification {
878
+ display: none; }
879
+ #ditty-extensions .ditty-extension:not([data-api_keys="error"]) .ditty-extension__custom-keys-notification {
880
+ display: none; }
881
+ #ditty-extensions .ditty-extension[data-license_status="invalid"] .ditty-extension__header__overlay, #ditty-extensions .ditty-extension[data-license_status="deactivated"] .ditty-extension__header__overlay {
882
+ background-color: rgba(225, 54, 46, 0.5); }
883
+ #ditty-extensions .ditty-extension[data-license_status="invalid"] .ditty-extension__tab[data-slide_id="license"], #ditty-extensions .ditty-extension[data-license_status="deactivated"] .ditty-extension__tab[data-slide_id="license"] {
884
+ background-color: #E1362E; }
885
+ #ditty-extensions .ditty-extension[data-license_status="invalid"] .ditty-extension__license__message, #ditty-extensions .ditty-extension[data-license_status="deactivated"] .ditty-extension__license__message {
886
+ color: #E1362E; }
887
+ #ditty-extensions .ditty-extension[data-api="unauthorized"] .ditty-extension__tab[data-slide_id="api_connect"] {
888
+ background-color: #FEBB00; }
889
+ #ditty-extensions .ditty-extension--init .ditty-extension__header__overlay {
890
+ background: rgba(35, 40, 46, 0.5); }
891
+ #ditty-extensions .ditty-extension--init .ditty-extension__header__icon i {
892
+ transform: scale(1) rotate(0); }
893
+ #ditty-extensions .ditty-extension--init .ditty-extension__icon {
894
+ opacity: 1;
895
+ transform: translateX(0); }
896
+ #ditty-extensions .ditty-extension--init .ditty-extension__icon__small {
897
+ border-width: 10px;
898
+ transform: scale(0.3) translate(-120px, -120px); }
899
+ #ditty-extensions .ditty-extension--init .ditty-extension__title {
900
+ opacity: 1; }
901
+
902
+ @media (min-width: 600px) {
903
+ #ditty-extensions .ditty-extension {
904
+ width: 50%; } }
905
+
906
+ @media (min-width: 1200px) {
907
+ #ditty-extensions .ditty-extension {
908
+ width: 33.333%; } }
909
+
910
+ #ditty-extensions-app {
911
+ box-sizing: border-box; }
912
+ #ditty-extensions-app * {
913
+ box-sizing: border-box; }
914
+ #ditty-extensions-app .ditty-extensions-grid {
915
+ display: flex;
916
+ flex-direction: row;
917
+ align-items: stretch;
918
+ justify-content: flex-start;
919
+ flex-wrap: wrap;
920
+ margin: -5px; }
921
+ #ditty-extensions-app .ditty-extensions-group {
922
+ margin: 10px 0; }
923
+ #ditty-extensions-app .ditty-extensions-group > h3 {
924
+ margin-top: 0; }
925
+ #ditty-extensions-app .ditty-extensions-group--other {
926
+ padding: 20px;
927
+ margin-top: 40px;
928
+ background: rgba(255, 255, 255, 0.9);
929
+ border-radius: 5px; }
930
+ #ditty-extensions-app .ditty-extension {
931
+ width: 100%;
932
+ padding: 5px; }
933
+ #ditty-extensions-app .ditty-extension__note {
934
+ padding: 10px;
935
+ border: 1px solid;
936
+ border-radius: 3px; }
937
+ #ditty-extensions-app .ditty-extension__note--warning {
938
+ background: #fff8e5;
939
+ border-color: #FEBB00; }
940
+ #ditty-extensions-app .ditty-extension__note--information {
941
+ background: #e5f5fa;
942
+ border-color: #159FD3; }
943
+ #ditty-extensions-app .ditty-extension__contents {
944
+ height: 100%;
945
+ background: #FFF;
946
+ border-radius: 5px;
947
+ overflow: hidden;
948
+ box-shadow: 0 0 1px rgba(0, 0, 0, 0.2); }
949
+ #ditty-extensions-app .ditty-extension__header {
950
+ position: relative;
951
+ display: flex;
952
+ flex-direction: row;
953
+ align-items: center;
954
+ justify-content: flex-start;
955
+ background-color: #23282E;
956
+ background-size: cover;
957
+ background-position: center center;
958
+ padding: 20px; }
959
+ #ditty-extensions-app .ditty-extension__header__icon {
960
+ position: absolute;
961
+ top: 0;
962
+ left: 0;
963
+ width: 100%;
964
+ height: 100%;
965
+ display: flex;
966
+ flex-direction: row;
967
+ align-items: center;
968
+ justify-content: flex-end;
969
+ padding: 20px;
970
+ overflow: hidden; }
971
+ #ditty-extensions-app .ditty-extension__header__icon i {
972
+ font-size: 260px;
973
+ color: #FFF;
974
+ transform: scale(0.8) rotate(-25deg);
975
+ transition: transform .5s ease; }
976
+ #ditty-extensions-app .ditty-extension__header__overlay {
977
+ position: absolute;
978
+ top: 0;
979
+ left: 0;
980
+ width: 100%;
981
+ height: 100%;
982
+ background: #23282e;
983
+ -webkit-backdrop-filter: blur(5px);
984
+ backdrop-filter: blur(5px);
985
+ transition: background-color .5s ease; }
986
+ #ditty-extensions-app .ditty-extension__icon {
987
+ position: relative;
988
+ flex: 0 0 auto;
989
+ display: flex;
990
+ flex-direction: column;
991
+ align-items: center;
992
+ justify-content: center;
993
+ width: 80px;
994
+ height: 80px;
995
+ font-size: 40px;
996
+ line-height: 40px;
997
+ color: #FFF;
998
+ margin-right: 10px;
999
+ background: #23282E;
1000
+ border-radius: 50%;
1001
+ border: 4px solid #FFF;
1002
+ box-sizing: content-box;
1003
+ opacity: 0;
1004
+ transform: translateX(-50px);
1005
+ transition: transform .5s ease, opacity .25s ease;
1006
+ transition-delay: .25s;
1007
+ transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); }
1008
+ #ditty-extensions-app .ditty-extension__icon img {
1009
+ width: 80px;
1010
+ height: auto;
1011
+ border-radius: 50%; }
1012
+ #ditty-extensions-app .ditty-extension__icon__small {
1013
+ position: absolute;
1014
+ left: -4px;
1015
+ top: -4px;
1016
+ display: flex;
1017
+ flex-direction: column;
1018
+ align-items: center;
1019
+ justify-content: center;
1020
+ width: 80px;
1021
+ height: 80px;
1022
+ font-size: 40px;
1023
+ line-height: 40px;
1024
+ color: #FFF;
1025
+ background: #23282E;
1026
+ border-radius: 50%;
1027
+ border: 4px solid #FFF;
1028
+ box-sizing: content-box;
1029
+ transition: transform .75s ease, border-width .75s ease;
1030
+ transition-delay: .75s; }
1031
+ #ditty-extensions-app .ditty-extension__title {
1032
+ position: relative;
1033
+ color: #FFF;
1034
+ background: rgba(0, 0, 0, 0.8);
1035
+ padding: 5px 10px;
1036
+ border-radius: 5px;
1037
+ margin: 0;
1038
+ opacity: 0;
1039
+ transition: opacity 1s ease;
1040
+ transition-delay: .5s; }
1041
+ #ditty-extensions-app .ditty-extension__preview {
1042
+ padding: 20px; }
1043
+ #ditty-extensions-app .ditty-extension__preview__link {
1044
+ margin: 0; }
1045
+ #ditty-extensions-app .ditty-extension__tabs {
1046
+ display: flex;
1047
+ flex-direction: row;
1048
+ align-items: center;
1049
+ justify-content: flex-start;
1050
+ background: #32373C;
1051
+ padding: 5px; }
1052
+ #ditty-extensions-app .ditty-extension__tab {
1053
+ position: relative;
1054
+ display: flex;
1055
+ flex-direction: column;
1056
+ align-items: center;
1057
+ justify-content: center;
1058
+ font-weight: bold;
1059
+ color: #FFF;
1060
+ padding: 10px;
1061
+ text-align: center;
1062
+ text-decoration: none;
1063
+ background-color: rgba(255, 255, 255, 0.1);
1064
+ border: none;
1065
+ border-radius: 3px;
1066
+ transition: color .25s ease, background-color .25s ease;
1067
+ margin-right: 3px; }
1068
+ #ditty-extensions-app .ditty-extension__tab:last-child {
1069
+ margin-right: 0; }
1070
+ #ditty-extensions-app .ditty-extension__tab:hover {
1071
+ background-color: rgba(255, 255, 255, 0.2); }
1072
+ #ditty-extensions-app .ditty-extension__tab.active {
1073
+ background-color: #19BF7C; }
1074
+ #ditty-extensions-app .ditty-extension__panels {
1075
+ position: relative; }
1076
+ #ditty-extensions-app .ditty-extension__panel {
1077
+ position: absolute;
1078
+ top: 0;
1079
+ left: 0;
1080
+ width: 100%;
1081
+ background: #FFF; }
1082
+ #ditty-extensions-app .ditty-extension__panel__sublabel {
1083
+ line-height: 1.4;
1084
+ text-transform: uppercase;
1085
+ margin: 0; }
1086
+ #ditty-extensions-app .ditty-extension__panel__label {
1087
+ line-height: 1.4;
1088
+ margin-top: 0;
1089
+ margin-bottom: auto; }
1090
+ #ditty-extensions-app .ditty-extension__form {
1091
+ padding: 20px; }
1092
+ #ditty-extensions-app .ditty-extension__form > *:first-child {
1093
+ margin-top: 0; }
1094
+ #ditty-extensions-app .ditty-extension__form > *:last-child {
1095
+ margin-bottom: 0; }
1096
+ #ditty-extensions-app .ditty-extension__license__fields {
1097
+ display: flex;
1098
+ flex-direction: row;
1099
+ align-items: stretch;
1100
+ justify-content: flex-start; }
1101
+ #ditty-extensions-app .ditty-extension__license__input {
1102
+ flex: 1;
1103
+ min-width: 100px;
1104
+ margin-right: 0;
1105
+ border-right: none;
1106
+ border-top-right-radius: 0 !important;
1107
+ border-bottom-right-radius: 0 !important; }
1108
+ #ditty-extensions-app .ditty-extension__license__submit {
1109
+ width: 45px;
1110
+ text-align: center;
1111
+ color: #FFF;
1112
+ background-color: #32373C;
1113
+ margin: 0;
1114
+ border-bottom-left-radius: 0;
1115
+ border-top-left-radius: 0; }
1116
+ #ditty-extensions-app .ditty-extension__license__submit:hover {
1117
+ background-color: #19BF7C; }
1118
+ #ditty-extensions-app .ditty-extension__license__refresh {
1119
+ width: 45px;
1120
+ text-align: center;
1121
+ color: #FFF;
1122
+ background-color: #68737d;
1123
+ margin: 0;
1124
+ border-radius: 0; }
1125
+ #ditty-extensions-app .ditty-extension__license__refresh:hover {
1126
+ background-color: #19BF7C; }
1127
+ #ditty-extensions-app .ditty-extension__license__deactivate {
1128
+ width: 45px;
1129
+ text-align: center;
1130
+ color: #FFF;
1131
+ background-color: #32373C;
1132
+ margin: 0;
1133
+ border-bottom-left-radius: 0;
1134
+ border-top-left-radius: 0; }
1135
+ #ditty-extensions-app .ditty-extension__license__deactivate:hover {
1136
+ background-color: #19BF7C; }
1137
+ #ditty-extensions-app .ditty-extension__buttons .ditty-button {
1138
+ color: #FFF;
1139
+ margin: 10px 0 0; }
1140
+ #ditty-extensions-app .ditty-extension__buttons .ditty-button:hover {
1141
+ color: #FFF; }
1142
+ #ditty-extensions-app .ditty-extension__buttons .ditty-button:first-child {
1143
+ margin-top: 0; }
1144
+ #ditty-extensions-app .ditty-extension__buttons .ditty-button:last-child {
1145
+ margin-bottom: 0; }
1146
+ #ditty-extensions-app .ditty-extension__buttons:empty {
1147
+ display: none; }
1148
+ #ditty-extensions-app .ditty-extension__license-notification, #ditty-extensions-app .ditty-extension__custom-keys-notification {
1149
+ position: absolute;
1150
+ top: 0;
1151
+ left: 0;
1152
+ width: 100%;
1153
+ height: 100%;
1154
+ display: flex;
1155
+ flex-direction: row;
1156
+ align-items: center;
1157
+ justify-content: center;
1158
+ text-align: center;
1159
+ background: rgba(255, 255, 255, 0.8);
1160
+ -webkit-backdrop-filter: blur(5px);
1161
+ backdrop-filter: blur(5px);
1162
+ padding: 20px; }
1163
+ #ditty-extensions-app .ditty-extension__renewal-link {
1164
+ display: block;
1165
+ margin-top: 5px; }
1166
+ #ditty-extensions-app .ditty-extension__renewal-link a {
1167
+ font-weight: bold;
1168
+ color: inherit; }
1169
+ #ditty-extensions-app .ditty-extension--valid .ditty-extension__license-notification {
1170
+ display: none; }
1171
+ #ditty-extensions-app .ditty-extension:not([data-license_status="valid"])[data-api_keys="error"] .ditty-extension__custom-keys-notification {
1172
+ display: none; }
1173
+ #ditty-extensions-app .ditty-extension:not([data-api_keys="error"]) .ditty-extension__custom-keys-notification {
1174
+ display: none; }
1175
+ #ditty-extensions-app .ditty-extension--failed .ditty-extension__header__overlay, #ditty-extensions-app .ditty-extension--invalid .ditty-extension__header__overlay, #ditty-extensions-app .ditty-extension--deactivated .ditty-extension__header__overlay {
1176
+ background-color: rgba(225, 54, 46, 0.5) !important; }
1177
+ #ditty-extensions-app .ditty-extension--failed .ditty-extension__tab--license, #ditty-extensions-app .ditty-extension--invalid .ditty-extension__tab--license, #ditty-extensions-app .ditty-extension--deactivated .ditty-extension__tab--license {
1178
+ background-color: #E1362E !important; }
1179
+ #ditty-extensions-app .ditty-extension--failed .ditty-extension__license__message, #ditty-extensions-app .ditty-extension--invalid .ditty-extension__license__message, #ditty-extensions-app .ditty-extension--deactivated .ditty-extension__license__message {
1180
+ color: #E1362E; }
1181
+ #ditty-extensions-app .ditty-extension--unauthorized .ditty-extension__tab--api_connect {
1182
+ background-color: #FEBB00; }
1183
+ #ditty-extensions-app .ditty-extension--init .ditty-extension__header__overlay {
1184
+ background: rgba(35, 40, 46, 0.5); }
1185
+ #ditty-extensions-app .ditty-extension--init .ditty-extension__header__icon i {
1186
+ transform: scale(1) rotate(0); }
1187
+ #ditty-extensions-app .ditty-extension--init .ditty-extension__icon {
1188
+ opacity: 1;
1189
+ transform: translateX(0); }
1190
+ #ditty-extensions-app .ditty-extension--init .ditty-extension__icon__small {
1191
+ border-width: 10px;
1192
+ transform: scale(0.3) translate(-120px, -120px); }
1193
+ #ditty-extensions-app .ditty-extension--init .ditty-extension__title {
1194
+ opacity: 1; }
1195
+
1196
+ @media (min-width: 600px) {
1197
+ #ditty-extensions-app .ditty-extension {
1198
+ width: 50%; } }
1199
+
1200
+ @media (min-width: 1200px) {
1201
+ #ditty-extensions-app .ditty-extension {
1202
+ width: 33.333%; } }
1203
+
1204
+ @media (min-width: 1600px) {
1205
+ #ditty-extensions-app .ditty-extension {
1206
+ width: 25%; } }
1207
+
1208
+ @media (min-width: 2000px) {
1209
+ #ditty-extensions-app .ditty-extension {
1210
+ width: 20%; } }
1211
+
1212
+ #ditty-extensions .ditty-extension--instagram .ditty-extension__header,
1213
+ #ditty-extensions .ditty-extension--instagram .ditty-extension__icon,
1214
+ #ditty-extensions .ditty-extension--instagram .ditty-extension__icon__small,
1215
+ #ditty-extensions-app .ditty-extension--instagram .ditty-extension__header,
1216
+ #ditty-extensions-app .ditty-extension--instagram .ditty-extension__icon,
1217
+ #ditty-extensions-app .ditty-extension--instagram .ditty-extension__icon__small {
1218
+ background: linear-gradient(45deg, #405de6, #5851db, #833ab4, #c13584, #e1306c, #fd1d1d); }
1219
+
1220
+ #ditty-extensions .ditty-extension--instagram .ditty-button:hover,
1221
+ #ditty-extensions .ditty-extension--instagram .ditty-button--primary,
1222
+ #ditty-extensions .ditty-extension--instagram .ditty-extension__tab.active,
1223
+ #ditty-extensions-app .ditty-extension--instagram .ditty-button:hover,
1224
+ #ditty-extensions-app .ditty-extension--instagram .ditty-button--primary,
1225
+ #ditty-extensions-app .ditty-extension--instagram .ditty-extension__tab.active {
1226
+ background-color: #e1306c; }
1227
+
1228
+ #ditty-extensions .ditty-extension--images .ditty-extension__header,
1229
+ #ditty-extensions .ditty-extension--images .ditty-extension__header,
1230
+ #ditty-extensions .ditty-extension--images .ditty-extension__icon,
1231
+ #ditty-extensions .ditty-extension--images .ditty-extension__icon__small,
1232
+ #ditty-extensions .ditty-extension--images .ditty-button:hover,
1233
+ #ditty-extensions .ditty-extension--images .ditty-button--primary,
1234
+ #ditty-extensions .ditty-extension--images .ditty-extension__tab.active,
1235
+ #ditty-extensions-app .ditty-extension--images .ditty-extension__header,
1236
+ #ditty-extensions-app .ditty-extension--images .ditty-extension__header,
1237
+ #ditty-extensions-app .ditty-extension--images .ditty-extension__icon,
1238
+ #ditty-extensions-app .ditty-extension--images .ditty-extension__icon__small,
1239
+ #ditty-extensions-app .ditty-extension--images .ditty-button:hover,
1240
+ #ditty-extensions-app .ditty-extension--images .ditty-button--primary,
1241
+ #ditty-extensions-app .ditty-extension--images .ditty-extension__tab.active {
1242
+ background-color: #39B449; }
1243
+
1244
+ #ditty-extensions .ditty-extension--facebook .ditty-extension__header,
1245
+ #ditty-extensions .ditty-extension--facebook .ditty-extension__icon,
1246
+ #ditty-extensions .ditty-extension--facebook .ditty-extension__icon__small,
1247
+ #ditty-extensions .ditty-extension--facebook .ditty-button:hover,
1248
+ #ditty-extensions .ditty-extension--facebook .ditty-button--primary,
1249
+ #ditty-extensions .ditty-extension--facebook .ditty-extension__tab.active,
1250
+ #ditty-extensions-app .ditty-extension--facebook .ditty-extension__header,
1251
+ #ditty-extensions-app .ditty-extension--facebook .ditty-extension__icon,
1252
+ #ditty-extensions-app .ditty-extension--facebook .ditty-extension__icon__small,
1253
+ #ditty-extensions-app .ditty-extension--facebook .ditty-button:hover,
1254
+ #ditty-extensions-app .ditty-extension--facebook .ditty-button--primary,
1255
+ #ditty-extensions-app .ditty-extension--facebook .ditty-extension__tab.active {
1256
+ background-color: #3b5998; }
1257
+
1258
+ #ditty-extensions .ditty-extension--rss .ditty-extension__header,
1259
+ #ditty-extensions .ditty-extension--rss .ditty-extension__icon,
1260
+ #ditty-extensions .ditty-extension--rss .ditty-extension__icon__small,
1261
+ #ditty-extensions .ditty-extension--rss .ditty-button:hover,
1262
+ #ditty-extensions .ditty-extension--rss .ditty-button--primary,
1263
+ #ditty-extensions .ditty-extension--rss .ditty-extension__tab.active,
1264
+ #ditty-extensions-app .ditty-extension--rss .ditty-extension__header,
1265
+ #ditty-extensions-app .ditty-extension--rss .ditty-extension__icon,
1266
+ #ditty-extensions-app .ditty-extension--rss .ditty-extension__icon__small,
1267
+ #ditty-extensions-app .ditty-extension--rss .ditty-button:hover,
1268
+ #ditty-extensions-app .ditty-extension--rss .ditty-button--primary,
1269
+ #ditty-extensions-app .ditty-extension--rss .ditty-extension__tab.active {
1270
+ background-color: #ee802f; }
1271
+
1272
+ #ditty-extensions .ditty-extension--timing .ditty-extension__header,
1273
+ #ditty-extensions .ditty-extension--timing .ditty-extension__icon,
1274
+ #ditty-extensions .ditty-extension--timing .ditty-extension__icon__small,
1275
+ #ditty-extensions .ditty-extension--timing .ditty-button:hover,
1276
+ #ditty-extensions .ditty-extension--timing .ditty-button--primary,
1277
+ #ditty-extensions .ditty-extension--timing .ditty-extension__tab.active,
1278
+ #ditty-extensions-app .ditty-extension--timing .ditty-extension__header,
1279
+ #ditty-extensions-app .ditty-extension--timing .ditty-extension__icon,
1280
+ #ditty-extensions-app .ditty-extension--timing .ditty-extension__icon__small,
1281
+ #ditty-extensions-app .ditty-extension--timing .ditty-button:hover,
1282
+ #ditty-extensions-app .ditty-extension--timing .ditty-button--primary,
1283
+ #ditty-extensions-app .ditty-extension--timing .ditty-extension__tab.active {
1284
+ background-color: #19BF7C; }
1285
+
1286
+ #ditty-extensions .ditty-extension--twitter .ditty-extension__header,
1287
+ #ditty-extensions .ditty-extension--twitter .ditty-extension__icon,
1288
+ #ditty-extensions .ditty-extension--twitter .ditty-extension__icon__small,
1289
+ #ditty-extensions .ditty-extension--twitter .ditty-button:hover,
1290
+ #ditty-extensions .ditty-extension--twitter .ditty-button--primary,
1291
+ #ditty-extensions .ditty-extension--twitter .ditty-extension__tab.active,
1292
+ #ditty-extensions-app .ditty-extension--twitter .ditty-extension__header,
1293
+ #ditty-extensions-app .ditty-extension--twitter .ditty-extension__icon,
1294
+ #ditty-extensions-app .ditty-extension--twitter .ditty-extension__icon__small,
1295
+ #ditty-extensions-app .ditty-extension--twitter .ditty-button:hover,
1296
+ #ditty-extensions-app .ditty-extension--twitter .ditty-button--primary,
1297
+ #ditty-extensions-app .ditty-extension--twitter .ditty-extension__tab.active {
1298
+ background-color: #1DA1F2; }
1299
+
1300
+ #ditty-extensions .ditty-extension--posts .ditty-extension__header,
1301
+ #ditty-extensions .ditty-extension--posts .ditty-extension__icon,
1302
+ #ditty-extensions .ditty-extension--posts .ditty-extension__icon__small,
1303
+ #ditty-extensions .ditty-extension--posts .ditty-button:hover,
1304
+ #ditty-extensions .ditty-extension--posts .ditty-button--primary,
1305
+ #ditty-extensions .ditty-extension--posts .ditty-extension__tab.active,
1306
+ #ditty-extensions-app .ditty-extension--posts .ditty-extension__header,
1307
+ #ditty-extensions-app .ditty-extension--posts .ditty-extension__icon,
1308
+ #ditty-extensions-app .ditty-extension--posts .ditty-extension__icon__small,
1309
+ #ditty-extensions-app .ditty-extension--posts .ditty-button:hover,
1310
+ #ditty-extensions-app .ditty-extension--posts .ditty-button--primary,
1311
+ #ditty-extensions-app .ditty-extension--posts .ditty-extension__tab.active {
1312
+ background-color: #21759b; }
1313
+
1314
+ #ditty-layout-html .inside,
1315
+ #ditty-layout-html .ditty-field,
1316
+ #ditty-layout-css .inside,
1317
+ #ditty-layout-css .ditty-field {
1318
+ padding: 0;
1319
+ margin: 0; }
1320
+ #ditty-layout-html .inside__input,
1321
+ #ditty-layout-html .ditty-field__input,
1322
+ #ditty-layout-css .inside__input,
1323
+ #ditty-layout-css .ditty-field__input {
1324
+ margin: 0; }
1325
+
1326
+ #ditty-layout-html .CodeMirror,
1327
+ #ditty-layout-css .CodeMirror {
1328
+ resize: vertical; }
1329
+
1330
+ #ditty-page {
1331
+ width: 1200px;
1332
+ max-width: calc( 100% - 22px);
1333
+ border-radius: 5px;
1334
+ box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
1335
+ margin-top: 22px;
1336
+ overflow: hidden; }
1337
+ #ditty-page__header {
1338
+ box-sizing: border-box;
1339
+ padding: 20px;
1340
+ background: #FFF;
1341
+ overflow: hidden;
1342
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05); }
1343
+ #ditty-page__version {
1344
+ margin-bottom: 20px; }
1345
+ #ditty-page__title {
1346
+ font-weight: bold; }
1347
+ #ditty-page__logo__image {
1348
+ display: block;
1349
+ line-height: 0;
1350
+ width: 200px;
1351
+ height: auto; }
1352
+ #ditty-page__content {
1353
+ box-sizing: border-box;
1354
+ width: 1200px;
1355
+ max-width: 100%;
1356
+ margin: 0 auto; }
1357
+ #ditty-page__content hr {
1358
+ margin: 40px 0; }
1359
+
1360
+ @media screen and (max-width: 782px) {
1361
+ #ditty-page {
1362
+ max-width: calc( 100% - 10px);
1363
+ margin-top: 10px; } }
1364
+
1365
+ #ditty-settings {
1366
+ display: flex;
1367
+ flex-direction: row;
1368
+ align-items: stretch;
1369
+ justify-content: flex-start; }
1370
+ #ditty-settings.updating .ditty-updating-overlay {
1371
+ display: block; }
1372
+
1373
+ .ditty-settings__header, .ditty-settings__footer {
1374
+ display: flex;
1375
+ flex-direction: row;
1376
+ align-items: center;
1377
+ justify-content: flex-end;
1378
+ padding: 20px; }
1379
+ .ditty-settings__header .ditty-button, .ditty-settings__footer .ditty-button {
1380
+ margin: 0; }
1381
+
1382
+ .ditty-settings__header {
1383
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05); }
1384
+
1385
+ .ditty-settings__footer {
1386
+ border-top: 1px solid rgba(0, 0, 0, 0.05); }
1387
+
1388
+ .ditty-settings__tabs {
1389
+ display: flex;
1390
+ flex-direction: column;
1391
+ align-items: stretch;
1392
+ justify-content: flex-start;
1393
+ width: 250px;
1394
+ background: #32373C;
1395
+ padding-top: 1em !important;
1396
+ padding-bottom: 1em !important; }
1397
+
1398
+ .ditty-settings__tab {
1399
+ box-sizing: border-box;
1400
+ position: relative;
1401
+ display: flex;
1402
+ flex-direction: row;
1403
+ align-items: center;
1404
+ justify-content: flex-start;
1405
+ min-height: 34px;
1406
+ font-size: 14px;
1407
+ font-weight: 400;
1408
+ color: #FFF;
1409
+ padding: 8px 4px 8px 25px;
1410
+ text-align: center;
1411
+ text-decoration: none;
1412
+ background-color: #32373C;
1413
+ border: none;
1414
+ transition: color .25s ease, background-color .25s ease; }
1415
+ .ditty-settings__tab i {
1416
+ position: absolute;
1417
+ top: 10px;
1418
+ display: block;
1419
+ font-size: 14px; }
1420
+ .ditty-settings__tab span {
1421
+ display: block;
1422
+ padding-left: 30px; }
1423
+ .ditty-settings__tab:focus {
1424
+ color: #FFF;
1425
+ outline: none;
1426
+ box-shadow: none; }
1427
+ .ditty-settings__tab:hover {
1428
+ color: #FFF;
1429
+ background-color: rgba(255, 255, 255, 0.2); }
1430
+ .ditty-settings__tab.active {
1431
+ background-color: #19BF7C; }
1432
+ .ditty-settings__tab.active:after {
1433
+ right: 0;
1434
+ border: 9px solid transparent;
1435
+ content: " ";
1436
+ height: 0;
1437
+ width: 0;
1438
+ position: absolute;
1439
+ pointer-events: none;
1440
+ border-right-color: #fff;
1441
+ top: 50%;
1442
+ margin-top: -8px; }
1443
+
1444
+ .ditty-settings__panel {
1445
+ display: none; }
1446
+ .ditty-settings__panel > .ditty-field {
1447
+ padding-left: 30px;
1448
+ padding-right: 30px; }
1449
+
1450
+ .ditty-settings__form {
1451
+ position: relative;
1452
+ flex: 1;
1453
+ background: #FFF; }
1454
+
1455
+ .ditty-settings__save.has-updates {
1456
+ background-color: orange; }
1457
+
1458
+ /* Default Layouts Variations */
1459
+ .ditty-field--layout_variation_defaults > .ditty-field__heading {
1460
+ display: none; }
1461
+
1462
+ .ditty-field--variation_defaults .ditty-input--group .ditty-field {
1463
+ display: flex;
1464
+ flex-direction: row;
1465
+ align-items: flex-start;
1466
+ justify-content: flex-start; }
1467
+ .ditty-field--variation_defaults .ditty-input--group .ditty-field .ditty-field__heading {
1468
+ flex: 0 0 200px;
1469
+ margin-right: 30px; }
1470
+ .ditty-field--variation_defaults .ditty-input--group .ditty-field .ditty-field__input__container {
1471
+ width: 100%; }
1472
+ .ditty-field--variation_defaults .ditty-input--group .ditty-field .ditty-field__input {
1473
+ margin: 0; }
1474
+
1475
+ /* Default Layouts & Displays */
1476
+ .ditty-field--layout_templates > .ditty-field__heading,
1477
+ .ditty-field--display_templates > .ditty-field__heading {
1478
+ display: none; }
1479
+
1480
+ .ditty-field--layout_templates .ditty-templates-list__type,
1481
+ .ditty-field--display_templates .ditty-templates-list__type {
1482
+ margin-bottom: 30px; }
1483
+ .ditty-field--layout_templates .ditty-templates-list__type h3,
1484
+ .ditty-field--display_templates .ditty-templates-list__type h3 {
1485
+ font-size: 1.2em;
1486
+ margin: 0 0 10px; }
1487
+
1488
+ .ditty-field--layout_templates .ditty-templates-list__template,
1489
+ .ditty-field--display_templates .ditty-templates-list__template {
1490
+ display: flex;
1491
+ flex-direction: row;
1492
+ align-items: center;
1493
+ justify-content: space-between;
1494
+ padding: 10px;
1495
+ background: #F2F2F2;
1496
+ border-radius: 3px; }
1497
+ .ditty-field--layout_templates .ditty-templates-list__template h4,
1498
+ .ditty-field--display_templates .ditty-templates-list__template h4 {
1499
+ font-size: 1.1em;
1500
+ margin: 0 0 3px; }
1501
+ .ditty-field--layout_templates .ditty-templates-list__template p,
1502
+ .ditty-field--display_templates .ditty-templates-list__template p {
1503
+ margin: 0; }
1504
+ .ditty-field--layout_templates .ditty-templates-list__template .ditty-button,
1505
+ .ditty-field--display_templates .ditty-templates-list__template .ditty-button {
1506
+ margin: 0; }
1507
+ .ditty-field--layout_templates .ditty-templates-list__template .ditty-button i,
1508
+ .ditty-field--display_templates .ditty-templates-list__template .ditty-button i {
1509
+ margin-left: 10px; }
1510
+
1511
+ /* Global Dittys */
1512
+ .ditty-settings__panel--global_ditty {
1513
+ padding: 10px 0; }
1514
+
1515
+ .ditty-field--global_ditty .ditty-input--clone {
1516
+ margin-bottom: 5px; }
1517
+
1518
+ .ditty-field--global_ditty .ditty-field-type--group-child {
1519
+ width: 100%; }
1520
+
1521
+ @media (max-width: 600px) {
1522
+ .ditty-settings__tabs {
1523
+ width: 44px; }
1524
+ .ditty-settings__tab {
1525
+ padding: 10px 4px 10px 14px;
1526
+ width: auto; }
1527
+ .ditty-settings__tab span {
1528
+ display: none; }
1529
+ .ditty-settings__panel > .ditty-field {
1530
+ padding-left: 20px;
1531
+ padding-right: 20px; } }
1532
+
1533
+ @media (min-width: 500px) {
1534
+ /* Global Dittys */
1535
+ .ditty-field--global_ditty .ditty-field--selector {
1536
+ width: 60%; }
1537
+ .ditty-field--global_ditty .ditty-field--position {
1538
+ width: 40%; }
1539
+ .ditty-field--global_ditty .ditty-field--ditty,
1540
+ .ditty-field--global_ditty .ditty-field--display {
1541
+ width: 50%; }
1542
+ .ditty-field--global_ditty .ditty-field--custom_id {
1543
+ width: 40%; }
1544
+ .ditty-field--global_ditty .ditty-field--custom_classes {
1545
+ width: 60%; } }
1546
+
1547
+ @media (min-width: 1000px) {
1548
+ .ditty-settings__panel:not(.ditty-settings__panel--global_ditty) > .ditty-field {
1549
+ display: flex;
1550
+ flex-direction: row;
1551
+ align-items: flex-start;
1552
+ justify-content: flex-start; }
1553
+ .ditty-settings__panel:not(.ditty-settings__panel--global_ditty) > .ditty-field > .ditty-field__heading {
1554
+ flex: 0 0 200px;
1555
+ margin-right: 30px; }
1556
+ .ditty-settings__panel:not(.ditty-settings__panel--global_ditty) > .ditty-field > .ditty-field__heading > .ditty-field__label,
1557
+ .ditty-settings__panel:not(.ditty-settings__panel--global_ditty) > .ditty-field > .ditty-field__heading > .ditty-field__description {
1558
+ margin-bottom: 0; }
1559
+ .ditty-settings__panel:not(.ditty-settings__panel--global_ditty) > .ditty-field > .ditty-field__input__container {
1560
+ width: 100%; }
1561
+ .ditty-settings__panel:not(.ditty-settings__panel--global_ditty) > .ditty-field > .ditty-field__input__container > .ditty-field__input {
1562
+ margin-top: 0; } }
1563
+
1564
+ .ditty-section {
1565
+ background: #FFF;
1566
+ padding: 40px; }
1567
+ .ditty-section--intro {
1568
+ color: #FFF;
1569
+ text-align: center;
1570
+ background: #1D2327; }
1571
+ .ditty-section--intro p {
1572
+ font-weight: 300; }
1573
+
1574
+ .ditty-row {
1575
+ display: flex;
1576
+ flex-direction: row;
1577
+ align-items: stretch;
1578
+ justify-content: flex-start;
1579
+ flex-wrap: wrap;
1580
+ box-sizing: border-box;
1581
+ margin-left: -20px;
1582
+ margin-right: -20px; }
1583
+
1584
+ .ditty-column {
1585
+ width: 100%;
1586
+ padding: 0 20px;
1587
+ box-sizing: border-box; }
1588
+
1589
+ .ditty-container {
1590
+ margin-bottom: 30px; }
1591
+ .ditty-container--details {
1592
+ display: flex;
1593
+ flex-direction: row;
1594
+ align-items: flex-start;
1595
+ justify-content: flex-start; }
1596
+ .ditty-container--details i {
1597
+ flex: 0 0 auto;
1598
+ width: 35px;
1599
+ font-size: 30px;
1600
+ line-height: 30px;
1601
+ margin-right: 10px; }
1602
+ .ditty-container--details__content {
1603
+ flex: 1; }
1604
+ .ditty-container--details h3 {
1605
+ margin-top: 0;
1606
+ margin-bottom: 5px; }
1607
+ .ditty-container--details p {
1608
+ margin-top: 5px; }
1609
+
1610
+ @media (min-width: 651px) {
1611
+ .ditty-column--1_2 {
1612
+ width: 50%; } }
1613
+
1614
+ .ditty-page__contents {
1615
+ padding: 20px; }
1616
+
1617
+ .ditty-page__header h2 {
1618
+ font-size: 23px;
1619
+ line-height: 30px;
1620
+ font-weight: 400;
1621
+ color: #FFF;
1622
+ margin: 0; }
includes/css/ditty.css ADDED
@@ -0,0 +1,1124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .ditty-metabox .rwmb-label,
2
+ .ditty-metabox .rwmb-input {
3
+ width: 100%; }
4
+
5
+ .ditty-metabox input[type=date],
6
+ .ditty-metabox input[type=datetime-local],
7
+ .ditty-metabox input[type=datetime],
8
+ .ditty-metabox input[type=email],
9
+ .ditty-metabox input[type=month],
10
+ .ditty-metabox input[type=number],
11
+ .ditty-metabox input[type=password],
12
+ .ditty-metabox input[type=search],
13
+ .ditty-metabox input[type=tel],
14
+ .ditty-metabox input[type=text],
15
+ .ditty-metabox input[type=time],
16
+ .ditty-metabox input[type=url],
17
+ .ditty-metabox input[type=week] {
18
+ font-size: 12px;
19
+ line-height: 16px;
20
+ padding: 5px;
21
+ border-radius: 0; }
22
+
23
+ .ditty-metabox #wp-content-editor-tools {
24
+ background: transparent; }
25
+
26
+ .ditty-metabox textarea {
27
+ font-size: 12px;
28
+ line-height: 16px;
29
+ padding: 5px;
30
+ border-radius: 0; }
31
+
32
+ .ditty-metabox .rwmb-field {
33
+ display: flex;
34
+ flex-direction: column;
35
+ align-items: flex-start;
36
+ justify-content: flex-start;
37
+ padding: 10px;
38
+ margin-bottom: 0; }
39
+ .ditty-metabox .rwmb-field:not(:last-child) {
40
+ border-bottom: 1px solid #EEE; }
41
+
42
+ .ditty-metabox .rwmb-select.rwmb-select {
43
+ font-size: 12px;
44
+ line-height: 16px;
45
+ padding: 5px;
46
+ border-radius: 0; }
47
+
48
+ .ditty-metabox .ui-slider-horizontal {
49
+ display: inline-block;
50
+ width: calc( 100% - 120px);
51
+ margin-right: 5px; }
52
+
53
+ .ditty-metabox .rwmb-group-wrapper {
54
+ margin: 0;
55
+ padding: 20px 0;
56
+ border-bottom: 2px dashed rgba(0, 0, 0, 0.05); }
57
+ .ditty-metabox .rwmb-group-wrapper:last-child {
58
+ border-bottom: none; }
59
+ .ditty-metabox .rwmb-group-wrapper > .rwmb-label {
60
+ width: 100%;
61
+ padding: 10px;
62
+ margin: 0; }
63
+ .ditty-metabox .rwmb-group-wrapper > .rwmb-label > label {
64
+ font-size: 14px;
65
+ line-height: 1.4;
66
+ margin: 0; }
67
+ .ditty-metabox .rwmb-group-wrapper > .rwmb-label ~ .rwmb-input {
68
+ width: 100%; }
69
+
70
+ .ditty-metabox .rwmb-ditty_padding-group,
71
+ .ditty-metabox .rwmb-ditty_border_radius-group,
72
+ .ditty-metabox .rwmb-ditty_display-group {
73
+ display: flex;
74
+ flex-direction: row;
75
+ align-items: center;
76
+ justify-content: flex-start;
77
+ flex-wrap: wrap;
78
+ margin: 0 -2px; }
79
+ .ditty-metabox .rwmb-ditty_padding-group .input-wrapper,
80
+ .ditty-metabox .rwmb-ditty_border_radius-group .input-wrapper,
81
+ .ditty-metabox .rwmb-ditty_display-group .input-wrapper {
82
+ width: 50%;
83
+ padding: 2px;
84
+ margin: 0; }
85
+ .ditty-metabox .rwmb-ditty_padding-group .input-border,
86
+ .ditty-metabox .rwmb-ditty_border_radius-group .input-border,
87
+ .ditty-metabox .rwmb-ditty_display-group .input-border {
88
+ position: relative;
89
+ border: 1px solid #EEE; }
90
+ .ditty-metabox .rwmb-ditty_padding-group .input-border:before,
91
+ .ditty-metabox .rwmb-ditty_border_radius-group .input-border:before,
92
+ .ditty-metabox .rwmb-ditty_display-group .input-border:before {
93
+ position: absolute;
94
+ content: ''; }
95
+ .ditty-metabox .rwmb-ditty_padding-group input,
96
+ .ditty-metabox .rwmb-ditty_border_radius-group input,
97
+ .ditty-metabox .rwmb-ditty_display-group input {
98
+ border-color: transparent; }
99
+ .ditty-metabox .rwmb-ditty_padding-group .rwmb-ditty_display-picker,
100
+ .ditty-metabox .rwmb-ditty_border_radius-group .rwmb-ditty_display-picker,
101
+ .ditty-metabox .rwmb-ditty_display-group .rwmb-ditty_display-picker {
102
+ margin-left: auto;
103
+ margin-right: auto; }
104
+
105
+ .ditty-metabox .rwmb-ditty_padding-group .input-border:before {
106
+ background: #0073aa; }
107
+
108
+ .ditty-metabox .rwmb-ditty_padding-group .input-wrapper {
109
+ width: 25%; }
110
+
111
+ .ditty-metabox .rwmb-ditty_padding-group .paddingTop .input-border:before {
112
+ top: 0;
113
+ left: 0;
114
+ height: 4px;
115
+ width: 100%; }
116
+
117
+ .ditty-metabox .rwmb-ditty_padding-group .paddingBottom .input-border:before {
118
+ bottom: 0;
119
+ left: 0;
120
+ height: 4px;
121
+ width: 100%; }
122
+
123
+ .ditty-metabox .rwmb-ditty_padding-group .paddingLeft .input-border:before {
124
+ top: 0;
125
+ left: 0;
126
+ height: 100%;
127
+ width: 4px; }
128
+
129
+ .ditty-metabox .rwmb-ditty_padding-group .paddingRight .input-border:before {
130
+ top: 0;
131
+ right: 0;
132
+ height: 100%;
133
+ width: 4px; }
134
+
135
+ .ditty-metabox .rwmb-ditty_border_radius-group .input-border:before {
136
+ width: 0;
137
+ height: 0;
138
+ border-style: solid; }
139
+
140
+ .ditty-metabox .rwmb-ditty_border_radius-group .borderTopLeftRadius .input-border:before {
141
+ top: 0;
142
+ left: 0;
143
+ border-width: 10px 10px 0 0;
144
+ border-color: #0073aa transparent transparent transparent; }
145
+
146
+ .ditty-metabox .rwmb-ditty_border_radius-group .borderTopRightRadius .input-border:before {
147
+ top: 0;
148
+ right: 0;
149
+ border-width: 0 10px 10px 0;
150
+ border-color: transparent #0073aa transparent transparent; }
151
+
152
+ .ditty-metabox .rwmb-ditty_border_radius-group .borderBottomLeftRadius .input-border:before {
153
+ bottom: 0;
154
+ left: 0;
155
+ border-width: 10px 0 0 10px;
156
+ border-color: transparent transparent transparent #0073aa; }
157
+
158
+ .ditty-metabox .rwmb-ditty_border_radius-group .borderBottomRightRadius .input-border:before {
159
+ bottom: 0;
160
+ right: 0;
161
+ border-width: 0 0 10px 10px;
162
+ border-color: transparent transparent #0073aa transparent; }
163
+
164
+ .ditty-metabox .rwmb-ditty_display-group {
165
+ width: 100%;
166
+ max-width: 300px; }
167
+ .ditty-metabox .rwmb-ditty_display-group .input-wrapper {
168
+ width: 33.333%; }
169
+ .ditty-metabox .rwmb-ditty_display-group .paddingTop .input-border:before,
170
+ .ditty-metabox .rwmb-ditty_display-group .paddingLeft .input-border:before,
171
+ .ditty-metabox .rwmb-ditty_display-group .paddingRight .input-border:before,
172
+ .ditty-metabox .rwmb-ditty_display-group .paddingBottom .input-border:before {
173
+ background: #0073aa; }
174
+ .ditty-metabox .rwmb-ditty_display-group .borderTopLeftRadius .input-border:before,
175
+ .ditty-metabox .rwmb-ditty_display-group .borderTopRightRadius .input-border:before,
176
+ .ditty-metabox .rwmb-ditty_display-group .borderBottomLeftRadius .input-border:before,
177
+ .ditty-metabox .rwmb-ditty_display-group .borderBottomRightRadius .input-border:before {
178
+ width: 0;
179
+ height: 0;
180
+ border-style: solid; }
181
+ .ditty-metabox .rwmb-ditty_display-group .borderTopLeftRadius .input-border:before {
182
+ top: 0;
183
+ left: 0;
184
+ border-width: 10px 10px 0 0;
185
+ border-color: #0073aa transparent transparent transparent; }
186
+ .ditty-metabox .rwmb-ditty_display-group .borderTopLeftRadius input {
187
+ padding-left: 9px; }
188
+ .ditty-metabox .rwmb-ditty_display-group .paddingTop .input-border:before {
189
+ top: 0;
190
+ left: 0;
191
+ height: 4px;
192
+ width: 100%; }
193
+ .ditty-metabox .rwmb-ditty_display-group .paddingTop input {
194
+ text-align: center; }
195
+ .ditty-metabox .rwmb-ditty_display-group .borderTopRightRadius .input-border:before {
196
+ top: 0;
197
+ right: 0;
198
+ border-width: 0 10px 10px 0;
199
+ border-color: transparent #0073aa transparent transparent; }
200
+ .ditty-metabox .rwmb-ditty_display-group .borderTopRightRadius input {
201
+ text-align: right;
202
+ padding-right: 9px; }
203
+ .ditty-metabox .rwmb-ditty_display-group .paddingLeft .input-border:before {
204
+ top: 0;
205
+ left: 0;
206
+ height: 100%;
207
+ width: 4px; }
208
+ .ditty-metabox .rwmb-ditty_display-group .paddingLeft input {
209
+ padding-left: 9px; }
210
+ .ditty-metabox .rwmb-ditty_display-group .backgroundColor .wp-picker-container {
211
+ width: 100%; }
212
+ .ditty-metabox .rwmb-ditty_display-group .backgroundColor .wp-picker-container .wp-color-result.button {
213
+ width: 100%;
214
+ font-size: 12px;
215
+ border-radius: 0;
216
+ border-color: transparent;
217
+ margin: 0; }
218
+ .ditty-metabox .rwmb-ditty_display-group .backgroundColor .wp-picker-container .wp-color-result.button .wp-color-result-text {
219
+ position: absolute;
220
+ top: 0;
221
+ left: 0;
222
+ border: none;
223
+ background: transparent; }
224
+ .ditty-metabox .rwmb-ditty_display-group .backgroundColor input {
225
+ text-align: center; }
226
+ .ditty-metabox .rwmb-ditty_display-group .paddingRight .input-border:before {
227
+ top: 0;
228
+ right: 0;
229
+ height: 100%;
230
+ width: 4px; }
231
+ .ditty-metabox .rwmb-ditty_display-group .paddingRight input {
232
+ text-align: right;
233
+ padding-right: 9px; }
234
+ .ditty-metabox .rwmb-ditty_display-group .borderBottomLeftRadius .input-border:before {
235
+ bottom: 0;
236
+ left: 0;
237
+ border-width: 10px 0 0 10px;
238
+ border-color: transparent transparent transparent #0073aa; }
239
+ .ditty-metabox .rwmb-ditty_display-group .borderBottomLeftRadius input {
240
+ padding-left: 9px; }
241
+ .ditty-metabox .rwmb-ditty_display-group .paddingBottom .input-border:before {
242
+ bottom: 0;
243
+ left: 0;
244
+ height: 4px;
245
+ width: 100%; }
246
+ .ditty-metabox .rwmb-ditty_display-group .paddingBottom input {
247
+ text-align: center; }
248
+ .ditty-metabox .rwmb-ditty_display-group .borderBottomRightRadius .input-border:before {
249
+ bottom: 0;
250
+ right: 0;
251
+ border-width: 0 0 10px 10px;
252
+ border-color: transparent transparent #0073aa transparent; }
253
+ .ditty-metabox .rwmb-ditty_display-group .borderBottomRightRadius input {
254
+ text-align: right;
255
+ padding-right: 9px; }
256
+
257
+ .ditty {
258
+ position: relative;
259
+ flex: 1;
260
+ max-width: 100%;
261
+ box-sizing: border-box; }
262
+
263
+ .ditty-item {
264
+ max-width: 100%; }
265
+ .ditty-item__elements {
266
+ max-width: 100%;
267
+ box-sizing: border-box; }
268
+ .ditty-item__elements * {
269
+ box-sizing: border-box; }
270
+ .ditty-item__wrapper {
271
+ position: relative;
272
+ overflow: hidden; }
273
+ .ditty-item__elements {
274
+ max-width: 100%; }
275
+
276
+ .ditty-update-wrapper {
277
+ position: relative;
278
+ overflow: hidden; }
279
+
280
+ .ditty-updating-overlay {
281
+ position: absolute;
282
+ top: 0;
283
+ left: 0;
284
+ right: 0;
285
+ bottom: 0;
286
+ opacity: 0.10;
287
+ background: #000;
288
+ z-index: 200;
289
+ display: none; }
290
+
291
+ .ditty-notification {
292
+ font-weight: 600;
293
+ padding: 10px 30px;
294
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
295
+ display: none; }
296
+ .ditty-notification--updated {
297
+ color: #3DB44C;
298
+ background: #ecf7ed; }
299
+ .ditty-notification--warning {
300
+ color: #FEBB00;
301
+ background: #fff8e5; }
302
+ .ditty-notification--error {
303
+ color: #E1362E;
304
+ background: #fbeaea; }
305
+
306
+ @media (max-width: 600px) {
307
+ .ditty-notification {
308
+ padding-left: 20px;
309
+ padding-right: 20px; } }
310
+
311
+ .ditty-slider {
312
+ display: flex;
313
+ flex-direction: column;
314
+ position: relative;
315
+ box-sizing: border-box; }
316
+ .ditty-slider * {
317
+ box-sizing: border-box; }
318
+ .ditty-slider__contents {
319
+ position: relative;
320
+ order: 1; }
321
+ .ditty-slider__contents:hover .ditty-slider__arrows {
322
+ opacity: 1; }
323
+ .ditty-slider__slides {
324
+ position: relative;
325
+ overflow: hidden; }
326
+ .ditty-slider__slide {
327
+ display: none;
328
+ position: absolute;
329
+ width: 100%;
330
+ line-height: 1; }
331
+ .ditty-slider__bullets {
332
+ order: 2;
333
+ width: 100%;
334
+ display: flex;
335
+ flex-direction: row;
336
+ align-items: center;
337
+ justify-content: center; }
338
+ .ditty-slider__bullet {
339
+ flex: 0 0 auto;
340
+ position: relative;
341
+ z-index: 9999;
342
+ display: block;
343
+ width: 10px;
344
+ height: 10px;
345
+ border-radius: 50%;
346
+ background: #CCC;
347
+ margin: 0 1px;
348
+ transition: background-color .25s ease; }
349
+ .ditty-slider__bullet--active {
350
+ background: #000; }
351
+ .ditty-slider__arrows {
352
+ order: 3;
353
+ position: absolute;
354
+ top: 0;
355
+ left: 0;
356
+ width: 100%;
357
+ height: 100%;
358
+ display: flex;
359
+ flex-direction: row;
360
+ align-items: center;
361
+ justify-content: space-between;
362
+ opacity: 0;
363
+ transition: opacity .25s ease; }
364
+ .ditty-slider__arrows--static {
365
+ opacity: 1; }
366
+ .ditty-slider__prev, .ditty-slider__next {
367
+ position: relative;
368
+ z-index: 9999;
369
+ display: flex;
370
+ flex-direction: row;
371
+ align-items: center;
372
+ justify-content: center;
373
+ line-height: 0;
374
+ width: 30px;
375
+ height: 30px;
376
+ color: #32373C;
377
+ background: rgba(255, 255, 255, 0.3);
378
+ border-radius: 50%;
379
+ text-decoration: none; }
380
+ .ditty-slider__prev i, .ditty-slider__next i {
381
+ display: block;
382
+ line-height: 0;
383
+ vertical-align: middle; }
384
+ .ditty-slider__prev:focus, .ditty-slider__next:focus {
385
+ outline: none;
386
+ box-shadow: none; }
387
+
388
+ .ditty-item {
389
+ box-sizing: border-box; }
390
+ .ditty-item * {
391
+ box-sizing: border-box; }
392
+ .ditty-item img {
393
+ max-width: 100%;
394
+ height: auto; }
395
+ .ditty-item__elements {
396
+ overflow: hidden; }
397
+ .ditty-item__clear {
398
+ clear: both; }
399
+
400
+ #ditty-display-settings.postbox .inside {
401
+ padding: 0;
402
+ margin: 0; }
403
+ #ditty-display-settings.postbox .inside .ditty-display-admin-settings {
404
+ box-sizing: border-box; }
405
+ #ditty-display-settings.postbox .inside .ditty-display-admin-settings * {
406
+ box-sizing: border-box; }
407
+ #ditty-display-settings.postbox .inside .ditty-display-admin-settings > .ditty-field-type--group > .ditty-field__input__container {
408
+ padding-left: 12px;
409
+ padding-right: 12px; }
410
+
411
+ .ditty-ticker {
412
+ box-sizing: border-box; }
413
+ .ditty-ticker * {
414
+ box-sizing: border-box; }
415
+ .ditty-ticker__items {
416
+ position: relative;
417
+ overflow: hidden; }
418
+ .ditty-ticker .ditty-item {
419
+ display: none;
420
+ position: absolute;
421
+ line-height: 1;
422
+ /*
423
+ &--current {
424
+ color: green;
425
+ }
426
+ &--last {
427
+ color: red;
428
+ &.ditty-item--current {
429
+ color: purple;
430
+ }
431
+ }
432
+ */ }
433
+
434
+ .ditty-list {
435
+ position: relative;
436
+ box-sizing: border-box; }
437
+ .ditty-list * {
438
+ box-sizing: border-box; }
439
+ .ditty-list .ditty-item {
440
+ position: relative;
441
+ display: block; }
442
+
443
+ .ditty-item-type--wp_editor > *:first-child {
444
+ margin-top: 0; }
445
+
446
+ .ditty-item-type--wp_editor > *:last-child {
447
+ margin-bottom: 0; }
448
+
449
+ .ditty-data-list__item[data-type="wp_editor"] i.fa-edit {
450
+ padding-left: 4px; }
451
+
452
+ .protip-content {
453
+ line-height: 1.5em; }
454
+ .protip-content a {
455
+ color: #FFF; }
456
+
457
+ .ditty-button {
458
+ display: flex;
459
+ flex-direction: row;
460
+ align-items: center;
461
+ justify-content: center;
462
+ font-size: 14px;
463
+ line-height: 20px;
464
+ font-weight: 500;
465
+ text-align: center;
466
+ text-decoration: none;
467
+ color: #23282d;
468
+ background: rgba(0, 0, 0, 0.2);
469
+ border: none;
470
+ border-radius: 3px;
471
+ padding: 10px 15px;
472
+ margin: 10px 0;
473
+ overflow: hidden;
474
+ text-overflow: ellipsis;
475
+ white-space: nowrap;
476
+ cursor: pointer;
477
+ transition: color .25s ease, background-color .25s ease; }
478
+ .ditty-button[disabled] {
479
+ cursor: default; }
480
+ .ditty-button[type="button"], .ditty-button[type="submit"] {
481
+ -webkit-appearance: none;
482
+ border: none;
483
+ cursor: pointer; }
484
+ .ditty-button span {
485
+ margin-left: auto;
486
+ margin-right: auto; }
487
+ .ditty-button i:first-child {
488
+ margin-right: 10px; }
489
+ .ditty-button i:last-child {
490
+ margin-left: 10px; }
491
+ .ditty-button:focus {
492
+ color: #FFF; }
493
+ .ditty-button:hover:not(:disabled) {
494
+ color: #FFF;
495
+ background: #23282d; }
496
+ .ditty-button--small {
497
+ font-size: 12px;
498
+ line-height: 14px;
499
+ font-weight: normal;
500
+ padding: 8px 12px; }
501
+ .ditty-button--small i {
502
+ margin-right: 5px; }
503
+ .ditty-button--large {
504
+ font-size: 18px;
505
+ line-height: 22px;
506
+ padding: 30px; }
507
+ .ditty-button--primary {
508
+ color: #FFF;
509
+ background: #19BF7C; }
510
+ .ditty-button--primary:hover {
511
+ color: #FFF;
512
+ background: #28e398; }
513
+ .ditty-button--wide {
514
+ width: 100%; }
515
+
516
+ .ditty-data-list__filters {
517
+ display: flex;
518
+ flex-direction: row;
519
+ align-items: flex-start;
520
+ justify-content: flex-start;
521
+ flex-wrap: wrap;
522
+ padding: 10px 12px 7px 15px;
523
+ background: #F7F7F7;
524
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05); }
525
+
526
+ .ditty-data-list__filter {
527
+ display: block;
528
+ font-size: 12px;
529
+ line-height: 14px;
530
+ text-decoration: none;
531
+ color: #3c434a;
532
+ background: rgba(0, 0, 0, 0.2);
533
+ border-radius: 3px;
534
+ padding: 8px 12px;
535
+ margin: 0 3px 3px 0;
536
+ transition: background-color .25s ease, color .25s ease; }
537
+ .ditty-data-list__filter i {
538
+ margin-right: 5px; }
539
+ .ditty-data-list__filter:hover {
540
+ color: #FFF;
541
+ background-color: #23282d; }
542
+ .ditty-data-list__filter:focus {
543
+ color: #FFF; }
544
+ .ditty-data-list__filter.active {
545
+ color: #FFF;
546
+ background: #19BF7C; }
547
+
548
+ .ditty-data-list__items {
549
+ background: #FFF;
550
+ padding: 5px; }
551
+
552
+ .ditty-data-list__item {
553
+ display: flex;
554
+ flex-direction: row;
555
+ align-items: center;
556
+ justify-content: flex-start;
557
+ background: #FFF;
558
+ border: 1px solid rgba(0, 0, 0, 0.05);
559
+ margin: 0 0 5px;
560
+ padding-right: 8px;
561
+ border-radius: 3px;
562
+ overflow: hidden;
563
+ transition: background-color .25s ease, border-color .25s ease; }
564
+ .ditty-data-list__item:last-child {
565
+ margin-bottom: 0; }
566
+ .ditty-data-list__item__label {
567
+ color: #444;
568
+ padding-right: 5px;
569
+ margin-right: auto;
570
+ white-space: nowrap;
571
+ overflow: hidden;
572
+ text-overflow: ellipsis;
573
+ transition: color .25s ease;
574
+ -webkit-user-select: none;
575
+ -moz-user-select: none;
576
+ -ms-user-select: none;
577
+ user-select: none; }
578
+ .ditty-data-list__item__label__title {
579
+ display: block;
580
+ white-space: normal;
581
+ overflow: visible;
582
+ font-weight: bold;
583
+ margin-bottom: 1px; }
584
+ .ditty-data-list__item__label__description {
585
+ display: block;
586
+ white-space: normal;
587
+ overflow: visible;
588
+ font-size: .85em; }
589
+ .ditty-data-list__item a {
590
+ display: none;
591
+ flex: 0 0 auto;
592
+ text-decoration: none;
593
+ color: rgba(0, 0, 0, 0.4);
594
+ overflow: hidden;
595
+ transition: color .25s ease;
596
+ margin: 0 2px; }
597
+ .ditty-data-list__item a:focus {
598
+ outline: none;
599
+ box-shadow: none;
600
+ color: #19BF7C; }
601
+ .ditty-data-list__item a:hover {
602
+ color: rgba(0, 0, 0, 0.7); }
603
+ .ditty-data-list__item a:hover i {
604
+ transform: scale(1.2); }
605
+ .ditty-data-list__item a.ditty-data-list__item__icon,
606
+ .ditty-data-list__item span.ditty-data-list__item__icon {
607
+ font-size: 14px;
608
+ margin: 0; }
609
+ .ditty-data-list__item a.ditty-data-list__item__icon:not(:focus),
610
+ .ditty-data-list__item span.ditty-data-list__item__icon:not(:focus) {
611
+ color: rgba(0, 0, 0, 0.7); }
612
+ .ditty-data-list__item a.ditty-data-list__item__icon i,
613
+ .ditty-data-list__item span.ditty-data-list__item__icon i {
614
+ display: block;
615
+ width: 40px;
616
+ height: 40px;
617
+ text-align: center;
618
+ line-height: 40px; }
619
+ .ditty-data-list__item a.ditty-data-list__item__icon:hover {
620
+ color: rgba(0, 0, 0, 0.9); }
621
+ .ditty-data-list__item i {
622
+ display: block;
623
+ width: 20px;
624
+ height: 20px;
625
+ text-align: center;
626
+ line-height: 20px;
627
+ transition: transform 0.3s ease; }
628
+ .ditty-data-list__item i:focus {
629
+ outline: none; }
630
+ .ditty-data-list__item:hover {
631
+ background-color: #FAFAFA; }
632
+ .ditty-data-list__item:hover a {
633
+ display: block; }
634
+ .ditty-data-list__item:focus-within a {
635
+ display: block; }
636
+ .ditty-data-list__item.active {
637
+ cursor: default;
638
+ background: #EDF8ED;
639
+ border-color: #19BF7C;
640
+ /*
641
+ a:not(.ditty-data-list__item__icon) {
642
+ color: #89D08D;
643
+ &:hover {
644
+ color: $green;
645
+ }
646
+ }
647
+ */ }
648
+ .ditty-data-list__item.active:hover {
649
+ background: #DBF1DB; }
650
+
651
+ .ditty-accordion {
652
+ background: #F1F1F1;
653
+ margin: 5px 0; }
654
+ .ditty-accordion__toggle {
655
+ position: relative;
656
+ display: block;
657
+ font-size: 14px;
658
+ line-height: 20px;
659
+ font-weight: 500;
660
+ text-align: left;
661
+ text-decoration: none;
662
+ color: #FFF;
663
+ background: #32373C;
664
+ border-radius: 3px;
665
+ padding: 10px 40px 10px 15px;
666
+ margin: 0;
667
+ cursor: pointer;
668
+ transition: color .25s ease, background-color .25s ease, border-radius .5s ease; }
669
+ .ditty-accordion__toggle i {
670
+ margin-right: 5px; }
671
+ .ditty-accordion__toggle:after {
672
+ position: absolute;
673
+ top: 50%;
674
+ right: 15px;
675
+ content: '\f078';
676
+ font-family: 'Font Awesome 5 Pro';
677
+ width: 20px;
678
+ height: 20px;
679
+ font-size: 17px;
680
+ line-height: 20px;
681
+ text-align: center;
682
+ margin-top: -10px;
683
+ transition: transform .25s ease; }
684
+ .ditty-accordion__content {
685
+ display: none;
686
+ line-height: 1.5em;
687
+ padding: 15px; }
688
+ .ditty-accordion__content > *:first-child {
689
+ margin-top: 0; }
690
+ .ditty-accordion__content > *:last-child {
691
+ margin-bottom: 0; }
692
+ .ditty-accordion.active > .ditty-accordion__toggle {
693
+ border-bottom-left-radius: 0;
694
+ border-bottom-right-radius: 0; }
695
+ .ditty-accordion.active > .ditty-accordion__toggle:after {
696
+ transform: rotate(180deg); }
697
+
698
+ /**
699
+ * Ditty Editor Styles
700
+ */
701
+ #ditty-editor {
702
+ position: relative;
703
+ display: flex;
704
+ flex-direction: row;
705
+ align-items: stretch;
706
+ justify-content: flex-start;
707
+ box-sizing: border-box; }
708
+ #ditty-editor__preview {
709
+ order: 0;
710
+ flex: 1;
711
+ width: calc( 100% - 350px);
712
+ background: #FFF;
713
+ box-sizing: border-box; }
714
+ #ditty-editor__settings {
715
+ position: relative;
716
+ order: 1;
717
+ display: flex;
718
+ flex-direction: column;
719
+ align-items: stretch;
720
+ justify-content: flex-start;
721
+ width: 350px;
722
+ background: #32373C; }
723
+ #ditty-editor__settings .ditty-field {
724
+ padding: 15px;
725
+ border-color: rgba(0, 0, 0, 0.05); }
726
+ #ditty-editor__settings .ditty-field__label {
727
+ font-weight: 400; }
728
+ #ditty-editor__settings .ditty-field-type--group {
729
+ padding: 0;
730
+ border-color: rgba(0, 0, 0, 0.05); }
731
+ #ditty-editor__settings .ditty-field-type--checkboxes .ditty-field {
732
+ padding: 0 10px 0 0;
733
+ border: none; }
734
+ #ditty-editor__settings .ditty-input--group__container > .ditty-field {
735
+ width: 100%; }
736
+ #ditty-editor .ditty-editor__panels {
737
+ background: #F7F7F7; }
738
+ #ditty-editor .ditty-editor__contents {
739
+ display: flex;
740
+ flex-direction: column;
741
+ align-items: stretch;
742
+ justify-content: flex-start;
743
+ height: 100%; }
744
+ #ditty-editor .ditty-editor__header {
745
+ flex: 0 0 auto;
746
+ display: flex;
747
+ flex-direction: row;
748
+ align-items: stretch;
749
+ justify-content: flex-end;
750
+ padding: 15px;
751
+ border-bottom: 1px solid rgba(255, 255, 255, 0.2); }
752
+ #ditty-editor .ditty-editor__header .ditty-editor__title {
753
+ flex: 1;
754
+ width: 100%;
755
+ min-height: 0;
756
+ border: 1px solid rgba(0, 0, 0, 0.2);
757
+ border-radius: 3px;
758
+ padding: 5px 10px;
759
+ margin: 0; }
760
+ #ditty-editor .ditty-editor__header .ditty-editor__update {
761
+ flex: 0 0 auto;
762
+ margin: 0 0 0 5px; }
763
+ #ditty-editor .ditty-editor__header .ditty-editor__update__count {
764
+ font-size: 10px;
765
+ line-height: 14px;
766
+ font-weight: bold;
767
+ background: rgba(255, 255, 255, 0.9);
768
+ color: #32373C;
769
+ padding: 3px 7px;
770
+ margin-right: 5px;
771
+ border-radius: 15px; }
772
+ #ditty-editor .ditty-editor__header .ditty-editor__update__count:empty {
773
+ display: none; }
774
+ #ditty-editor .ditty-editor__tabs {
775
+ display: flex;
776
+ flex-direction: row;
777
+ align-items: center;
778
+ justify-content: flex-start;
779
+ background: #32373C; }
780
+ #ditty-editor .ditty-editor__tab {
781
+ position: relative;
782
+ display: flex;
783
+ flex-direction: row;
784
+ align-items: center;
785
+ justify-content: flex-start;
786
+ font-weight: 400;
787
+ color: #FFF;
788
+ padding: 10px;
789
+ text-align: center;
790
+ text-decoration: none;
791
+ background-color: transparent;
792
+ border-radius: 0;
793
+ transition: color .25s ease, background-color .25s ease; }
794
+ #ditty-editor .ditty-editor__tab span {
795
+ display: block;
796
+ padding-left: 20px; }
797
+ #ditty-editor .ditty-editor__tab i {
798
+ position: absolute;
799
+ top: 13px;
800
+ display: block;
801
+ font-size: 13px; }
802
+ #ditty-editor .ditty-editor__tab:focus {
803
+ color: #FFF;
804
+ outline: none;
805
+ box-shadow: none; }
806
+ #ditty-editor .ditty-editor__tab:hover {
807
+ color: #FFF;
808
+ background-color: rgba(255, 255, 255, 0.2); }
809
+ #ditty-editor .ditty-editor__tab.active {
810
+ color: #FFF;
811
+ background-color: #19BF7C; }
812
+ #ditty-editor .ditty-editor__tab.active:after {
813
+ border: 6px solid transparent;
814
+ content: " ";
815
+ height: 0;
816
+ width: 0;
817
+ position: absolute;
818
+ pointer-events: none;
819
+ border-bottom-color: #F7F7F7;
820
+ left: 50%;
821
+ bottom: 0;
822
+ margin-left: -5px; }
823
+ #ditty-editor .ditty-editor__import-export textarea {
824
+ width: 100%; }
825
+ #ditty-editor .ditty-editor__spacer {
826
+ width: 100%; }
827
+ #ditty-editor .ditty-editor__oauth-warning {
828
+ display: inline-block;
829
+ font-weight: bold;
830
+ color: #FFF;
831
+ padding: 5px 8px;
832
+ border-radius: 3px;
833
+ background: #E1362E;
834
+ vertical-align: middle; }
835
+ #ditty-editor .ditty-editor__oauth-warning i {
836
+ display: inline;
837
+ color: rgba(255, 255, 255, 0.8); }
838
+
839
+ .ditty-editor--updates-exist .ditty-editor__header .ditty-editor__update {
840
+ background-color: orange; }
841
+
842
+ .ditty-editor-options__header {
843
+ display: flex;
844
+ flex-direction: row;
845
+ align-items: center;
846
+ justify-content: flex-start;
847
+ flex-wrap: wrap;
848
+ padding: 10px 15px;
849
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05); }
850
+
851
+ .ditty-editor-options__buttons {
852
+ display: flex;
853
+ flex-direction: row;
854
+ align-items: center;
855
+ justify-content: flex-start; }
856
+ .ditty-editor-options__buttons .ditty-button {
857
+ margin: 0; }
858
+ .ditty-editor-options__buttons a:not(.ditty-button),
859
+ .ditty-editor-options__buttons button:not(.ditty-button) {
860
+ display: block;
861
+ width: 30px;
862
+ height: 30px;
863
+ text-align: center;
864
+ line-height: 30px;
865
+ color: #FFF;
866
+ background: #32373C;
867
+ border: none;
868
+ border-radius: 3px;
869
+ transition: background-color .25s ease, color .25s ease;
870
+ margin: 0;
871
+ padding: 0; }
872
+ .ditty-editor-options__buttons a:not(.ditty-button):hover,
873
+ .ditty-editor-options__buttons button:not(.ditty-button):hover {
874
+ color: #FFF;
875
+ background-color: #19BF7C; }
876
+ .ditty-editor-options__buttons a:not(.ditty-button).ditty-editor-options__preview.ditty-has-updates,
877
+ .ditty-editor-options__buttons button:not(.ditty-button).ditty-editor-options__preview.ditty-has-updates {
878
+ cursor: pointer;
879
+ background-color: orange;
880
+ opacity: 1; }
881
+ .ditty-editor-options__buttons a:not(.ditty-button).ditty-editor-options__preview.ditty-has-updates:hover,
882
+ .ditty-editor-options__buttons button:not(.ditty-button).ditty-editor-options__preview.ditty-has-updates:hover {
883
+ background-color: #19BF7C; }
884
+ .ditty-editor-options__buttons a:not(.ditty-button).ditty-editor-options__preview:not(.ditty-has-updates),
885
+ .ditty-editor-options__buttons button:not(.ditty-button).ditty-editor-options__preview:not(.ditty-has-updates) {
886
+ cursor: default;
887
+ opacity: .2; }
888
+ .ditty-editor-options__buttons a:not(.ditty-button).ditty-editor-options__preview:not(.ditty-has-updates):hover,
889
+ .ditty-editor-options__buttons button:not(.ditty-button).ditty-editor-options__preview:not(.ditty-has-updates):hover {
890
+ background: #32373C; }
891
+ .ditty-editor-options__buttons a:not(.ditty-button).ditty-editor-options__preview:not(.ditty-has-updates):focus,
892
+ .ditty-editor-options__buttons button:not(.ditty-button).ditty-editor-options__preview:not(.ditty-has-updates):focus {
893
+ border: none;
894
+ outline: none;
895
+ box-shadow: none; }
896
+ .ditty-editor-options__buttons--start a:not(.ditty-button),
897
+ .ditty-editor-options__buttons--start button:not(.ditty-button) {
898
+ margin-right: 5px; }
899
+ .ditty-editor-options__buttons--end {
900
+ margin-left: auto; }
901
+ .ditty-editor-options__buttons--end a:not(.ditty-button),
902
+ .ditty-editor-options__buttons--end button:not(.ditty-button) {
903
+ margin-left: 5px; }
904
+
905
+ .ditty-editor-options__save {
906
+ margin-left: auto;
907
+ cursor: pointer; }
908
+ .ditty-editor-options__save.unsaved-updates i {
909
+ -webkit-animation-name: ditty-unsaved-changes;
910
+ animation-name: ditty-unsaved-changes;
911
+ -webkit-animation-timing-function: ease;
912
+ animation-timing-function: ease;
913
+ -webkit-animation-duration: .75s;
914
+ animation-duration: .75s;
915
+ -webkit-animation-iteration-count: infinite;
916
+ animation-iteration-count: infinite; }
917
+
918
+ .ditty-editor-options__title, .ditty-editor-options__title[type="text"] {
919
+ flex: 1;
920
+ font-size: 14px;
921
+ line-height: 18px;
922
+ margin: 0;
923
+ white-space: nowrap;
924
+ overflow: hidden;
925
+ text-overflow: ellipsis;
926
+ border-radius: 3px !important; }
927
+
928
+ .ditty-editor-options__title[type="text"] {
929
+ background: transparent; }
930
+
931
+ .ditty-editor-options__body {
932
+ position: relative;
933
+ max-height: calc( 100vh - 470px);
934
+ min-height: 300px;
935
+ overflow-y: scroll;
936
+ -webkit-overflow-scrolling: touch; }
937
+ .ditty-editor-options__body__error {
938
+ position: absolute;
939
+ top: 0;
940
+ left: 0;
941
+ right: 0;
942
+ bottom: 0;
943
+ z-index: 99;
944
+ display: flex;
945
+ flex-direction: row;
946
+ align-items: center;
947
+ justify-content: center;
948
+ text-align: center;
949
+ background: rgba(170, 0, 0, 0.5);
950
+ padding: 20px;
951
+ cursor: pointer; }
952
+ .ditty-editor-options__body__error span {
953
+ display: block;
954
+ line-height: 1.5em;
955
+ color: #FFF;
956
+ text-shadow: 0 0 3px rgba(0, 0, 0, 0.5); }
957
+
958
+ .ditty-editor-options__code {
959
+ width: 100%; }
960
+
961
+ .ditty-editor-options__footer {
962
+ padding: 10px;
963
+ border-top: 1px solid #ddd;
964
+ background: #f5f5f5;
965
+ box-sizing: border-box; }
966
+ .ditty-editor-options__footer .button {
967
+ margin-left: 5px; }
968
+
969
+ .ditty-editor-options__tags h3 {
970
+ font-size: 14px;
971
+ line-height: 14px;
972
+ margin: 0 0 10px; }
973
+
974
+ .ditty-editor-options__tags__list {
975
+ display: flex;
976
+ flex-direction: row;
977
+ align-items: center;
978
+ justify-content: flex-start;
979
+ flex-wrap: wrap;
980
+ margin: -2px; }
981
+
982
+ .ditty-editor-options__tag {
983
+ font-size: 12px;
984
+ line-height: 12px;
985
+ background: rgba(0, 0, 0, 0.05);
986
+ border-radius: 2px;
987
+ padding: 3px 5px;
988
+ margin: 2px;
989
+ cursor: pointer;
990
+ transition: background-color .25s ease; }
991
+ .ditty-editor-options__tag:hover {
992
+ background: rgba(0, 0, 0, 0.15); }
993
+
994
+ .ditty-editor-options.ditty-editor-has-errors .ditty-editor-options__save {
995
+ cursor: default;
996
+ color: red;
997
+ opacity: .3; }
998
+
999
+ .ditty-editor-options .ditty-data-list__items {
1000
+ background: #F7F7F7;
1001
+ padding: 15px; }
1002
+
1003
+ .ditty-editor-item--error {
1004
+ background-color: #fbeaea; }
1005
+ .ditty-editor-item--error .ditty-data-list__item__icon,
1006
+ .ditty-editor-item--error .ditty-data-list__item__label {
1007
+ color: #E1362E !important; }
1008
+ .ditty-editor-item--error:hover {
1009
+ background-color: #fbeaea;
1010
+ border-color: #E1362E; }
1011
+
1012
+ @-webkit-keyframes ditty-unsaved-changes {
1013
+ 0% {
1014
+ color: #FFF; }
1015
+ 50% {
1016
+ color: #FF3B77; }
1017
+ 100% {
1018
+ color: #FFF; } }
1019
+
1020
+ @keyframes ditty-unsaved-changes {
1021
+ 0% {
1022
+ color: #FFF; }
1023
+ 50% {
1024
+ color: #FF3B77; }
1025
+ 100% {
1026
+ color: #FFF; } }
1027
+
1028
+ @media (max-width: 800px) {
1029
+ #ditty-editor {
1030
+ flex-direction: column; }
1031
+ #ditty-editor__preview, #ditty-editor__settings {
1032
+ width: 100%; } }
1033
+
1034
+ .ditty-editor__panel--items .ditty-data-list {
1035
+ max-height: calc( 100vh - 470px);
1036
+ min-height: 300px;
1037
+ overflow-y: scroll;
1038
+ -webkit-overflow-scrolling: touch; }
1039
+ .ditty-editor__panel--items .ditty-data-list__item.ditty-editor-item--disabled {
1040
+ cursor: default;
1041
+ background: #F8EDED;
1042
+ border: 1px solid red;
1043
+ box-shadow: 0 0 1px red; }
1044
+ .ditty-editor__panel--items .ditty-data-list__item a.ditty-data-list__item__icon {
1045
+ display: block; }
1046
+
1047
+ .ditty-editor-display {
1048
+ cursor: pointer; }
1049
+ .ditty-editor-display:not(.active):hover .ditty-data-list__item__edit {
1050
+ display: none; }
1051
+ .ditty-editor-display--default .ditty-data-list__item__delete {
1052
+ display: none !important; }
1053
+ .ditty-editor-display.active .ditty-data-list__item__delete {
1054
+ display: none; }
1055
+ .ditty-editor-display.active:hover .ditty-data-list__item__delete {
1056
+ display: none; }
1057
+ .ditty-editor-display--default {
1058
+ background-color: #CCC; }
1059
+ .ditty-editor-display .ditty-data-list {
1060
+ max-height: calc( 100vh - 470px);
1061
+ min-height: 300px;
1062
+ overflow-y: scroll;
1063
+ -webkit-overflow-scrolling: touch; }
1064
+
1065
+ .ditty-editor-layout {
1066
+ cursor: pointer; }
1067
+ .ditty-editor-layout:not(.active):hover .ditty-data-list__item__edit_html,
1068
+ .ditty-editor-layout:not(.active):hover .ditty-data-list__item__edit_css {
1069
+ display: none; }
1070
+ .ditty-editor-layout.active .ditty-data-list__item__delete {
1071
+ display: none; }
1072
+ .ditty-editor-layout.active:hover .ditty-data-list__item__delete {
1073
+ display: none; }
1074
+
1075
+ .ditty-layout-variation {
1076
+ padding: 5px 8px 0 10px; }
1077
+ .ditty-layout-variation__icon i {
1078
+ width: 40px;
1079
+ height: 40px;
1080
+ font-size: 20px;
1081
+ line-height: 40px; }
1082
+ .ditty-layout-variation__content {
1083
+ flex: 1;
1084
+ display: flex;
1085
+ flex-direction: column;
1086
+ align-items: flex-start;
1087
+ justify-content: flex-start;
1088
+ padding: 5px 0 5px; }
1089
+ .ditty-layout-variation__label {
1090
+ display: block;
1091
+ font-weight: bold;
1092
+ margin-bottom: 5px; }
1093
+ .ditty-layout-variation__template {
1094
+ display: block;
1095
+ margin-bottom: 5px; }
1096
+ .ditty-layout-variation__buttons {
1097
+ flex: 0 0 auto;
1098
+ display: flex;
1099
+ flex-direction: row;
1100
+ align-items: center;
1101
+ justify-content: flex-start; }
1102
+ .ditty-layout-variation__buttons a {
1103
+ display: block; }
1104
+ .ditty-layout-variation a.ditty-layout-variation__change {
1105
+ flex: 0 0 auto;
1106
+ display: block; }
1107
+ .ditty-layout-variation a.ditty-layout-variation__change i {
1108
+ width: 30px;
1109
+ height: 30px;
1110
+ font-size: 20px;
1111
+ line-height: 30px;
1112
+ color: #444; }
1113
+
1114
+ .ditty-editor__panel--item_types .ditty-data-list__items {
1115
+ display: flex;
1116
+ flex-direction: column;
1117
+ align-items: stretch;
1118
+ justify-content: flex-start; }
1119
+
1120
+ .ditty-editor__panel--item_types .ditty-data-list__item {
1121
+ cursor: pointer;
1122
+ order: 1; }
1123
+ .ditty-editor__panel--item_types .ditty-data-list__item.active {
1124
+ order: 0; }
includes/fields/ditty-field-button.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Number Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Number
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Button extends Ditty_Field {
13
+
14
+ public $type = 'button';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'label' => __( 'Button', 'ditty-news-ticker' ),
25
+ 'link' => '#',
26
+ 'size' => 'default',
27
+ 'priority' => 'default',
28
+ 'full_width' => false,
29
+ 'icon_before' => '',
30
+ 'icon_after' => '',
31
+ );
32
+ return wp_parse_args( $atts, $this->common );
33
+ }
34
+
35
+ /**
36
+ * Return the input
37
+ *
38
+ * @since 3.0
39
+ * @return $html string
40
+ */
41
+ public function input( $name, $std = false ) {
42
+ $html = '';
43
+ $icon_before = ( $this->args['icon_before'] ) ? '<i class="' . esc_attr( $this->args['icon_before'] ) . '"></i>' : '';
44
+ $icon_after = ( $this->args['icon_after'] ) ? '<i class="' . esc_attr( $this->args['icon_after'] ) . '"></i>' : '';
45
+
46
+ $class = 'ditty-button';
47
+ if ( $this->args['size'] ) {
48
+ $class .= ' ditty-button--' . $this->args['size'];
49
+ }
50
+ if ( $this->args['priority'] ) {
51
+ $class .= ' ditty-button--' . $this->args['priority'];
52
+ }
53
+ if ( $this->args['full_width'] ) {
54
+ $class .= ' ditty-button--wide';
55
+ }
56
+ if ( $this->args['input_class'] ) {
57
+ $class .= ' ' . $this->args['input_class'];
58
+ }
59
+ $atts = array(
60
+ 'name' => $name,
61
+ 'class' => $class,
62
+ 'href' => $this->args['link'],
63
+ );
64
+ if ( is_array( $this->args['atts'] ) && count( $this->args['atts'] ) > 0 ) {
65
+ foreach ( $this->args['atts'] as $key => $value ) {
66
+ $atts[$key] = $value;
67
+ }
68
+ }
69
+
70
+ $html .= '<button ' . ditty_attr_to_html( $atts ) . '><span class="ditty-button__contents">' . $icon_before . '<span ditty-button__label>' . sanitize_text_field( $this->args['label'] ) . '</span>' . $icon_after . '</span></button>';
71
+ return $html;
72
+ }
73
+
74
+ }
includes/fields/ditty-field-checkbox.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Checkbox Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Checkbox
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Checkbox extends Ditty_Field {
13
+
14
+ public $type = 'checkbox';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'label' => '',
25
+ 'value' => '1',
26
+ );
27
+ return wp_parse_args( $atts, $this->common );
28
+ }
29
+
30
+ /**
31
+ * Return the input
32
+ *
33
+ * @since 3.0
34
+ * @return $html string
35
+ */
36
+ public function input( $name, $std = false ) {
37
+ $html = '';
38
+ $id = uniqid( 'ditty-input--' );
39
+ $value = sanitize_text_field( $this->args['value'] );
40
+ $html .= '<input id="ditty-input--' . $id . '" name="' . $name . '" type="checkbox" value="' . $value . '" ' . checked( $value, $std, false ) . ' />';
41
+ if ( '' != $this->args['label'] ) {
42
+ $html .= ' <label for="ditty-input--' . $id . '">' . sanitize_text_field( $this->args['label'] ) . '</label>';
43
+ }
44
+ return $html;
45
+ }
46
+
47
+ }
includes/fields/ditty-field-checkboxes.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Checkboxes Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Checkboxes
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Checkboxes extends Ditty_Field {
13
+
14
+ public $type = 'checkboxes';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'options' => array(),
25
+ );
26
+ return wp_parse_args( $atts, $this->common );
27
+ }
28
+
29
+ /**
30
+ * Return the input
31
+ *
32
+ * @since 3.0
33
+ * @return $html string
34
+ */
35
+ public function input( $name, $standard = false ) {
36
+ $inputs = array();
37
+ foreach ( $this->args['options'] as $key => $label ) {
38
+ $std = ( is_array( $standard ) && isset( $standard[ $key ] ) ) ? $standard[ $key ] : false;
39
+ $atts = array(
40
+ 'id' => "{$name}[{$key}]",
41
+ 'label' => $label,
42
+ 'value' => $key,
43
+ 'std' => $std,
44
+ );
45
+ $input = new Ditty_Field_Checkbox();
46
+ $input->init( $atts );
47
+ $inputs[] = $input->html();
48
+ }
49
+
50
+ $html = '<div class="ditty-input--checkboxes__group">' . implode( ' ', $inputs ) . '</div>';
51
+ return $html;
52
+ }
53
+
54
+ }
includes/fields/ditty-field-code.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Code Field Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Code
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Code extends Ditty_Field {
13
+
14
+ public $type = 'code';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'rows' => 4,
25
+ 'cols' => 60,
26
+ 'js_options' => array(),
27
+ );
28
+ return wp_parse_args( $atts, $this->common );
29
+ }
30
+
31
+ /**
32
+ * Return the default atts
33
+ *
34
+ * @access private
35
+ * @since 3.0
36
+ */
37
+ private function attributes() {
38
+ $atts = array();
39
+ if ( is_array( $this->args['js_options'] ) && count( $this->args['js_options'] ) > 0 ) {
40
+ foreach ( $this->args['js_options'] as $option => $value ) {
41
+ $atts["data-{$option}"] = $value;
42
+ }
43
+ }
44
+ $atts['rows'] = $this->args['rows'];
45
+ $atts['cols'] = $this->args['cols'];
46
+ return $atts;
47
+ }
48
+
49
+ /**
50
+ * Return the input
51
+ *
52
+ * @since 3.0
53
+ * @return $html string
54
+ */
55
+ public function input( $name, $std = false ) {
56
+ $html = '';
57
+ $html .= '<textarea name="' . $name . '" ' . ditty_attr_to_html( $this->attributes() ) . '>' . $std . '</textarea>';
58
+ return $html;
59
+ }
60
+ }
includes/fields/ditty-field-color.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Color Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Color
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Color extends Ditty_Field {
13
+
14
+ public $type = 'color';
15
+
16
+ /**
17
+ * Return the input
18
+ *
19
+ * @since 3.0
20
+ * @return $html string
21
+ */
22
+ public function input( $name, $std = false ) {
23
+ $html = '';
24
+ $html .= '<input name="' . $name . '" type="text" value="' . sanitize_text_field( $std ) . '" />';
25
+ return $html;
26
+ }
27
+
28
+ }
includes/fields/ditty-field-date.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Date Field Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Date
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Date extends Ditty_Field {
13
+
14
+ public $type = 'date';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'js_options' => array(
25
+ 'dateFormat' => 'yy-mm-dd',
26
+ ),
27
+ );
28
+ return wp_parse_args( $atts, $this->common );
29
+ }
30
+
31
+ /**
32
+ * Return the default atts
33
+ *
34
+ * @access private
35
+ * @since 3.0
36
+ */
37
+ private function attributes() {
38
+ $atts = array();
39
+ if ( is_array( $this->args['js_options'] ) && count( $this->args['js_options'] ) > 0 ) {
40
+ foreach ( $this->args['js_options'] as $option => $value ) {
41
+ $atts["data-{$option}"] = $value;
42
+ }
43
+ }
44
+ return $atts;
45
+ }
46
+
47
+ /**
48
+ * Return the input
49
+ *
50
+ * @since 3.0
51
+ * @return $html string
52
+ */
53
+ public function input( $name, $std = false ) {
54
+ $html = '';
55
+ $html .= '<input name="' . $name . '" type="text" value="' . $std . '" ' . ditty_attr_to_html( $this->attributes() ) . ' />';
56
+ return $html;
57
+ }
58
+ }
includes/fields/ditty-field-divider.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Divider Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Divider
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Divider extends Ditty_Field {
13
+
14
+ public $type = 'divider';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'height' => 50,
25
+ 'line' => true,
26
+ 'line_height' => 2,
27
+ );
28
+ return wp_parse_args( $atts, $this->common );
29
+ }
30
+
31
+ /**
32
+ * Return the html
33
+ *
34
+ * @since 3.0
35
+ * @return $html string
36
+ */
37
+ public function html() {
38
+ $html = '';
39
+
40
+ $height = intval( $this->args['height'] );
41
+ if ( $height < 0 ) {
42
+ $height = 30;
43
+ }
44
+
45
+ $id = parent::sanitize_id( $this->args['id'] );
46
+ $classes = 'ditty-field ditty-field-type--' . $this->type . ' ' . $this->sanitize_id( 'ditty-field--' . $id );
47
+ $classes .= ( '' != $this->args['baseid'] ) ? ' ditty-field--' . esc_attr( $this->args['baseid'] ) : '';
48
+ $classes .= ( '' != $this->args['class'] ) ? ' ' . esc_attr( $this->args['class'] ) : '';
49
+ $classes .= ( $this->args['clone'] ) ? ' ditty-field--clone-enabled' : '';
50
+
51
+ $atts = array(
52
+ //'id' => sanitize_id( 'ditty-field--' . $id ),
53
+ 'class' => $classes,
54
+ );
55
+ if ( $this->args['clone'] ) {
56
+ $atts['data-clone_name'] = $this->args['id'];
57
+ $atts['data-clone_args'] = htmlentities( json_encode( $this->args ) );
58
+ $atts['data-clone_field'] = htmlentities( $this->input_wrap( $this->args['id'] ) );
59
+ $atts['data-clone_max' ] = intval( $this->args['max_clone'] );
60
+ $atts['style' ] = "height:{$height}px";
61
+ }
62
+ $html .= '<div ' . ditty_attr_to_html( $atts ) . '>';
63
+ $html .= '<div class="ditty-field__heading">';
64
+ $html .= parent::label();
65
+ $html .= parent::description();
66
+ $html .= '</div>';
67
+ $html .= parent::input_container();
68
+ $html .= '</div>';
69
+ return $html;
70
+ }
71
+
72
+ /**
73
+ * Return the input
74
+ *
75
+ * @since 3.0
76
+ * @return $html string
77
+ */
78
+ public function input( $name, $std = false ) {
79
+ $html = '';
80
+
81
+ $line_height = intval( $this->args['line_height'] );
82
+ if ( $line_height < 0 ) {
83
+ $line_height = 1;
84
+ }
85
+ if ( true == $this->args['line'] ) {
86
+ $html .= '<div class="ditty-input--divider__line" style="height:' . $line_height . 'px"></div>';
87
+ }
88
+ return $html;
89
+ }
90
+
91
+ }
includes/fields/ditty-field-group.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Group Field Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Group
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Group extends Ditty_Field {
13
+
14
+ public $type = 'group';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'fields' => array(),
25
+ 'group_title' => '',
26
+ 'collapsible' => false,
27
+ 'default_state' => 'expanded',
28
+ 'multiple_fields' => false,
29
+ );
30
+ return wp_parse_args( $atts, $this->common );
31
+ }
32
+
33
+ /**
34
+ * Return the html
35
+ *
36
+ * @since 3.0
37
+ * @return $html string
38
+ */
39
+ public function html() {
40
+ $atts = $this->html_atts();
41
+ if ( $this->args['collapsible'] ) {
42
+ $atts['data-collapsible'] = $this->args['default_state'];
43
+ }
44
+ $html = '';
45
+ $html .= '<div ' . ditty_attr_to_html( $atts ) . '>';
46
+ if ( '' != $this->label() || '' != $this->description() ) {
47
+ $html .= '<div class="ditty-field__heading">';
48
+ $html .= $this->label();
49
+ $html .= $this->description();
50
+ if ( $this->args['collapsible'] ) {
51
+ $html .= '<a href="#" class="ditty-field__collapsible-toggle"><i class="fas fa-angle-down"></i></a>';
52
+ }
53
+ $html .= '</div>';
54
+ }
55
+ $html .= $this->input_container();
56
+ $html .= '</div>';
57
+ return $html;
58
+ }
59
+
60
+ /**
61
+ * Return the input
62
+ *
63
+ * @since 3.0
64
+ * @return $html string
65
+ */
66
+ public function input( $name, $std = false ) {
67
+ $inputs = array();
68
+ $values = $this->args['std'];
69
+
70
+ if ( $this->args['multiple_fields'] ) {
71
+ foreach ( $this->args['fields'] as $field_args ) {
72
+ //$id = $field_args['id'];
73
+ //$field_args['std'] = isset( $std[$id] ) ? $std[$id] : false;
74
+ $inputs[] = ditty_field( $field_args );
75
+ }
76
+ } else {
77
+ foreach ( $this->args['fields'] as $field_args ) {
78
+ $id = $field_args['id'];
79
+ $field_args['id'] = "{$name}[{$id}]";
80
+ $field_args['baseid'] = $id;
81
+ $field_args['class'] = 'ditty-field-type--group-child';
82
+ $field_args['std'] = isset( $std[$id] ) ? $std[$id] : false;
83
+ $inputs[] = ditty_field( $field_args );
84
+ }
85
+ }
86
+
87
+ $html = '<div class="ditty-input--group__container">' . implode( ' ', $inputs ) . '</div>';
88
+ return $html;
89
+ }
90
+ }
includes/fields/ditty-field-html.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Html Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Html
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Html extends Ditty_Field {
13
+
14
+ public $type = 'html';
15
+
16
+ /**
17
+ * Return the input
18
+ *
19
+ * @since 3.0
20
+ * @return $html string
21
+ */
22
+ public function input( $name, $std = false ) {
23
+ return $std;
24
+ }
25
+
26
+ }
includes/fields/ditty-field-image.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Image Field Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Image
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Image extends Ditty_Field {
13
+ public $type = 'image';
14
+
15
+ /**
16
+ * Return the default atts
17
+ *
18
+ * @access private
19
+ * @since 3.0
20
+ */
21
+ public function defaults() {
22
+ $atts = array(
23
+ 'types' => array(),
24
+ 'multiple' => false,
25
+ 'media_title' => __( 'Upload or select an image', 'ditty-news-ticker' ),
26
+ 'media_button' => __( 'Insert Image', 'ditty-news-ticker' ),
27
+ );
28
+ return wp_parse_args( $atts, $this->common );
29
+ }
30
+
31
+ /**
32
+ * Return the input
33
+ *
34
+ * @since 3.0
35
+ * @return $html string
36
+ */
37
+ public function input( $name, $std = false ) {
38
+ $html = '';
39
+
40
+ $atts = array(
41
+ 'name' => $name,
42
+ 'type' => 'hidden',
43
+ 'class' => ( $this->args['input_class'] ) ? $this->args['input_class'] : false,
44
+ 'data-media_title' => $this->args['media_title'],
45
+ 'data-media_button' => $this->args['media_button'],
46
+ 'data-multiple' => $this->args['multiple'],
47
+ 'value' => $std,
48
+ );
49
+ $html .= '<input ' . ditty_attr_to_html( $atts ) . ' />';
50
+ $html .= '<div class="ditty-input--image__preview">';
51
+ if( '' != $std ) {
52
+ $html .= wp_get_attachment_image( $std, 'medium' );
53
+ $html .= '<a href="#" class="ditty-input--image__upload"></a>';
54
+ } else {
55
+ $html .= '<a href="#" class="ditty-input--image__upload"><i class="fas fa-plus"></i></a>';
56
+ }
57
+ $html .= '</div>';
58
+ return $html;
59
+ }
60
+ }
includes/fields/ditty-field-number.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Number Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Number
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Number extends Ditty_Field {
13
+
14
+ public $type = 'number';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'min' => '0',
25
+ 'step' => '1',
26
+ );
27
+ return wp_parse_args( $atts, $this->common );
28
+ }
29
+
30
+ /**
31
+ * Return the input
32
+ *
33
+ * @since 3.0
34
+ * @return $html string
35
+ */
36
+ public function input( $name, $std = false ) {
37
+ $html = '';
38
+ $html .= '<input name="' . $name . '" step="' . intval( $this->args['step'] ) . '" min="' . intval( $this->args['min'] ) . '" type="number" value="' . intval( $std ) . '" />';
39
+ return $html;
40
+ }
41
+
42
+ }
includes/fields/ditty-field-radio.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Radio Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Radio
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Radio extends Ditty_Field {
13
+
14
+ public $type = 'radio';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'options' => array(),
25
+ 'inline' => false,
26
+ );
27
+ return wp_parse_args( $atts, $this->common );
28
+ }
29
+
30
+ /**
31
+ * Return a single input
32
+ *
33
+ * @since 3.0
34
+ * @return $html string
35
+ */
36
+ public function input_wrap( $name, $std = false, $clone = 'orig' ) {
37
+ $html = '';
38
+
39
+ $extra_classes = '';
40
+ if ( $this->args['clone'] ) {
41
+ $extra_classes .= ' ditty-input--clone ditty-input--clone--' . $clone;
42
+ }
43
+ if ( $this->args['inline'] ) {
44
+ $extra_classes .= ' ditty-input--' . $this->type . '--inline';
45
+ }
46
+ $atts = array(
47
+ 'class' => 'ditty-field__input ditty-input--' . $this->type . $extra_classes,
48
+ 'role' => 'radiogroup',
49
+ );
50
+ if ( '' != $this->args['baseid'] ) {
51
+ $atts['data-baseid'] = $this->args['baseid'];
52
+ }
53
+
54
+ $html .= '<div ' . ditty_attr_to_html( $atts ) . '>';
55
+ $html .= $this->input_actions();
56
+ $html .= $this->input_before();
57
+ $html .= '<span class="ditty-field__input__primary">' . $this->input( $name, $std ) . '</span>';
58
+ $html .= $this->input_after();
59
+ $html .= $this->input_description();
60
+ $html .= '</div>';
61
+ return $html;
62
+ }
63
+
64
+ /**
65
+ * Return the input
66
+ *
67
+ * @since 3.0
68
+ * @return $html string
69
+ */
70
+ public function input( $name, $std = false ) {
71
+ $html = '';
72
+ if ( is_array( $this->args['options'] ) && count( $this->args['options'] ) > 0 ) {
73
+ foreach ( $this->args['options'] as $value => $label ) {
74
+ $input_id = uniqid( 'ditty-input--' );
75
+ $html .= '<span class="ditty-input--radio__option">';
76
+ $sanitized_value = sanitize_text_field( $value );
77
+ $html .= '<input id="' . $input_id . '" name="' . $name . '" type="radio" value="' . $sanitized_value . '" ' . checked( $sanitized_value, $this->args['std'], false ) . ' /> <label for="' . $input_id . '">' . sanitize_text_field( $label ) . '</label>';
78
+ $html .= '</span>';
79
+ }
80
+ }
81
+ return $html;
82
+ }
83
+
84
+ }
includes/fields/ditty-field-radius.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Radius Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Radius
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Radius extends Ditty_Field {
13
+
14
+ public $type = 'radius';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'options' => array(
25
+ 'borderTopLeftRadius' => __( 'Top Left', 'ditty-news-ticker' ),
26
+ 'borderTopRightRadius' => __( 'Top Right', 'ditty-news-ticker' ),
27
+ 'borderBottomLeftRadius' => __( 'Bottom Left', 'ditty-news-ticker' ),
28
+ 'borderBottomRightRadius' => __( 'Bottom Right', 'ditty-news-ticker' ),
29
+ ),
30
+ );
31
+ return wp_parse_args( $atts, $this->common );
32
+ }
33
+
34
+ /**
35
+ * Return the input
36
+ *
37
+ * @since 3.0
38
+ * @return $html string
39
+ */
40
+ public function input( $name, $std = false ) {
41
+
42
+ $inputs = array();
43
+ foreach ( $this->args['options'] as $key => $label ) {
44
+ $value = isset( $std[ $key ] ) ? $std[ $key ] : '';
45
+ $atts = array(
46
+ 'id' => "{$name}[{$key}]",
47
+ 'placeholder' => $label,
48
+ 'std' => $value,
49
+ );
50
+ $input = new Ditty_Field_Text();
51
+ $input->init( $atts );
52
+ $inputs[] = $input->html();
53
+ }
54
+
55
+ $html = '<div class="ditty-input--radius__group">' . implode( ' ', $inputs ) . '</div>';
56
+ return $html;
57
+ }
58
+
59
+ }
includes/fields/ditty-field-select.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Select Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Select
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Select extends Ditty_Field {
13
+
14
+ public $type = 'select';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'options' => array(),
25
+ );
26
+ return wp_parse_args( $atts, $this->common );
27
+ }
28
+
29
+ /**
30
+ * Return an option array
31
+ *
32
+ * @since 3.0
33
+ * @return $html string
34
+ */
35
+ private function render_option( $value, $data, $std = false ) {
36
+ $sanitized_help = false;
37
+ if ( is_array( $data ) ) {
38
+ $sanitized_value = isset( $data['value'] ) ? esc_attr( $data['value'] ) : '';
39
+ $sanitized_label = isset( $data['label'] ) ? sanitize_text_field( $data['label'] ) : '';
40
+ $sanitized_help = isset( $data['help'] ) ? esc_attr( $data['help'] ) : false;
41
+ } else {
42
+ $sanitized_value = esc_attr( $value );
43
+ $sanitized_label = sanitize_text_field( $data );
44
+ }
45
+ $atts = array(
46
+ 'value' => $sanitized_value,
47
+ 'data-help' => $sanitized_help,
48
+ );
49
+ return '<option ' . ditty_attr_to_html( $atts ) . ' ' . selected( $sanitized_value, $std, false ) . '>' . $sanitized_label . '</option>';
50
+ }
51
+
52
+ /**
53
+ * Return a select group
54
+ *
55
+ * @since 3.0
56
+ * @return $html string
57
+ */
58
+ private function render_group( $value, $data, $std = false ) {
59
+ $sanitized_label = isset( $data['label'] ) ? sanitize_text_field( $data['label'] ) : '';
60
+ $html = '';
61
+ $html .= '<optgroup label="' . $sanitized_label . '">';
62
+ if ( is_array( $data['options'] ) && count( $data['options'] ) > 0 ) {
63
+ foreach ( $data['options'] as $sub_value => $sub_data ) {
64
+ $html .= $this->render_option( $sub_value, $sub_data, $std );
65
+ }
66
+ }
67
+ $html .= '</optgroup>';
68
+ return $html;
69
+ }
70
+
71
+ /**
72
+ * Return the input
73
+ *
74
+ * @since 3.0
75
+ * @return $html string
76
+ */
77
+ public function input( $name, $std = false ) {
78
+ $html = '';
79
+ $placeholder = ( '' != $this->args['placeholder'] ) ? $this->args['placeholder'] : false;
80
+ $html .= '<select name="' . $name . '">';
81
+ if ( is_array( $this->args['options'] ) && count( $this->args['options'] ) > 0 ) {
82
+ if ( $placeholder ) {
83
+ $html .= '<option value="">' . $placeholder . '</option>';
84
+ }
85
+ foreach ( $this->args['options'] as $value => $data ) {
86
+ if ( is_array( $data ) && isset( $data['group'] ) ) {
87
+ $html .= $this->render_group( $value, $data, $std );
88
+ } else {
89
+ $html .= $this->render_option( $value, $data, $std );
90
+ }
91
+
92
+ // echo '<optgroup label="'.$i.'">';
93
+ // foreach( $option as $e=>$suboption ) {
94
+ // $html .= mtphr_dnt_select_help( $suboption );
95
+ // $v = $option_keys ? $e : $data['label'];
96
+ // $html .= '<option value="'.$v.'" '.selected($v, $value, false).''.$data['help'].'>'.$data['label'].'</option>';
97
+ // }
98
+ // $html .= '</optgroup>';
99
+ // } else {
100
+ // $sanitized_value = sanitize_text_field( $value );
101
+ // $html .= '<option value="' . $sanitized_value . '" ' . selected( $sanitized_value, $std, false ) . '>' . sanitize_text_field( $data ) . '</option>';
102
+ // }
103
+ }
104
+ }
105
+ $html .= '</select>';
106
+ return $html;
107
+ }
108
+
109
+ }
includes/fields/ditty-field-slider.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Slider Field Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Slider
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Slider extends Ditty_Field {
13
+
14
+ public $type = 'slider';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'js_options' => array(),
25
+ );
26
+ return wp_parse_args( $atts, $this->common );
27
+ }
28
+
29
+ /**
30
+ * Return the default atts
31
+ *
32
+ * @access private
33
+ * @since 3.0
34
+ */
35
+ private function attributes() {
36
+ $atts = array();
37
+ if ( is_array( $this->args['js_options'] ) && count( $this->args['js_options'] ) > 0 ) {
38
+ foreach ( $this->args['js_options'] as $option => $value ) {
39
+ $atts["data-{$option}"] = $value;
40
+ }
41
+ }
42
+ return $atts;
43
+ }
44
+
45
+ /**
46
+ * Return the input
47
+ *
48
+ * @since 3.0
49
+ * @return $html string
50
+ */
51
+ public function input( $name, $std = false ) {
52
+ $html = '';
53
+ $html .= '<input name="' . $name . '" type="text" value="' . $std . '" ' . ditty_attr_to_html( $this->attributes() ) . ' />';
54
+ return $html;
55
+ }
56
+ }
includes/fields/ditty-field-spacing.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Spacing Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Spacing
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Spacing extends Ditty_Field {
13
+
14
+ public $type = 'spacing';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'options' => array(
25
+ 'paddingTop' => __( 'Top', 'ditty-news-ticker' ),
26
+ 'paddingBottom' => __( 'Bottom', 'ditty-news-ticker' ),
27
+ 'paddingLeft' => __( 'Left', 'ditty-news-ticker' ),
28
+ 'paddingRight' => __( 'Right', 'ditty-news-ticker' ),
29
+ ),
30
+ );
31
+ return wp_parse_args( $atts, $this->common );
32
+ }
33
+
34
+ /**
35
+ * Return the input
36
+ *
37
+ * @since 3.0
38
+ * @return $html string
39
+ */
40
+ public function input( $name, $std = false ) {
41
+
42
+ $inputs = array();
43
+
44
+ foreach ( $this->args['options'] as $key => $label ) {
45
+ $value = isset( $std[ $key ] ) ? $std[ $key ] : '';
46
+ $atts = array(
47
+ 'id' => "{$name}[{$key}]",
48
+ 'placeholder' => $label,
49
+ 'std' => $value,
50
+ );
51
+ $input = new Ditty_Field_Text();
52
+ $input->init( $atts );
53
+ $inputs[] = $input->html();
54
+ }
55
+
56
+ $html = '<div class="ditty-input--spacing__group">' . implode( ' ', $inputs ) . '</div>';
57
+ return $html;
58
+ }
59
+
60
+ }
includes/fields/ditty-field-text.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Text Field Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Text
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Text extends Ditty_Field {
13
+ public $type = 'text';
14
+ }
includes/fields/ditty-field-textarea.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Textarea Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Textarea
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Textarea extends Ditty_Field {
13
+
14
+ public $type = 'textarea';
15
+
16
+ /**
17
+ * Return the default atts
18
+ *
19
+ * @access private
20
+ * @since 3.0
21
+ */
22
+ public function defaults() {
23
+ $atts = array(
24
+ 'cols' => 60,
25
+ 'rows' => 4,
26
+ );
27
+ return wp_parse_args( $atts, $this->common );
28
+ }
29
+
30
+ /**
31
+ * Return the input
32
+ *
33
+ * @since 3.0
34
+ * @return $html string
35
+ */
36
+ public function input( $name, $std = false ) {
37
+ $html = '';
38
+ $placeholder = ( '' != $this->args['placeholder'] ) ? ' placeholder="' . sanitize_text_field( $this->args['placeholder'] ) . '"' : false;
39
+ $html .= '<textarea name="' . $name . '"' . $placeholder . '>' . $std . '</textarea>';
40
+ return $html;
41
+ }
42
+
43
+ }
includes/fields/ditty-field-wysiwyg.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Ditty_Field_Wysiwyg Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field Ditty_Field_Wysiwyg
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field_Wysiwyg extends Ditty_Field {
13
+
14
+ public $type = 'wysiwyg';
15
+
16
+ /**
17
+ * Return the input
18
+ *
19
+ * @since 3.0
20
+ * @return $html string
21
+ */
22
+ public function input( $name, $std = '' ) {
23
+
24
+ if ( ! is_string( $std ) ) {
25
+ $std = '';
26
+ }
27
+
28
+ wp_enqueue_editor();
29
+ $settings = array(
30
+ 'textarea_name' => $name,
31
+ 'textarea_rows' => 10,
32
+ 'media_buttons' => false,
33
+ 'teeny' => true,
34
+ );
35
+ ob_start();
36
+ wp_editor( stripslashes( $std ), uniqid( 'ditty-input--' ), $settings );
37
+ return ob_get_clean();
38
+ }
39
+
40
+ }
includes/fields/ditty-field.php ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Ditty Field Class
5
+ *
6
+ * @package Ditty
7
+ * @subpackage Classes/Ditty Field
8
+ * @copyright Copyright (c) 2020, Metaphor Creations
9
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
+ * @since 3.0
11
+ */
12
+ class Ditty_Field {
13
+
14
+ public $type = 'text';
15
+ public $args = array();
16
+ public $common = array();
17
+
18
+ /**
19
+ * Get things started
20
+ * @access public
21
+ * @since 3.0
22
+ */
23
+ public function __construct() {
24
+ $this->common = array(
25
+ 'id' => '',
26
+ 'baseid' => '',
27
+ 'name' => '',
28
+ 'desc' => '',
29
+ 'input_desc' => '',
30
+ 'placeholder' => '',
31
+ 'before' => '',
32
+ 'after' => '',
33
+ 'help' => '',
34
+ 'class' => '',
35
+ 'input_class' => '',
36
+ 'clone' => false,
37
+ 'clone_button' => __( 'Add More', 'ditty-news-ticker' ),
38
+ 'max_clone' => 0,
39
+ 'field_only' => false,
40
+ 'std' => '',
41
+ 'atts' => array(),
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Initialize the field
47
+ * @access public
48
+ * @since 3.0
49
+ */
50
+ public function init( $args ) {
51
+ $this->args = wp_parse_args( $args, $this->defaults() );
52
+ }
53
+
54
+ /**
55
+ * Return the default atts
56
+ *
57
+ * @access private
58
+ * @since 3.0
59
+ */
60
+ public function defaults() {
61
+ return $this->common;
62
+ }
63
+
64
+ /**
65
+ * Sanitize field IDs
66
+ *
67
+ * @access private
68
+ * @since 3.0
69
+ */
70
+ public function sanitize_id( $id ) {
71
+ $id = str_replace( '[', '--', $id );
72
+ $id = str_replace( ']', '', $id );
73
+ return $id;
74
+ }
75
+
76
+ /**
77
+ * Return the html attributes
78
+ *
79
+ * @since 3.0
80
+ * @return $html string
81
+ */
82
+ public function html_atts() {
83
+ $id = $this->sanitize_id( $this->args['id'] );
84
+ $classes = 'ditty-field ditty-field-type--' . $this->type . ' ' . $this->sanitize_id( 'ditty-field--' . $id );
85
+ $classes .= ( '' != $this->args['baseid'] ) ? ' ditty-field--' . esc_attr( $this->args['baseid'] ) : '';
86
+ $classes .= ( '' != $this->args['class'] ) ? ' ' . esc_attr( $this->args['class'] ) : '';
87
+ $classes .= ( $this->args['clone'] ) ? ' ditty-field--clone-enabled' : '';
88
+
89
+ $atts = array(
90
+ 'class' => $classes,
91
+ );
92
+ if ( $this->args['clone'] ) {
93
+ $atts['data-clone_name'] = $this->args['id'];
94
+ $atts['data-clone_args'] = htmlentities( json_encode( $this->args ) );
95
+ $atts['data-clone_field'] = htmlentities( $this->input_wrap( $this->args['id'], false, 'clone' ) );
96
+ $atts['data-clone_max' ] = intval( $this->args['max_clone'] );
97
+ }
98
+ return $atts;
99
+ }
100
+
101
+ /**
102
+ * Return the html
103
+ *
104
+ * @since 3.0
105
+ * @return $html string
106
+ */
107
+ public function html() {
108
+ $html = '';
109
+ if ( $this->args['field_only'] ) {
110
+ $html .= $this->input( $this->args['id'] );
111
+ } else {
112
+ $html .= '<div ' . ditty_attr_to_html( $this->html_atts() ) . '>';
113
+ if ( '' != $this->label() || '' != $this->description() ) {
114
+ $html .= '<div class="ditty-field__heading">';
115
+ $html .= $this->label();
116
+ $html .= $this->description();
117
+ $html .= '</div>';
118
+ }
119
+ $html .= $this->input_container();
120
+ $html .= '</div>';
121
+ }
122
+ return $html;
123
+ }
124
+
125
+ /**
126
+ * Return the label
127
+ *
128
+ * @since 3.0
129
+ * @return $html string
130
+ */
131
+ public function label() {
132
+ $html = '';
133
+ if ( '' != $this->args['name'] || '' != $this->args['help'] ) {
134
+ $html .= '<label class="ditty-field__label">';
135
+ if ( '' != $this->args['name'] ) {
136
+ $add_space = true;
137
+ $html .= wp_kses_post( $this->args['name'] );
138
+ }
139
+ if ( '' != $this->args['help'] ) {
140
+ if ( '' != $this->args['name'] ) {
141
+ $html .= ' ';
142
+ }
143
+ $html .= '<i class="ditty-help-icon protip fas fa-question-circle" data-pt-title="' . sanitize_text_field( $this->args['help'] ) . '"></i>';
144
+ }
145
+ $html .= '</label>';
146
+ }
147
+ return $html;
148
+ }
149
+
150
+ /**
151
+ * Return the description
152
+ *
153
+ * @since 3.0
154
+ * @return $html string
155
+ */
156
+ public function description() {
157
+ $html = '';
158
+ if ( '' != $this->args['desc'] ) {
159
+ $html .= '<p class="ditty-field__description">';
160
+ $html .= wp_kses_post( $this->args['desc'] );
161
+ $html .= '</p>';
162
+ }
163
+ return $html;
164
+ }
165
+
166
+ /**
167
+ * Return the input description
168
+ *
169
+ * @since 3.0
170
+ * @return $html string
171
+ */
172
+ public function input_description() {
173
+ $html = '';
174
+ if ( '' != $this->args['input_desc'] ) {
175
+ $html .= '<p class="ditty-field__input__description">';
176
+ $html .= wp_kses_post( $this->args['input_desc'] );
177
+ $html .= '</p>';
178
+ }
179
+ return $html;
180
+ }
181
+
182
+ /**
183
+ * Return the input container
184
+ *
185
+ * @since 3.0
186
+ * @return $html string
187
+ */
188
+ public function input_container() {
189
+ $html = '';
190
+ $html .= '<div class="ditty-field__input__container">';
191
+ if ( $this->args['clone'] ) {
192
+ if ( is_array( $this->args['std'] ) && count( $this->args['std'] ) > 0 ) {
193
+ foreach ( $this->args['std'] as $i => $std ) {
194
+ $html .= $this->input_wrap( "{$this->args['id']}[{$i}]", $std );
195
+ }
196
+ } else {
197
+ $html .= $this->input_wrap( "{$this->args['id']}[0]" );
198
+ }
199
+ $html .= '<div class="ditty-field__actions">';
200
+ $html .= '<a href="#" class="ditty-button ditty-button--primary ditty-field__actions__clone">' . sanitize_text_field( $this->args['clone_button'] ) . '</a>';
201
+ $html .= '</div>';
202
+ } else {
203
+ $html .= $this->input_wrap( $this->args['id'], $this->args['std'] );
204
+ }
205
+ $html .= '</div>';
206
+ return $html;
207
+ }
208
+
209
+ /**
210
+ * Return the input actions
211
+ *
212
+ * @since 3.0
213
+ * @return $html string
214
+ */
215
+ public function input_actions() {
216
+ $html = '';
217
+
218
+ if ( $this->args['clone'] ) {
219
+ $html .= '<div class="ditty-field__input__actions">';
220
+ $html .= '<a href="#" class="ditty-field__input__action--arrange protip" data-pt-title="' . __( 'Re-arrange', 'ditty-news-ticker' ) . '"><i class="fas fa-bars" data-class="fas fa-bars"></i></a>';
221
+ $html .= '<a href="#" class="ditty-field__input__action--remove protip" data-pt-title="' . __( 'Delete', 'ditty-news-ticker' ) . '"><i class="fas fa-minus-circle" data-class="fas fa-minus-circle"></i></a>';
222
+ $html .= '<a href="#" class="ditty-field__input__action--add protip" data-pt-title="' . __( 'Add', 'ditty-news-ticker' ) . '"><i class="fas fa-plus-circle" data-class="fas fa-plus-circle"></i></a>';
223
+ $html .= '<a href="#" class="ditty-field__input__action--clone protip" data-pt-title="' . __( 'Clone', 'ditty-news-ticker' ) . '"><i class="fas fa-clone" data-class="fas fa-clone"></i></a>';
224
+ $html .= '</div>';
225
+ }
226
+
227
+ return $html;
228
+ }
229
+
230
+ /**
231
+ * Return a single input
232
+ *
233
+ * @since 3.0
234
+ * @return $html string
235
+ */
236
+ public function input_wrap( $name, $std = false, $clone = 'orig' ) {
237
+ $html = '';
238
+
239
+ $extra_classes = '';
240
+ if ( $this->args['clone'] ) {
241
+ $extra_classes .= ' ditty-input--clone ditty-input--clone--' . $clone;
242
+ }
243
+ $atts = array(
244
+ 'class' => 'ditty-field__input ditty-input--' . $this->type . $extra_classes,
245
+ );
246
+ if ( '' != $this->args['baseid'] ) {
247
+ $atts['data-baseid'] = $this->args['baseid'];
248
+ }
249
+
250
+ $html .= '<div ' . ditty_attr_to_html( $atts ) . '>';
251
+ $html .= $this->input_actions();
252
+ $html .= $this->input_before();
253
+ $html .= '<span class="ditty-field__input__primary">' . $this->input( $name, $std ) . '</span>';
254
+ $html .= $this->input_after();
255
+ $html .= $this->input_description();
256
+ $html .= '</div>';
257
+ return $html;
258
+ }
259
+
260
+ /**
261
+ * Return the input before
262
+ *
263
+ * @since 3.0
264
+ * @return $html string
265
+ */
266
+ public function input_before() {
267
+ $html = '';
268
+ if ( $this->args['before'] ) {
269
+ $html = '<span class="ditty-field__input__before">' . $this->args['before'] . '</span>';
270
+ }
271
+ return $html;
272
+ }
273
+
274
+ /**
275
+ * Return the input after
276
+ *
277
+ * @since 3.0
278
+ * @return $html string
279
+ */
280
+ public function input_after() {
281
+ $html = '';
282
+ if ( $this->args['after'] ) {
283
+ $html = '<span class="ditty-field__input__after">' . $this->args['after'] . '</span>';
284
+ }
285
+ return $html;
286
+ }
287
+
288
+ /**
289
+ * Return the input
290
+ *
291
+ * @since 3.0
292
+ * @return $html string
293
+ */
294
+ public function input( $name, $std = false ) {
295
+ $html = '';
296
+
297
+ $atts = array(
298
+ 'name' => $name,
299
+ 'type' => 'text',
300
+ 'class' => ( $this->args['input_class'] ) ? $this->args['input_class'] : false,
301
+ 'placeholder' => ( $this->args['placeholder'] ) ? $this->args['placeholder'] : false,
302
+ 'value' => $std,
303
+ );
304
+ if ( is_array( $this->args['atts'] ) && count( $this->args['atts'] ) > 0 ) {
305
+ foreach ( $this->args['atts'] as $key => $value ) {
306
+ $atts[$key] = $value;
307
+ }
308
+ }
309
+ $html .= '<input ' . ditty_attr_to_html( $atts ) . ' />';
310
+ return $html;
311
+ }
312
+
313
+ }
includes/fields/helpers.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Display a field
5
+ *
6
+ * @access public
7
+ * @since 3.0
8
+ */
9
+ function ditty_field( $args = array() ) {
10
+ if ( ! isset( $args['type'] ) ) {
11
+ return '<div class="ditty-field ditty-field--error"><i class="fas fa-exclamation-circle"></i>' . __( 'No field type specified.', 'ditty-news-ticker' ) . '</div>';
12
+ }
13
+ $type = ucfirst( $args['type'] );
14
+ $class_name = "Ditty_Field_{$type}";
15
+ if ( ! class_exists( $class_name ) ) {
16
+ return '<div class="ditty-field ditty-field--error"><i class="fas fa-exclamation-circle"></i> ' . sprintf( __( '%s class does not exists.', 'ditty-news-ticker' ), $class_name ) . '</div>';
17
+ }
18
+ $class = new $class_name;
19
+
20
+ $class->init( $args );
21
+ return $class->html();
22
+ }
23
+
24
+ /**
25
+ * Display multiple fields
26
+ *
27
+ * @access public
28
+ * @since 3.0
29
+ */
30
+ function ditty_fields( $fields = array(), $values = array(), $action = 'render' ) {
31
+ if ( is_array( $fields ) && count( $fields ) > 0 ) {
32
+ foreach ( $fields as &$field ) {
33
+ if ( isset( $values[$field['id']] ) ) {
34
+ $field['std'] = $values[$field['id']];
35
+ }
36
+
37
+ if ( 'return' == $action ) {
38
+ return ditty_field( $field );
39
+ } else {
40
+ echo ditty_field( $field );
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Sanitize an input
48
+ *
49
+ * @access public
50
+ * @since 3.0
51
+ */
52
+ function ditty_sanitize_input( $field, $value ) {
53
+ $sanitize_type = isset( $field['sanitize'] ) ? $field['sanitize'] : $field['type'];
54
+ $sanitized_value = false;
55
+ switch( $sanitize_type ) {
56
+ case 'attr':
57
+ $sanitized_value = esc_attr( $value );
58
+ break;
59
+ case 'email':
60
+ if ( is_email( $value ) ) {
61
+ $sanitized_value = sanitize_text_field( $value );
62
+ } else {
63
+ $sanitized_value = false;
64
+ }
65
+ break;
66
+ case 'number':
67
+ $sanitized_value = intval( $value );
68
+ break;
69
+ case 'spacing':
70
+ case 'radius':
71
+ case 'checkboxes':
72
+ if ( is_array( $value ) && count( $value ) > 0 ) {
73
+ foreach ( $value as $key => $val ) {
74
+ $sanitized_value[$key] = sanitize_text_field( $val );
75
+ }
76
+ }
77
+ break;
78
+ case 'checkbox':
79
+ case 'radio':
80
+ case 'slider':
81
+ case 'text':
82
+ $sanitized_value = sanitize_text_field( $value );
83
+ break;
84
+ case 'url':
85
+ $sanitized_value = esc_url_raw( $value );
86
+ break;
87
+ default:
88
+ $sanitized_value = wp_kses_post( $value );
89
+ break;
90
+ }
91
+ return $sanitized_value;
92
+ }
93
+
94
+ /**
95
+ * Sanitize group field
96
+ *
97
+ * @access public
98
+ * @since 3.0
99
+ */
100
+ function ditty_sanitize_group( $group = array(), $values = array() ) {
101
+ $sanitized_values = array();
102
+ if ( isset( $group['fields'] ) && is_array( $group['fields'] ) && count( $group['fields'] ) > 0 ) {
103
+ foreach ( $group['fields'] as $field ) {
104
+ if ( ! isset( $values[$field['id']] ) ) {
105
+ continue;
106
+ }
107
+ $sanitized_values[$field['id']] = ditty_sanitize_input( $field, $values[$field['id']] );
108
+ }
109
+ }
110
+ return $sanitized_values;
111
+ }
112
+
113
+ /**
114
+ * Sanitize clone field
115
+ *
116
+ * @access public
117
+ * @since 3.0
118
+ */
119
+ function ditty_sanitize_clone( $field = array(), $values = array() ) {
120
+ $sanitized_values = array();
121
+ if ( is_array( $values ) && count( $values ) > 0 ) {
122
+ foreach ( $values as $index => $value ) {
123
+ if( 'group' == $field['type'] ) {
124
+ $sanitized_value = ditty_sanitize_group( $field, $value );
125
+ } else {
126
+ $sanitized_value = ditty_sanitize_input( $field, $value );
127
+ }
128
+ if ( $sanitized_value ) {
129
+ $sanitized_values[$index] = $sanitized_value;
130
+ }
131
+ }
132
+ }
133
+ return $sanitized_values;
134
+ }
135
+
136
+ /**
137
+ * Sanitize a single fields
138
+ *
139
+ * @access public
140
+ * @since 3.0
141
+ */
142
+ function ditty_sanitize_field( $field = array(), $values = array() ) {
143
+ $sanitized_value = false;
144
+ if ( isset( $field['clone'] ) && true == $field['clone'] ) {
145
+ $sanitized_value = ditty_sanitize_clone( $field, $values );
146
+ } elseif( 'group' == $field['type'] ) {
147
+ $sanitized_value = ditty_sanitize_group( $field, $values );
148
+ } else {
149
+ $sanitized_value = ditty_sanitize_input( $field, $values );
150
+ }
151
+ return $sanitized_value;
152
+ }
153
+
154
+ /**
155
+ * Sanitize fields
156
+ *
157
+ * @access public
158
+ * @since 3.0
159
+ */
160
+ function ditty_sanitize_fields( $fields = array(), $values = array(), $id = '' ) {
161
+ $sanitized_values = array();
162
+ if ( is_array( $fields ) && count( $fields ) > 0 ) {
163
+ foreach ( $fields as $field ) {
164
+ if ( 'group' == $field['type'] && isset( $field['multiple_fields'] ) && true == $field['multiple_fields'] ) {
165
+ if ( isset( $field['fields'] ) && is_array( $field['fields'] ) && count( $field['fields'] ) > 0 ) {
166
+ foreach ( $field['fields'] as $group_field ) {
167
+ if ( ! isset( $values[$group_field['id']] ) ) {
168
+ continue;
169
+ }
170
+ $sanitized_values[$group_field['id']] = ditty_sanitize_field( $group_field, $values[$group_field['id']] );
171
+ }
172
+ }
173
+ } else {
174
+ if ( ! isset( $values[$field['id']] ) ) {
175
+ continue;
176
+ }
177
+ $sanitized_values[$field['id']] = ditty_sanitize_field( $field, $values[$field['id']] );
178
+ }
179
+ }
180
+ }
181
+ return apply_filters( 'ditty_sanitize_fields', $sanitized_values, $fields, $values, $id );
182
+ }
includes/fields/js/ditty-fields.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* //global dittyVars:true */
3
+ /* //global console:true */
4
+
5
+ // @codekit-append 'fields/clone.js
6
+ // @codekit-append 'fields/code.js
7
+ // @codekit-append 'fields/color.js
8
+ // @codekit-append 'fields/date.js
9
+ // @codekit-append 'fields/image.js
10
+ // @codekit-append 'fields/slider.js
11
+ // @codekit-append 'fields/wysiwyg.js
12
+ // @codekit-append 'fields/group.js
includes/fields/js/ditty-fields.min.js ADDED
@@ -0,0 +1,563 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* //global dittyVars:true */
3
+ /* //global console:true */
4
+
5
+ // @codekit-append 'fields/clone.js
6
+ // @codekit-append 'fields/code.js
7
+ // @codekit-append 'fields/color.js
8
+ // @codekit-append 'fields/date.js
9
+ // @codekit-append 'fields/image.js
10
+ // @codekit-append 'fields/slider.js
11
+ // @codekit-append 'fields/wysiwyg.js
12
+ // @codekit-append 'fields/group.js
13
+
14
+ jQuery( document ).ready( function( $ ) {
15
+
16
+ // Setup strict mode
17
+ (function() {
18
+
19
+ "use strict";
20
+
21
+ function setup( $field ) {
22
+
23
+ // Setup protip
24
+ $.protip( {
25
+ defaults: {
26
+ position: 'top',
27
+ size: 'small',
28
+ scheme: 'black',
29
+ classes: 'ditty-protip'
30
+ }
31
+ } );
32
+
33
+ var $inputContainer = $field.children( '.ditty-field__input__container' );
34
+
35
+ $field.addClass( 'ditty-field--clone-enabled--init' );
36
+ $field.data( 'input_count', $inputContainer.children( '.ditty-field__input' ).length );
37
+
38
+ $inputContainer.children( '.ditty-field__input' ).each( function() {
39
+ setupButtons( $field, $( this ) );
40
+ } );
41
+
42
+ $field.find( '.ditty-field__actions__clone' ).on( 'click', function( e ) {
43
+ e.preventDefault();
44
+ var $input = $inputContainer.children( '.ditty-field__input' ).last();
45
+ addInput( $field, $input );
46
+ } );
47
+
48
+ $inputContainer.sortable( {
49
+ handle: '.ditty-field__input__action--arrange',
50
+ items: '> .ditty-field__input',
51
+ axis: 'y',
52
+ start: function( event, ui ) {
53
+ var $item = $( ui.item );
54
+ $item.addClass( 'ditty-field__input--moving' );
55
+ },
56
+ stop: function( event, ui ) {
57
+ var $item = $( ui.item );
58
+ $item.removeClass( 'ditty-field__input--moving' );
59
+ },
60
+ update: function() {
61
+ updateField( $field );
62
+ }
63
+ } );
64
+ }
65
+
66
+ /**
67
+ * Update the field class and input names
68
+ *
69
+ * @since 3.0
70
+ * @return null
71
+ */
72
+ function updateField( $field ) {
73
+ var $inputContainer = $field.children( '.ditty-field__input__container' ),
74
+ cloneName = $field.data( 'clone_name' ),
75
+ cloneMax = $field.data( 'clone_max' ),
76
+ fieldData = [];
77
+
78
+ $inputContainer.children( '.ditty-field__input' ).each( function( index ) {
79
+ var $input = $( this );
80
+ $input.find( ':input' ).each( function() {
81
+ var baseId = $( this ).parents( '.ditty-field__input' ).data( 'baseid' ),
82
+ fieldName;
83
+
84
+ if ( baseId ) {
85
+ fieldName = cloneName + '[' + index + '][' + baseId + ']';
86
+ //$( this ).attr( 'name', cloneName + '[' + index + '][' + baseId + ']' );
87
+ } else {
88
+ fieldName = cloneName + '[' + index + ']';
89
+ //$( this ).attr( 'name', cloneName + '[' + index + ']' );
90
+ }
91
+ $( this ).attr( 'name', fieldName );
92
+ fieldData.push( {
93
+ name : fieldName,
94
+ value : $(this).val()
95
+ } );
96
+ } );
97
+ } );
98
+ $field.data( 'input_count', $inputContainer.children( '.ditty-field__input' ).length );
99
+
100
+ if ( cloneMax > 0 && $inputContainer.children( '.ditty-field__input' ).length >= cloneMax ) {
101
+ $field.addClass( 'ditty-field--clone-enabled--max' );
102
+ } else {
103
+ $field.removeClass( 'ditty-field--clone-enabled--max' );
104
+ }
105
+
106
+ $field.trigger( 'ditty_field_update' );
107
+ $field.trigger( 'ditty_field_clone_update', [fieldData, cloneName] );
108
+ }
109
+
110
+ /**
111
+ * Add a new clone input
112
+ *
113
+ * @since 3.0
114
+ * @return null
115
+ */
116
+ function addInput( $field, $input, cloneField ) {
117
+ cloneField = cloneField ? cloneField : $field.data( 'clone_field' );
118
+
119
+ var $clone = $( cloneField );
120
+
121
+ $input.after( $clone );
122
+
123
+ updateField( $field );
124
+ setupButtons( $field, $clone );
125
+
126
+ $field.trigger( 'ditty_init_fields' );
127
+ }
128
+
129
+ /**
130
+ * Setup clone buttons
131
+ *
132
+ * @since 3.0
133
+ * @return null
134
+ */
135
+ function setupButtons( $field, $input ) {
136
+ var $remove = $input.find( '.ditty-field__input__action--remove' ),
137
+ $add = $input.find( '.ditty-field__input__action--add' ),
138
+ $clone = $input.find( '.ditty-field__input__action--clone' );
139
+
140
+ $remove.on( 'click', function( e ) {
141
+ e.preventDefault();
142
+ $( this ).protipHide();
143
+ if ( 1 === $input.siblings().length ) {
144
+ addInput( $field, $input );
145
+ }
146
+ $input.remove();
147
+ updateField( $field );
148
+ //$( 'body' ).trigger( 'ditty_enable_settings_update' );
149
+ } );
150
+
151
+ $add.on( 'click', function( e ) {
152
+ e.preventDefault();
153
+ addInput( $field, $input );
154
+ //$( 'body' ).trigger( 'ditty_enable_settings_update' );
155
+ } );
156
+
157
+ $clone.on( 'click', function( e ) {
158
+ e.preventDefault();
159
+ addInput( $field, $input, $input.clone() );
160
+ //$( 'body' ).trigger( 'ditty_enable_settings_update' );
161
+ } );
162
+ }
163
+
164
+ function init( e ) {
165
+ $( e.target ).find( '.ditty-field--clone-enabled:not(.ditty-field--clone-enabled--init)' ).each( function() {
166
+ setup( $( this ) );
167
+ } );
168
+ }
169
+ $( document ).on( 'ditty_init_fields', init );
170
+
171
+ }() );
172
+
173
+ } );
174
+
175
+ /* global _:true */
176
+
177
+ jQuery( document ).ready( function( $ ) {
178
+
179
+ // Setup strict mode
180
+ (function() {
181
+
182
+ "use strict";
183
+
184
+ function setup( $field ) {
185
+ $field.addClass( 'ditty-input--code--init' );
186
+
187
+ var $textarea = $field.find( 'textarea' ),
188
+ codeEditor = null,
189
+ codeEditorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
190
+
191
+ codeEditorSettings.codemirror = _.extend(
192
+ {},
193
+ codeEditorSettings.codemirror,
194
+ {
195
+ mode : $textarea.data( 'mode' ) ? $textarea.data( 'mode' ) : null,
196
+ indentUnit : 2,
197
+ tabSize : 2
198
+ }
199
+ );
200
+ codeEditor = wp.codeEditor.initialize( $textarea[0], codeEditorSettings );
201
+ }
202
+
203
+ function init( e ) {
204
+ $( e.target ).find( '.ditty-input--code:not(.ditty-input--code--init)' ).each( function() {
205
+ setup( $( this ) );
206
+ } );
207
+ }
208
+ $( document ).on( 'ditty_init_fields', init );
209
+
210
+ }() );
211
+
212
+ } );
213
+
214
+ jQuery( document ).ready( function( $ ) {
215
+
216
+ // Setup strict mode
217
+ (function() {
218
+
219
+ "use strict";
220
+
221
+ function setup( $field ) {
222
+ $field.addClass( 'ditty-input--color--init' );
223
+ $field.find( 'input[type="text"]' ).minicolors( {
224
+ format: 'rgb',
225
+ opacity: true
226
+ } );
227
+ }
228
+
229
+ function init( e ) {
230
+ $( e.target ).find( '.ditty-input--color:not(.ditty-input--color--init)' ).each( function() {
231
+ setup( $( this ) );
232
+ } );
233
+ }
234
+ $( document ).on( 'ditty_init_fields', init );
235
+
236
+ }() );
237
+
238
+ } );
239
+
240
+ jQuery( document ).ready( function( $ ) {
241
+
242
+ // Setup strict mode
243
+ (function() {
244
+
245
+ "use strict";
246
+
247
+ function setup( $field ) {
248
+ var format = $field.find( 'input[type="text"]' ).data( 'dateformat' );
249
+ $field.find( 'input[type="text"]' ).datepicker( {
250
+ dateFormat: format
251
+ } );
252
+ }
253
+
254
+ function init( e ) {
255
+ $( e.target ).find( '.ditty-input--date' ).each( function() {
256
+ setup( $( this ) );
257
+ } );
258
+ }
259
+ $( document ).on( 'ditty_init_fields', init );
260
+
261
+ }() );
262
+
263
+ } );
264
+
265
+ jQuery( document ).ready( function( $ ) {
266
+
267
+ // Setup strict mode
268
+ (function() {
269
+
270
+ "use strict";
271
+
272
+ function setup( $field ) {
273
+ $field.addClass( 'ditty-input--image--init' );
274
+
275
+ var $input = $field.find( 'input[type="hidden"]' ),
276
+ $preview = $field.find( '.ditty-input--image__preview' ),
277
+ $preview_img = $preview.children( 'img' ),
278
+ uploader;
279
+
280
+ $field.on( 'click', '.ditty-input--image__upload', function( e ) {
281
+ e.preventDefault();
282
+
283
+ if ( undefined === uploader ) {
284
+ uploader = wp.media({
285
+ title: $input.data( 'media_title' ),
286
+ button: { text: $input.data( 'media_button' ), size: 'small' },
287
+ multiple: $input.data( 'multiple' ),
288
+ library : {
289
+ type : 'image'
290
+ }
291
+ } );
292
+ }
293
+
294
+ uploader.on( 'open', function() {
295
+ var selection = uploader.state().get( 'selection' );
296
+ var attachment = wp.media.attachment( $input.val() );
297
+ if ( attachment ) {
298
+ selection.add( attachment );
299
+ }
300
+ // let ids = [13, 14, 56];
301
+ // ids.forEach(function(id) {
302
+ // let attachment = wp.media.attachment(id);
303
+ // selection.add(attachment ? [attachment] : []);
304
+ // } );
305
+ } );
306
+
307
+ uploader.on( 'select', function() {
308
+ var attachments = uploader.state().get( 'selection' ).toJSON(),
309
+ image_data = [];
310
+
311
+ if ( attachments.length > 0 ) {
312
+ $(attachments).each( function() {
313
+ image_data.push( {
314
+ id : $(this)[0].id,
315
+ title : $(this)[0].title,
316
+ caption : $(this)[0].caption,
317
+ description : $(this)[0].description,
318
+ link : $(this)[0].link,
319
+ url : $(this)[0].sizes.medium ? $(this)[0].sizes.medium.url : $(this)[0].sizes.full.url
320
+ } );
321
+ } );
322
+ }
323
+
324
+ $input.val( image_data[0].id );
325
+ if ( $preview_img.length ) {
326
+ $preview_img.remove();
327
+ }
328
+ $preview_img = $( '<img src="' + image_data[0].url + '" alt="" />' );
329
+ $preview.prepend( $preview_img );
330
+ $preview.find( 'i' ).remove();
331
+
332
+ $field.trigger( 'ditty_field_image_select', [$field, image_data] );
333
+ $field.trigger( 'ditty_field_update' );
334
+ } );
335
+
336
+ uploader.open();
337
+ return false;
338
+
339
+ } );
340
+
341
+ }
342
+
343
+ function init( e ) {
344
+ $( e.target ).find( '.ditty-input--image:not(.ditty-input--image--init)' ).each( function() {
345
+ setup( $( this ) );
346
+ } );
347
+ }
348
+ $( document ).on( 'ditty_init_fields', init );
349
+
350
+ }() );
351
+
352
+ } );
353
+
354
+ jQuery( document ).ready( function( $ ) {
355
+
356
+ // Setup strict mode
357
+ (function() {
358
+
359
+ "use strict";
360
+
361
+ function setup( $field ) {
362
+ $field.addClass( 'ditty-input--slider--init' );
363
+ $field.find( 'input[type="text"]' ).ionRangeSlider();
364
+ }
365
+
366
+ function init( e ) {
367
+ $( e.target ).find( '.ditty-input--slider:not(.ditty-input--slider--init)' ).each( function() {
368
+ setup( $( this ) );
369
+ } );
370
+ }
371
+ $( document ).on( 'ditty_init_fields', init );
372
+
373
+ }() );
374
+
375
+ } );
376
+
377
+ /* global tinyMCEPreInit:true */
378
+ /* global tinymce:true */
379
+ /* global quicktags:true */
380
+ /* global QTags:true */
381
+ /* global wp:true */
382
+
383
+ jQuery( document ).ready( function( $ ) {
384
+
385
+ // Setup strict mode
386
+ (function() {
387
+
388
+ "use strict";
389
+
390
+ /**
391
+ * Transform textarea into wysiwyg editor.
392
+ */
393
+ function transform( $field ) {
394
+
395
+ $field.addClass( 'ditty-input--wysiwyg--init' );
396
+ if ( $field.hasClass( 'ditty-input--clone--clone' ) ) {
397
+ var ranId = Math.floor( ( Math.random() * 100000000 ) + 1 );
398
+ $field.find( 'textarea' ).attr( 'id', 'ditty-input--' + ranId );
399
+ }
400
+
401
+ var $wrapper = $field.find( '.wp-editor-wrap' ),
402
+ id = $field.find( 'textarea' ).attr( 'id' ),
403
+ editor;
404
+
405
+ // Ignore existing editor.
406
+ if ( tinyMCEPreInit.mceInit[id] ) {
407
+ editor = tinymce.get( id );
408
+ editor.on( 'keyup change', function() {
409
+ tinymce.triggerSave();
410
+ $field.trigger( 'ditty_input_wysiwyg_update' );
411
+ } );
412
+ return;
413
+ }
414
+
415
+ var originalId = getOriginalId( $field ),
416
+ settings = getEditorSettings( originalId );
417
+
418
+ updateDom( $wrapper, id );
419
+
420
+ // TinyMCE
421
+ if ( window.tinymce ) {
422
+ tinymce.execCommand( 'mceRemoveEditor', true, id );
423
+ editor = new tinymce.Editor( id, settings.tinymce, tinymce.EditorManager );
424
+ editor.render();
425
+ editor.on( 'keyup change', function() {
426
+ tinymce.triggerSave();
427
+ $field.trigger( 'ditty_input_wysiwyg_update' );
428
+ } );
429
+ }
430
+
431
+ // Quick tags
432
+ if ( window.quicktags ) {
433
+ settings.quicktags.id = id;
434
+ quicktags( settings.quicktags );
435
+ QTags._buttonsInit();
436
+ }
437
+ }
438
+
439
+ function getOriginalId( $clone ) {
440
+ var $original = $clone.siblings( '.ditty-input--wysiwyg.ditty-input--clone--orig' ),
441
+ origingalID = $original.find( 'textarea' ).attr( 'id' );
442
+
443
+ if ( /_\d+$/.test( origingalID ) ) {
444
+ origingalID = origingalID.replace( /_\d+$/, '' );
445
+ }
446
+ if ( tinyMCEPreInit.mceInit.hasOwnProperty( origingalID ) || tinyMCEPreInit.qtInit.hasOwnProperty( origingalID ) ) {
447
+ return origingalID;
448
+ }
449
+ return '';
450
+ }
451
+
452
+ function updateDom( $wrapper, id ) {
453
+ // Wrapper div and media buttons
454
+ $wrapper.attr( 'id', 'wp-' + id + '-wrap' )
455
+ .find( '.mce-container' ).remove().end() // Remove rendered tinyMCE editor
456
+ .find( '.wp-editor-tools' ).attr( 'id', 'wp-' + id + '-editor-tools' )
457
+ .find( '.wp-media-buttons' ).attr( 'id', 'wp-' + id + '-media-buttons' )
458
+ .find( 'button' ).data( 'editor', id ).attr( 'data-editor', id );
459
+
460
+ // Set default active mode.
461
+ $wrapper.removeClass( 'html-active tmce-active' );
462
+ $wrapper.addClass( window.tinymce ? 'tmce-active' : 'html-active' );
463
+
464
+ // Editor tabs
465
+ $wrapper.find( '.switch-tmce' )
466
+ .attr( 'id', id + 'tmce' )
467
+ .data( 'wp-editor-id', id ).attr( 'data-wp-editor-id', id ).end()
468
+ .find( '.switch-html' )
469
+ .attr( 'id', id + 'html' )
470
+ .data( 'wp-editor-id', id ).attr( 'data-wp-editor-id', id );
471
+
472
+ // Quick tags
473
+ $wrapper.find( '.wp-editor-container' ).attr( 'id', 'wp-' + id + '-editor-container' )
474
+ .find( '.quicktags-toolbar' ).attr( 'id', 'qt_' + id + '_toolbar' ).html( '' );
475
+ }
476
+
477
+ function getEditorSettings( id ) {
478
+ var settings = getDefaultEditorSettings();
479
+ if ( id && tinyMCEPreInit.mceInit.hasOwnProperty( id ) ) {
480
+ settings.tinymce = tinyMCEPreInit.mceInit[id];
481
+ }
482
+ if ( id && window.quicktags && tinyMCEPreInit.qtInit.hasOwnProperty( id ) ) {
483
+ settings.quicktags = tinyMCEPreInit.qtInit[id];
484
+ }
485
+ return settings;
486
+ }
487
+
488
+ function getDefaultEditorSettings() {
489
+ var settings = wp.editor.getDefaultSettings();
490
+ settings.tinymce.toolbar1 = 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,wp_more,spellchecker,fullscreen,wp_adv';
491
+ settings.tinymce.toolbar2 = 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help';
492
+ settings.quicktags.buttons = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close';
493
+ return settings;
494
+ }
495
+
496
+ function pre_save( e ) {
497
+ if ( window.tinymce && $( e.target ).find( '.ditty-input--wysiwyg--init .wp-editor-area' ).length ) {
498
+ tinymce.triggerSave();
499
+ }
500
+ }
501
+ $( document ).on( 'ditty_pre_save_fields', pre_save );
502
+
503
+ function init( e ) {
504
+ $( e.target ).find( '.ditty-input--wysiwyg:not(.ditty-input--wysiwyg--init)' ).each( function() {
505
+ transform( $( this ) );
506
+ } );
507
+ }
508
+ $( document ).on( 'ditty_init_fields', init );
509
+
510
+ }() );
511
+
512
+ } );
513
+
514
+ jQuery( document ).ready( function( $ ) {
515
+
516
+ // Setup strict mode
517
+ (function() {
518
+
519
+ "use strict";
520
+
521
+ function setup( $field ) {
522
+ $field.addClass( 'ditty-field-type--group--init' );
523
+
524
+ var $input = $field.children( '.ditty-field__input__container' ).children( '.ditty-input--group' ),
525
+ height = 0;
526
+
527
+ if ( 'collapsed' === $field.attr( 'data-collapsible' ) ) {
528
+ $input.hide();
529
+ }
530
+
531
+ $field.on( 'click', '.ditty-field__collapsible-toggle', function( e ) {
532
+ e.preventDefault();
533
+ if ( 'expanded' === $( this ).parents( '.ditty-field-type--group' ).attr( 'data-collapsible' ) ) {
534
+ $( this ).parents( '.ditty-field-type--group' ).attr( 'data-collapsible', 'collapsed' );
535
+ height = $input.outerHeight();
536
+ $input.stop().animate( {
537
+ marginTop: '-' + height + 'px'
538
+ }, 1000, 'easeInOutQuint', function() {
539
+ $input.hide();
540
+ } );
541
+ } else {
542
+ $( this ).parents( '.ditty-field-type--group' ).attr( 'data-collapsible', 'expanded' );
543
+ height = $input.outerHeight();
544
+ $input.stop().css( 'marginTop', '-' + height + 'px' );
545
+ $input.show();
546
+ $input.stop().animate( {
547
+ marginTop: 0
548
+ }, 1000, 'easeInOutQuint', function() {
549
+ } );
550
+ }
551
+ } );
552
+ }
553
+
554
+ function init( e ) {
555
+ $( e.target ).find( '.ditty-field-type--group[data-collapsible]:not(.ditty-field-type--group--init)' ).each( function() {
556
+ setup( $( this ) );
557
+ } );
558
+ }
559
+ $( document ).on( 'ditty_init_fields', init );
560
+
561
+ }() );
562
+
563
+ } );
includes/fields/js/fields/clone.js ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ function setup( $field ) {
9
+
10
+ // Setup protip
11
+ $.protip( {
12
+ defaults: {
13
+ position: 'top',
14
+ size: 'small',
15
+ scheme: 'black',
16
+ classes: 'ditty-protip'
17
+ }
18
+ } );
19
+
20
+ var $inputContainer = $field.children( '.ditty-field__input__container' );
21
+
22
+ $field.addClass( 'ditty-field--clone-enabled--init' );
23
+ $field.data( 'input_count', $inputContainer.children( '.ditty-field__input' ).length );
24
+
25
+ $inputContainer.children( '.ditty-field__input' ).each( function() {
26
+ setupButtons( $field, $( this ) );
27
+ } );
28
+
29
+ $field.find( '.ditty-field__actions__clone' ).on( 'click', function( e ) {
30
+ e.preventDefault();
31
+ var $input = $inputContainer.children( '.ditty-field__input' ).last();
32
+ addInput( $field, $input );
33
+ } );
34
+
35
+ $inputContainer.sortable( {
36
+ handle: '.ditty-field__input__action--arrange',
37
+ items: '> .ditty-field__input',
38
+ axis: 'y',
39
+ start: function( event, ui ) {
40
+ var $item = $( ui.item );
41
+ $item.addClass( 'ditty-field__input--moving' );
42
+ },
43
+ stop: function( event, ui ) {
44
+ var $item = $( ui.item );
45
+ $item.removeClass( 'ditty-field__input--moving' );
46
+ },
47
+ update: function() {
48
+ updateField( $field );
49
+ }
50
+ } );
51
+ }
52
+
53
+ /**
54
+ * Update the field class and input names
55
+ *
56
+ * @since 3.0
57
+ * @return null
58
+ */
59
+ function updateField( $field ) {
60
+ var $inputContainer = $field.children( '.ditty-field__input__container' ),
61
+ cloneName = $field.data( 'clone_name' ),
62
+ cloneMax = $field.data( 'clone_max' ),
63
+ fieldData = [];
64
+
65
+ $inputContainer.children( '.ditty-field__input' ).each( function( index ) {
66
+ var $input = $( this );
67
+ $input.find( ':input' ).each( function() {
68
+ var baseId = $( this ).parents( '.ditty-field__input' ).data( 'baseid' ),
69
+ fieldName;
70
+
71
+ if ( baseId ) {
72
+ fieldName = cloneName + '[' + index + '][' + baseId + ']';
73
+ //$( this ).attr( 'name', cloneName + '[' + index + '][' + baseId + ']' );
74
+ } else {
75
+ fieldName = cloneName + '[' + index + ']';
76
+ //$( this ).attr( 'name', cloneName + '[' + index + ']' );
77
+ }
78
+ $( this ).attr( 'name', fieldName );
79
+ fieldData.push( {
80
+ name : fieldName,
81
+ value : $(this).val()
82
+ } );
83
+ } );
84
+ } );
85
+ $field.data( 'input_count', $inputContainer.children( '.ditty-field__input' ).length );
86
+
87
+ if ( cloneMax > 0 && $inputContainer.children( '.ditty-field__input' ).length >= cloneMax ) {
88
+ $field.addClass( 'ditty-field--clone-enabled--max' );
89
+ } else {
90
+ $field.removeClass( 'ditty-field--clone-enabled--max' );
91
+ }
92
+
93
+ $field.trigger( 'ditty_field_update' );
94
+ $field.trigger( 'ditty_field_clone_update', [fieldData, cloneName] );
95
+ }
96
+
97
+ /**
98
+ * Add a new clone input
99
+ *
100
+ * @since 3.0
101
+ * @return null
102
+ */
103
+ function addInput( $field, $input, cloneField ) {
104
+ cloneField = cloneField ? cloneField : $field.data( 'clone_field' );
105
+
106
+ var $clone = $( cloneField );
107
+
108
+ $input.after( $clone );
109
+
110
+ updateField( $field );
111
+ setupButtons( $field, $clone );
112
+
113
+ $field.trigger( 'ditty_init_fields' );
114
+ }
115
+
116
+ /**
117
+ * Setup clone buttons
118
+ *
119
+ * @since 3.0
120
+ * @return null
121
+ */
122
+ function setupButtons( $field, $input ) {
123
+ var $remove = $input.find( '.ditty-field__input__action--remove' ),
124
+ $add = $input.find( '.ditty-field__input__action--add' ),
125
+ $clone = $input.find( '.ditty-field__input__action--clone' );
126
+
127
+ $remove.on( 'click', function( e ) {
128
+ e.preventDefault();
129
+ $( this ).protipHide();
130
+ if ( 1 === $input.siblings().length ) {
131
+ addInput( $field, $input );
132
+ }
133
+ $input.remove();
134
+ updateField( $field );
135
+ //$( 'body' ).trigger( 'ditty_enable_settings_update' );
136
+ } );
137
+
138
+ $add.on( 'click', function( e ) {
139
+ e.preventDefault();
140
+ addInput( $field, $input );
141
+ //$( 'body' ).trigger( 'ditty_enable_settings_update' );
142
+ } );
143
+
144
+ $clone.on( 'click', function( e ) {
145
+ e.preventDefault();
146
+ addInput( $field, $input, $input.clone() );
147
+ //$( 'body' ).trigger( 'ditty_enable_settings_update' );
148
+ } );
149
+ }
150
+
151
+ function init( e ) {
152
+ $( e.target ).find( '.ditty-field--clone-enabled:not(.ditty-field--clone-enabled--init)' ).each( function() {
153
+ setup( $( this ) );
154
+ } );
155
+ }
156
+ $( document ).on( 'ditty_init_fields', init );
157
+
158
+ }() );
159
+
160
+ } );
includes/fields/js/fields/code.js ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global _:true */
2
+
3
+ jQuery( document ).ready( function( $ ) {
4
+
5
+ // Setup strict mode
6
+ (function() {
7
+
8
+ "use strict";
9
+
10
+ function setup( $field ) {
11
+ $field.addClass( 'ditty-input--code--init' );
12
+
13
+ var $textarea = $field.find( 'textarea' ),
14
+ codeEditor = null,
15
+ codeEditorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
16
+
17
+ codeEditorSettings.codemirror = _.extend(
18
+ {},
19
+ codeEditorSettings.codemirror,
20
+ {
21
+ mode : $textarea.data( 'mode' ) ? $textarea.data( 'mode' ) : null,
22
+ indentUnit : 2,
23
+ tabSize : 2
24
+ }
25
+ );
26
+ codeEditor = wp.codeEditor.initialize( $textarea[0], codeEditorSettings );
27
+ }
28
+
29
+ function init( e ) {
30
+ $( e.target ).find( '.ditty-input--code:not(.ditty-input--code--init)' ).each( function() {
31
+ setup( $( this ) );
32
+ } );
33
+ }
34
+ $( document ).on( 'ditty_init_fields', init );
35
+
36
+ }() );
37
+
38
+ } );
includes/fields/js/fields/color.js ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ function setup( $field ) {
9
+ $field.addClass( 'ditty-input--color--init' );
10
+ $field.find( 'input[type="text"]' ).minicolors( {
11
+ format: 'rgb',
12
+ opacity: true
13
+ } );
14
+ }
15
+
16
+ function init( e ) {
17
+ $( e.target ).find( '.ditty-input--color:not(.ditty-input--color--init)' ).each( function() {
18
+ setup( $( this ) );
19
+ } );
20
+ }
21
+ $( document ).on( 'ditty_init_fields', init );
22
+
23
+ }() );
24
+
25
+ } );
includes/fields/js/fields/date.js ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ function setup( $field ) {
9
+ var format = $field.find( 'input[type="text"]' ).data( 'dateformat' );
10
+ $field.find( 'input[type="text"]' ).datepicker( {
11
+ dateFormat: format
12
+ } );
13
+ }
14
+
15
+ function init( e ) {
16
+ $( e.target ).find( '.ditty-input--date' ).each( function() {
17
+ setup( $( this ) );
18
+ } );
19
+ }
20
+ $( document ).on( 'ditty_init_fields', init );
21
+
22
+ }() );
23
+
24
+ } );
includes/fields/js/fields/group.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ function setup( $field ) {
9
+ $field.addClass( 'ditty-field-type--group--init' );
10
+
11
+ var $input = $field.children( '.ditty-field__input__container' ).children( '.ditty-input--group' ),
12
+ height = 0;
13
+
14
+ if ( 'collapsed' === $field.attr( 'data-collapsible' ) ) {
15
+ $input.hide();
16
+ }
17
+
18
+ $field.on( 'click', '.ditty-field__collapsible-toggle', function( e ) {
19
+ e.preventDefault();
20
+ if ( 'expanded' === $( this ).parents( '.ditty-field-type--group' ).attr( 'data-collapsible' ) ) {
21
+ $( this ).parents( '.ditty-field-type--group' ).attr( 'data-collapsible', 'collapsed' );
22
+ height = $input.outerHeight();
23
+ $input.stop().animate( {
24
+ marginTop: '-' + height + 'px'
25
+ }, 1000, 'easeInOutQuint', function() {
26
+ $input.hide();
27
+ } );
28
+ } else {
29
+ $( this ).parents( '.ditty-field-type--group' ).attr( 'data-collapsible', 'expanded' );
30
+ height = $input.outerHeight();
31
+ $input.stop().css( 'marginTop', '-' + height + 'px' );
32
+ $input.show();
33
+ $input.stop().animate( {
34
+ marginTop: 0
35
+ }, 1000, 'easeInOutQuint', function() {
36
+ } );
37
+ }
38
+ } );
39
+ }
40
+
41
+ function init( e ) {
42
+ $( e.target ).find( '.ditty-field-type--group[data-collapsible]:not(.ditty-field-type--group--init)' ).each( function() {
43
+ setup( $( this ) );
44
+ } );
45
+ }
46
+ $( document ).on( 'ditty_init_fields', init );
47
+
48
+ }() );
49
+
50
+ } );
includes/fields/js/fields/image.js ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ function setup( $field ) {
9
+ $field.addClass( 'ditty-input--image--init' );
10
+
11
+ var $input = $field.find( 'input[type="hidden"]' ),
12
+ $preview = $field.find( '.ditty-input--image__preview' ),
13
+ $preview_img = $preview.children( 'img' ),
14
+ uploader;
15
+
16
+ $field.on( 'click', '.ditty-input--image__upload', function( e ) {
17
+ e.preventDefault();
18
+
19
+ if ( undefined === uploader ) {
20
+ uploader = wp.media({
21
+ title: $input.data( 'media_title' ),
22
+ button: { text: $input.data( 'media_button' ), size: 'small' },
23
+ multiple: $input.data( 'multiple' ),
24
+ library : {
25
+ type : 'image'
26
+ }
27
+ } );
28
+ }
29
+
30
+ uploader.on( 'open', function() {
31
+ var selection = uploader.state().get( 'selection' );
32
+ var attachment = wp.media.attachment( $input.val() );
33
+ if ( attachment ) {
34
+ selection.add( attachment );
35
+ }
36
+ // let ids = [13, 14, 56];
37
+ // ids.forEach(function(id) {
38
+ // let attachment = wp.media.attachment(id);
39
+ // selection.add(attachment ? [attachment] : []);
40
+ // } );
41
+ } );
42
+
43
+ uploader.on( 'select', function() {
44
+ var attachments = uploader.state().get( 'selection' ).toJSON(),
45
+ image_data = [];
46
+
47
+ if ( attachments.length > 0 ) {
48
+ $(attachments).each( function() {
49
+ image_data.push( {
50
+ id : $(this)[0].id,
51
+ title : $(this)[0].title,
52
+ caption : $(this)[0].caption,
53
+ description : $(this)[0].description,
54
+ link : $(this)[0].link,
55
+ url : $(this)[0].sizes.medium ? $(this)[0].sizes.medium.url : $(this)[0].sizes.full.url
56
+ } );
57
+ } );
58
+ }
59
+
60
+ $input.val( image_data[0].id );
61
+ if ( $preview_img.length ) {
62
+ $preview_img.remove();
63
+ }
64
+ $preview_img = $( '<img src="' + image_data[0].url + '" alt="" />' );
65
+ $preview.prepend( $preview_img );
66
+ $preview.find( 'i' ).remove();
67
+
68
+ $field.trigger( 'ditty_field_image_select', [$field, image_data] );
69
+ $field.trigger( 'ditty_field_update' );
70
+ } );
71
+
72
+ uploader.open();
73
+ return false;
74
+
75
+ } );
76
+
77
+ }
78
+
79
+ function init( e ) {
80
+ $( e.target ).find( '.ditty-input--image:not(.ditty-input--image--init)' ).each( function() {
81
+ setup( $( this ) );
82
+ } );
83
+ }
84
+ $( document ).on( 'ditty_init_fields', init );
85
+
86
+ }() );
87
+
88
+ } );
includes/fields/js/fields/slider.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ function setup( $field ) {
9
+ $field.addClass( 'ditty-input--slider--init' );
10
+ $field.find( 'input[type="text"]' ).ionRangeSlider();
11
+ }
12
+
13
+ function init( e ) {
14
+ $( e.target ).find( '.ditty-input--slider:not(.ditty-input--slider--init)' ).each( function() {
15
+ setup( $( this ) );
16
+ } );
17
+ }
18
+ $( document ).on( 'ditty_init_fields', init );
19
+
20
+ }() );
21
+
22
+ } );
includes/fields/js/fields/wysiwyg.js ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global tinyMCEPreInit:true */
2
+ /* global tinymce:true */
3
+ /* global quicktags:true */
4
+ /* global QTags:true */
5
+ /* global wp:true */
6
+
7
+ jQuery( document ).ready( function( $ ) {
8
+
9
+ // Setup strict mode
10
+ (function() {
11
+
12
+ "use strict";
13
+
14
+ /**
15
+ * Transform textarea into wysiwyg editor.
16
+ */
17
+ function transform( $field ) {
18
+
19
+ $field.addClass( 'ditty-input--wysiwyg--init' );
20
+ if ( $field.hasClass( 'ditty-input--clone--clone' ) ) {
21
+ var ranId = Math.floor( ( Math.random() * 100000000 ) + 1 );
22
+ $field.find( 'textarea' ).attr( 'id', 'ditty-input--' + ranId );
23
+ }
24
+
25
+ var $wrapper = $field.find( '.wp-editor-wrap' ),
26
+ id = $field.find( 'textarea' ).attr( 'id' ),
27
+ editor;
28
+
29
+ // Ignore existing editor.
30
+ if ( tinyMCEPreInit.mceInit[id] ) {
31
+ editor = tinymce.get( id );
32
+ editor.on( 'keyup change', function() {
33
+ tinymce.triggerSave();
34
+ $field.trigger( 'ditty_input_wysiwyg_update' );
35
+ } );
36
+ return;
37
+ }
38
+
39
+ var originalId = getOriginalId( $field ),
40
+ settings = getEditorSettings( originalId );
41
+
42
+ updateDom( $wrapper, id );
43
+
44
+ // TinyMCE
45
+ if ( window.tinymce ) {
46
+ tinymce.execCommand( 'mceRemoveEditor', true, id );
47
+ editor = new tinymce.Editor( id, settings.tinymce, tinymce.EditorManager );
48
+ editor.render();
49
+ editor.on( 'keyup change', function() {
50
+ tinymce.triggerSave();
51
+ $field.trigger( 'ditty_input_wysiwyg_update' );
52
+ } );
53
+ }
54
+
55
+ // Quick tags
56
+ if ( window.quicktags ) {
57
+ settings.quicktags.id = id;
58
+ quicktags( settings.quicktags );
59
+ QTags._buttonsInit();
60
+ }
61
+ }
62
+
63
+ function getOriginalId( $clone ) {
64
+ var $original = $clone.siblings( '.ditty-input--wysiwyg.ditty-input--clone--orig' ),
65
+ origingalID = $original.find( 'textarea' ).attr( 'id' );
66
+
67
+ if ( /_\d+$/.test( origingalID ) ) {
68
+ origingalID = origingalID.replace( /_\d+$/, '' );
69
+ }
70
+ if ( tinyMCEPreInit.mceInit.hasOwnProperty( origingalID ) || tinyMCEPreInit.qtInit.hasOwnProperty( origingalID ) ) {
71
+ return origingalID;
72
+ }
73
+ return '';
74
+ }
75
+
76
+ function updateDom( $wrapper, id ) {
77
+ // Wrapper div and media buttons
78
+ $wrapper.attr( 'id', 'wp-' + id + '-wrap' )
79
+ .find( '.mce-container' ).remove().end() // Remove rendered tinyMCE editor
80
+ .find( '.wp-editor-tools' ).attr( 'id', 'wp-' + id + '-editor-tools' )
81
+ .find( '.wp-media-buttons' ).attr( 'id', 'wp-' + id + '-media-buttons' )
82
+ .find( 'button' ).data( 'editor', id ).attr( 'data-editor', id );
83
+
84
+ // Set default active mode.
85
+ $wrapper.removeClass( 'html-active tmce-active' );
86
+ $wrapper.addClass( window.tinymce ? 'tmce-active' : 'html-active' );
87
+
88
+ // Editor tabs
89
+ $wrapper.find( '.switch-tmce' )
90
+ .attr( 'id', id + 'tmce' )
91
+ .data( 'wp-editor-id', id ).attr( 'data-wp-editor-id', id ).end()
92
+ .find( '.switch-html' )
93
+ .attr( 'id', id + 'html' )
94
+ .data( 'wp-editor-id', id ).attr( 'data-wp-editor-id', id );
95
+
96
+ // Quick tags
97
+ $wrapper.find( '.wp-editor-container' ).attr( 'id', 'wp-' + id + '-editor-container' )
98
+ .find( '.quicktags-toolbar' ).attr( 'id', 'qt_' + id + '_toolbar' ).html( '' );
99
+ }
100
+
101
+ function getEditorSettings( id ) {
102
+ var settings = getDefaultEditorSettings();
103
+ if ( id && tinyMCEPreInit.mceInit.hasOwnProperty( id ) ) {
104
+ settings.tinymce = tinyMCEPreInit.mceInit[id];
105
+ }
106
+ if ( id && window.quicktags && tinyMCEPreInit.qtInit.hasOwnProperty( id ) ) {
107
+ settings.quicktags = tinyMCEPreInit.qtInit[id];
108
+ }
109
+ return settings;
110
+ }
111
+
112
+ function getDefaultEditorSettings() {
113
+ var settings = wp.editor.getDefaultSettings();
114
+ settings.tinymce.toolbar1 = 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,wp_more,spellchecker,fullscreen,wp_adv';
115
+ settings.tinymce.toolbar2 = 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help';
116
+ settings.quicktags.buttons = 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close';
117
+ return settings;
118
+ }
119
+
120
+ function pre_save( e ) {
121
+ if ( window.tinymce && $( e.target ).find( '.ditty-input--wysiwyg--init .wp-editor-area' ).length ) {
122
+ tinymce.triggerSave();
123
+ }
124
+ }
125
+ $( document ).on( 'ditty_pre_save_fields', pre_save );
126
+
127
+ function init( e ) {
128
+ $( e.target ).find( '.ditty-input--wysiwyg:not(.ditty-input--wysiwyg--init)' ).each( function() {
129
+ transform( $( this ) );
130
+ } );
131
+ }
132
+ $( document ).on( 'ditty_init_fields', init );
133
+
134
+ }() );
135
+
136
+ } );
includes/helpers.php ADDED
@@ -0,0 +1,1442 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Return the settings defaults
5
+ *
6
+ * @since 3.0
7
+ */
8
+ function ditty_settings_defaults() {
9
+ $defaults = array(
10
+ 'live_refresh' => 10,
11
+ 'default_display' => false,
12
+ 'ditty_display_ui' => 'enabled',
13
+ 'ditty_layout_ui' => 'enabled',
14
+ 'ditty_layouts_sass' => false,
15
+ 'variation_defaults' => array(),
16
+ 'global_ditty' => array(),
17
+ 'ditty_news_ticker' => '',
18
+ 'notification_email' => '',
19
+ );
20
+ return apply_filters( 'ditty_settings_defaults', $defaults );
21
+ }
22
+
23
+ /**
24
+ * Return or set plugin settings
25
+ *
26
+ * @since 3.0
27
+ */
28
+ function ditty_settings( $key=false, $value='' ) {
29
+ global $ditty_settings;
30
+ if ( empty( $ditty_settings ) ) {
31
+ $ditty_settings = get_option( 'ditty_settings', array() );
32
+ }
33
+ if ( $key ) {
34
+ if ( is_array( $key ) ) {
35
+ foreach ( $key as $k => $v ) {
36
+ $ditty_settings[$k] = $v;
37
+ }
38
+ update_option( 'ditty_settings', $ditty_settings );
39
+ } else {
40
+ if ( $value ) {
41
+ $ditty_settings[$key] = $value;
42
+ update_option( 'ditty_settings', $ditty_settings );
43
+ }
44
+ }
45
+ }
46
+ $ditty_settings = wp_parse_args( $ditty_settings, ditty_settings_defaults() );
47
+ if ( $key && ! is_array( $key ) ) {
48
+ if ( isset( $ditty_settings[$key] ) ) {
49
+ return $ditty_settings[$key];
50
+ }
51
+ } else {
52
+ return $ditty_settings;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Return an array of item types
58
+ *
59
+ * @since 3.0
60
+ */
61
+ function ditty_item_types() {
62
+ $item_types = array();
63
+ $item_types['default'] = array(
64
+ 'type' => 'default',
65
+ 'label' => __( 'Default', 'ditty-news-ticker' ),
66
+ 'icon' => 'fas fa-pencil-alt',
67
+ 'description' => __( 'Manually add HTML to the item.', 'ditty-news-ticker' ),
68
+ 'class_name' => 'Ditty_Item_Type_Default',
69
+ );
70
+ $item_types['wp_editor'] = array(
71
+ 'type' => 'wp_editor',
72
+ 'label' => __( 'WP Editor', 'ditty-news-ticker' ),
73
+ 'icon' => 'fas fa-edit',
74
+ 'description' => __( 'Manually add wp editor content to the item.', 'ditty-news-ticker' ),
75
+ 'class_name' => 'Ditty_Item_Type_WP_Editor',
76
+ );
77
+ $item_types['posts_feed'] = array(
78
+ 'type' => 'posts_feed',
79
+ 'label' => __( 'WP Posts Feed (Lite)', 'ditty-news-ticker' ),
80
+ 'icon' => 'fab fa-wordpress',
81
+ 'description' => __( 'Add a WP Posts feed.', 'ditty-news-ticker' ),
82
+ 'class_name' => 'Ditty_Item_Type_Posts_Lite',
83
+ );
84
+ return apply_filters( 'ditty_item_types', $item_types );
85
+ }
86
+
87
+ /**
88
+ * Return a type class object
89
+ *
90
+ * @since 3.0
91
+ * @var object $type_object
92
+ */
93
+ function ditty_item_type_object( $type ) {
94
+ $item_types = ditty_item_types();
95
+ if ( isset( $item_types[$type] ) && class_exists( $item_types[$type]['class_name'] ) ) {
96
+ $type_object = new $item_types[$type]['class_name'];
97
+ return $type_object;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Return an array of ditty displays
103
+ *
104
+ * @since 3.0
105
+ */
106
+ function ditty_display_types() {
107
+ $display_types = array();
108
+ $display_types['ticker'] = array(
109
+ 'label' => __( 'Ticker', 'ditty-news-ticker' ),
110
+ 'icon' => 'fas fa-ellipsis-h',
111
+ 'description' => __( 'Basic news ticker display.', 'ditty-news-ticker' ),
112
+ 'class_name' => 'Ditty_Display_Type_Ticker',
113
+ //'class_path' => DITTY_DIR . 'includes/class-ditty-display-type-ticker.php',
114
+ );
115
+ $display_types['list'] = array(
116
+ 'label' => __( 'List', 'ditty-news-ticker' ),
117
+ 'icon' => 'fas fa-list',
118
+ 'description' => __( 'Display items in a static list.', 'ditty-news-ticker' ),
119
+ 'class_name' => 'Ditty_Display_Type_List',
120
+ //'class_path' => DITTY_DIR . 'includes/class-ditty-display-type-list.php',
121
+ );
122
+ return apply_filters( 'ditty_display_types', $display_types );
123
+ }
124
+
125
+ /**
126
+ * Return a display class object
127
+ *
128
+ * @since 3.0
129
+ * @var object $display_object
130
+ */
131
+ function ditty_display_type_object( $type ) {
132
+ $display_types = ditty_display_types();
133
+ if ( isset( $display_types[$type] ) && class_exists( $display_types[$type]['class_name'] ) ) {
134
+ $display_object = new $display_types[$type]['class_name'];
135
+ return $display_object;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Add in legacy licenses
141
+ *
142
+ * @since 3.0
143
+ */
144
+ function ditty_extension_legacy_licenses( $licenses ) {
145
+ $legacy_licenses = apply_filters( 'mtphr_dnt_license_data', array() );
146
+ if ( is_array( $legacy_licenses ) && count( $legacy_licenses ) > 0 ) {
147
+ foreach ( $legacy_licenses as $slug => $legacy_license ) {
148
+ if ( $updated_slug = ditty_updated_extension_slug( $slug ) ) {
149
+ if ( ! isset( $licenses[$updated_slug] ) ) {
150
+ $licenses[$updated_slug] = $legacy_license;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ return $licenses;
156
+ }
157
+
158
+ /**
159
+ * Return an array of Ditty extension licenses
160
+ *
161
+ * @since 3.0
162
+ */
163
+ function ditty_extension_licenses() {
164
+ $licenses = apply_filters( 'ditty_extension_licenses', array() );
165
+ $licenses = ditty_extension_legacy_licenses( $licenses );
166
+ return $licenses;
167
+ }
168
+
169
+ /**
170
+ * Add in legacy licenses
171
+ *
172
+ * @since 3.0
173
+ */
174
+ function ditty_legacy_extensions( $extensions ) {
175
+ $legacy_extensions = apply_filters( 'mtphr_dnt_license_data', array() );
176
+ if ( is_array( $legacy_extensions ) && count( $legacy_extensions ) > 0 ) {
177
+ foreach ( $legacy_extensions as $slug => $legacy_extension ) {
178
+ if ( $updated_slug = ditty_updated_extension_slug( $slug ) ) {
179
+ if ( isset( $extensions[$updated_slug] ) ) {
180
+ unset( $extensions[$updated_slug]['preview'] );
181
+ }
182
+ }
183
+ }
184
+ }
185
+ return $extensions;
186
+ }
187
+
188
+ /**
189
+ * Return an array of Ditty Extensions
190
+ *
191
+ * @since 3.0
192
+ */
193
+ function ditty_extensions() {
194
+ $extensions = array(
195
+ 'facebook' => array(
196
+ 'icon' => 'fab fa-facebook',
197
+ 'name' => __( 'Facebook', 'ditty-news-ticker' ),
198
+ 'preview' => true,
199
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-facebook-ticker/',
200
+ ),
201
+ 'facebook' => array(
202
+ 'icon' => 'fab fa-facebook',
203
+ 'name' => __( 'Facebook', 'ditty-news-ticker' ),
204
+ 'preview' => true,
205
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-facebook-ticker/',
206
+ ),
207
+ 'grid' => array(
208
+ 'icon' => 'fas fa-th',
209
+ 'name' => __( 'Grid Display', 'ditty-news-ticker' ),
210
+ 'preview' => true,
211
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-grid-display/',
212
+ ),
213
+ 'images' => array(
214
+ 'icon' => 'fas fa-image',
215
+ 'name' => __( 'Images', 'ditty-news-ticker' ),
216
+ 'preview' => true,
217
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-image-ticker/',
218
+ ),
219
+ 'instagram' => array(
220
+ 'icon' => 'fab fa-instagram',
221
+ 'name' => __( 'Instagram', 'ditty-news-ticker' ),
222
+ 'preview' => true,
223
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-instagram-ticker/',
224
+ ),
225
+ 'posts' => array(
226
+ 'icon' => 'fab fa-wordpress',
227
+ 'name' => __( 'Posts', 'ditty-news-ticker' ),
228
+ 'preview' => true,
229
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-posts-ticker/',
230
+ ),
231
+ 'rss' => array(
232
+ 'icon' => 'fas fa-rss',
233
+ 'name' => __( 'RSS', 'ditty-news-ticker' ),
234
+ 'preview' => true,
235
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-rss-ticker/',
236
+ ),
237
+ 'timing' => array(
238
+ 'icon' => 'fas fa-clock',
239
+ 'name' => __( 'Timing', 'ditty-news-ticker' ),
240
+ 'preview' => true,
241
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-timed-ticker/',
242
+ ),
243
+ 'twitter' => array(
244
+ 'icon' => 'fab fa-twitter',
245
+ 'name' => __( 'Twitter', 'ditty-news-ticker' ),
246
+ 'preview' => true,
247
+ 'url' => 'https://www.metaphorcreations.com/downloads/ditty-twitter-ticker/',
248
+ ),
249
+ );
250
+ $extensions = apply_filters( 'ditty_extensions', $extensions );
251
+ $extensions = ditty_legacy_extensions( $extensions );
252
+ ksort( $extensions );
253
+
254
+ // Set the live extensions to be first
255
+ $live_extensions = array();
256
+ $preview_extensions = array();
257
+ if ( is_array( $extensions ) && count( $extensions ) > 0 ) {
258
+ foreach ( $extensions as $slug => $data ) {
259
+ if ( isset( $data['preview'] ) ) {
260
+ $preview_extensions[$slug] = $data;
261
+ } else {
262
+ $live_extensions[$slug] = $data;
263
+ }
264
+ }
265
+ }
266
+ return $live_extensions + $preview_extensions;
267
+ }
268
+
269
+ /**
270
+ * Return an updated legacy slug
271
+ * @since 3.0
272
+ */
273
+ function ditty_updated_extension_slug( $slug ) {
274
+ $updated_slug = '';
275
+ switch ( $slug ) {
276
+ case 'ditty-facebook-ticker':
277
+ $updated_slug = 'facebook';
278
+ break;
279
+ case 'ditty-image-ticker':
280
+ $updated_slug = 'images';
281
+ break;
282
+ case 'ditty-instagram-ticker':
283
+ $updated_slug = 'instagram';
284
+ break;
285
+ case 'ditty-mega-ticker':
286
+ $updated_slug = 'mega';
287
+ break;
288
+ case 'ditty-posts-ticker':
289
+ $updated_slug = 'posts';
290
+ break;
291
+ case 'ditty-rss-ticker':
292
+ $updated_slug = 'rss';
293
+ break;
294
+ case 'ditty-timed-ticker':
295
+ $updated_slug = 'timing';
296
+ break;
297
+ case 'ditty-twitter-ticker':
298
+ $updated_slug = 'twitter';
299
+ break;
300
+ default:
301
+ break;
302
+ }
303
+ if ( '' != $updated_slug ) {
304
+ return $updated_slug;
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Set the global draft values
310
+ * @since 3.0
311
+ */
312
+ function ditty_set_draft_values( $values ) {
313
+ global $ditty_draft_values;
314
+ $ditty_draft_values = $values;
315
+ }
316
+
317
+ /**
318
+ * Get the global draft values
319
+ * @since 3.0
320
+ */
321
+ function ditty_get_draft_values() {
322
+ global $ditty_draft_values;
323
+ if ( ! empty( $ditty_draft_values ) ) {
324
+ return $ditty_draft_values;
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Get the item draft values
330
+ * @since 3.0
331
+ */
332
+ function ditty_draft_item_get_data( $item_id, $key = false ) {
333
+ $draft_values = ditty_get_draft_values();
334
+ if ( ! $draft_values ) {
335
+ return false;
336
+ }
337
+ if ( ! isset( $draft_values['items'] ) ) {
338
+ return false;
339
+ }
340
+ if ( ! isset( $draft_values['items'][$item_id] ) ) {
341
+ return false;
342
+ }
343
+ if ( ! isset( $draft_values['items'][$item_id]['data'] ) ) {
344
+ return false;
345
+ }
346
+ if ( $key ) {
347
+ if ( isset( $draft_values['items'][$item_id]['data'][$key] ) ) {
348
+ return $draft_values['items'][$item_id]['data'][$key];
349
+ }
350
+ } else {
351
+ return $draft_values['items'][$item_id]['data'];
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Get item draft meta
357
+ * @since 3.0
358
+ */
359
+ function ditty_draft_item_get_meta( $item_id, $key = false ) {
360
+ $draft_values = ditty_get_draft_values();
361
+ if ( ! $draft_values ) {
362
+ return false;
363
+ }
364
+ if ( ! isset( $draft_values['items'] ) ) {
365
+ return false;
366
+ }
367
+ if ( ! isset( $draft_values['items'][$item_id] ) ) {
368
+ return false;
369
+ }
370
+ if ( ! isset( $draft_values['items'][$item_id]['meta'] ) ) {
371
+ return false;
372
+ }
373
+ if ( $key ) {
374
+ if ( isset( $draft_values['items'][$item_id]['meta'][$key] ) ) {
375
+ return $draft_values['items'][$item_id]['meta'][$key];
376
+ }
377
+ } else {
378
+ return $draft_values['items'][$item_id]['meta'];
379
+ }
380
+ }
381
+
382
+ /**
383
+ * Update item draft meta
384
+ * @since 3.0
385
+ */
386
+ function ditty_draft_item_update_meta( $item_id, $key = false, $value ) {
387
+ $draft_values = ditty_get_draft_values();
388
+ if ( ! $draft_values ) {
389
+ $draft_values = array();
390
+ }
391
+ if ( ! isset( $draft_values['items'] ) ) {
392
+ $draft_values['items'] = array();
393
+ }
394
+ if ( ! isset( $draft_values['items'][$item_id] ) ) {
395
+ $draft_values['items'][$item_id] = array();
396
+ }
397
+ if ( ! isset( $draft_values['items'][$item_id]['meta'] ) ) {
398
+ $draft_values['items'][$item_id]['meta'] = array();
399
+ }
400
+ if ( $key ) {
401
+ $draft_values['items'][$item_id]['meta'][$key] = $value;
402
+ } else {
403
+ $draft_values['items'][$item_id]['meta'] = $value;
404
+ }
405
+ ditty_set_draft_values( $draft_values );
406
+ }
407
+
408
+ /**
409
+ * Get the layout draft values
410
+ * @since 3.0
411
+ */
412
+ function ditty_draft_layout_get( $layout_id = false, $key = false ) {
413
+ $draft_values = ditty_get_draft_values();
414
+ if ( ! $draft_values ) {
415
+ return false;
416
+ }
417
+ if ( ! isset( $draft_values['layouts'] ) ) {
418
+ return false;
419
+ }
420
+ if ( ! $layout_id ) {
421
+ return $draft_values['layouts'];
422
+ }
423
+ if ( ! isset( $draft_values['layouts'][$layout_id] ) ) {
424
+ return false;
425
+ }
426
+ if ( $key ) {
427
+ if ( isset( $draft_values['layouts'][$layout_id][$key] ) ) {
428
+ return $draft_values['layouts'][$layout_id][$key];
429
+ }
430
+ } else {
431
+ return $draft_values['layouts'][$layout_id];
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Update a layout draft
437
+ * @since 3.0
438
+ */
439
+ function ditty_draft_layout_update( $layout_id, $key = false, $value ) {
440
+ $draft_values = ditty_get_draft_values();
441
+ if ( ! $draft_values ) {
442
+ $draft_values = array();
443
+ }
444
+ if ( ! isset( $draft_values['layouts'] ) ) {
445
+ $draft_values['layouts'] = array();
446
+ }
447
+ if ( ! isset( $draft_values['layouts'][$layout_id] ) ) {
448
+ $draft_values['layouts'][$layout_id] = array();
449
+ }
450
+ if ( $key ) {
451
+ $draft_values['layouts'][$layout_id][$key] = $value;
452
+ } else {
453
+ $draft_values['layouts'][$layout_id] = $value;
454
+ }
455
+ ditty_set_draft_values( $draft_values );
456
+ }
457
+
458
+ /**
459
+ * Get the display draft values
460
+ * @since 3.0
461
+ */
462
+ function ditty_draft_display_get( $display_id, $key = false ) {
463
+ $draft_values = ditty_get_draft_values();
464
+ if ( ! $draft_values ) {
465
+ return false;
466
+ }
467
+ if ( ! isset( $draft_values['displays'] ) ) {
468
+ return false;
469
+ }
470
+ if ( ! isset( $draft_values['displays'][$display_id] ) ) {
471
+ return false;
472
+ }
473
+ if ( $key ) {
474
+ if ( isset( $draft_values['displays'][$display_id][$key] ) ) {
475
+ return $draft_values['displays'][$display_id][$key];
476
+ }
477
+ } else {
478
+ return $draft_values['displays'][$display_id];
479
+ }
480
+ }
481
+
482
+ /**
483
+ * Update a display draft
484
+ * @since 3.0
485
+ */
486
+ function ditty_draft_display_update( $display_id, $key = false, $value ) {
487
+ $draft_values = ditty_get_draft_values();
488
+ if ( ! $draft_values ) {
489
+ $draft_values = array();
490
+ }
491
+ if ( ! isset( $draft_values['displays'] ) ) {
492
+ $draft_values['displays'] = array();
493
+ }
494
+ if ( ! isset( $draft_values['displays'][$display_id] ) ) {
495
+ $draft_values['displays'][$display_id] = array();
496
+ }
497
+ if ( $key ) {
498
+ $draft_values['displays'][$display_id][$key] = $value;
499
+ } else {
500
+ $draft_values['displays'][$display_id] = $value;
501
+ }
502
+ ditty_set_draft_values( $draft_values );
503
+ }
504
+
505
+ /**
506
+ * Return all possible item type variations
507
+ *
508
+ * @since 3.0
509
+ * @var html
510
+ */
511
+ function ditty_set_variation_default( $item_type, $variation, $layout_id ) {
512
+ if ( ! $item_type_object = ditty_item_type_object( $item_type ) ) {
513
+ return false;
514
+ }
515
+ $variation_defaults = ditty_settings( 'variation_defaults' );
516
+ if ( ! isset( $variation_defaults[$item_type] ) ) {
517
+ $variation_defaults[$item_type] = array();
518
+ }
519
+ if ( is_string( $layout_id ) ) {
520
+ $args = array(
521
+ 'template' => $layout_id,
522
+ 'fields' => 'ids',
523
+ );
524
+ if ( $posts = ditty_layouts_posts( $args ) ) {
525
+ $post_layout_id = reset( $posts );
526
+ $variation_defaults[$item_type][$variation] = $post_layout_id;
527
+ ditty_settings( 'variation_defaults', $variation_defaults );
528
+ return $post_layout_id;
529
+ } elseif( $post_layout_id = Ditty()->layouts->install_default( $layout_id ) ) {
530
+ $variation_defaults[$item_type][$variation] = $post_layout_id;
531
+ ditty_settings( 'variation_defaults', $variation_defaults );
532
+ return $post_layout_id;
533
+ }
534
+ } elseif( get_post( $layout_id ) ) {
535
+ $variation_defaults[$item_type][$variation] = $layout_id;
536
+ ditty_settings( 'variation_defaults', $variation_defaults );
537
+ return $layout_id;
538
+ }
539
+ }
540
+
541
+ /**
542
+ * Return all possible item type variations
543
+ *
544
+ * @since 3.0
545
+ * @var html
546
+ */
547
+ function ditty_layout_variation_types( $item_type = false ) {
548
+ if ( $item_type ) {
549
+ if ( $item_type_object = ditty_item_type_object( $item_type ) ) {
550
+ return $item_type_object->get_layout_variation_types();
551
+ }
552
+ } else {
553
+ $item_types = ditty_item_types();
554
+ $layout_variation_types = array();
555
+ if ( is_array( $item_types ) && count( $item_types ) > 0 ) {
556
+ foreach ( $item_types as $item_type => $data ) {
557
+ if ( $item_type_object = ditty_item_type_object( $item_type ) ) {
558
+ $layout_variation_types[$item_type] = $item_type_object->get_layout_variation_types();
559
+ }
560
+ }
561
+ }
562
+ return $layout_variation_types;
563
+ }
564
+ }
565
+
566
+ /**
567
+ * Check if a layout type exists
568
+ *
569
+ * @since 3.0
570
+ * @access public
571
+ * @var bool
572
+ */
573
+ function ditty_layouts_posts( $atts = array() ) {
574
+ $defaults = array(
575
+ 'template' => false,
576
+ 'version' => false,
577
+ 'fields' => 'all',
578
+ 'return' => 'posts',
579
+ );
580
+ $args = shortcode_atts( $defaults, $atts );
581
+
582
+ $query_args = array(
583
+ 'posts_per_page' => -1,
584
+ 'post_type' => 'ditty_layout',
585
+ 'post_status' => 'publish',
586
+ 'fields' => $args['fields'],
587
+ );
588
+ $meta_query = array();
589
+ if ( $args['template'] ) {
590
+ $meta_query['template'] = array(
591
+ 'key' => '_ditty_layout_template',
592
+ 'value' => $args['template'],
593
+ );
594
+ }
595
+ if ( $args['version'] ) {
596
+ $meta_query['version'] = array(
597
+ 'key' => '_ditty_layout_version',
598
+ 'value' => $args['version'],
599
+ );
600
+ }
601
+ $query_args['meta_query'] = $meta_query;
602
+ $layouts = get_posts( $query_args );
603
+
604
+ if ( 'versions' == $args['return'] ) {
605
+ $layout_versions = array();
606
+ if ( is_array( $layouts ) && count( $layouts ) > 0 ) {
607
+ foreach ( $layouts as $i => $layout_id ) {
608
+ $version = get_post_meta( $layout_id, '_ditty_layout_version', true );
609
+ $layout_versions[] = $version;
610
+ }
611
+ }
612
+ if ( ! empty( $layout_versions ) ) {
613
+ return $layout_versions;
614
+ }
615
+ } else {
616
+ return $layouts;
617
+ }
618
+ }
619
+
620
+ /**
621
+ * Check if a display type exists
622
+ *
623
+ * @since 3.0
624
+ * @access public
625
+ * @var bool
626
+ */
627
+ function ditty_displays_with_type( $display_type, $atts = array() ) {
628
+ $defaults = array(
629
+ 'template' => false,
630
+ 'version' => false,
631
+ 'return' => 'ids',
632
+ );
633
+ $args = shortcode_atts( $defaults, $atts );
634
+
635
+ $query_args = array(
636
+ 'posts_per_page' => -1,
637
+ 'post_type' => 'ditty_display',
638
+ 'post_status' => 'publish',
639
+ 'fields' => 'ids',
640
+ );
641
+ $meta_query = array();
642
+ $meta_query['type'] = array(
643
+ 'key' => '_ditty_display_type',
644
+ 'value' => $display_type,
645
+ );
646
+ if ( $args['template'] ) {
647
+ $meta_query['template'] = array(
648
+ 'key' => '_ditty_display_template',
649
+ 'value' => $args['template'],
650
+ );
651
+ }
652
+ if ( $args['version'] ) {
653
+ $meta_query['version'] = array(
654
+ 'key' => '_ditty_display_version',
655
+ 'value' => $args['version'],
656
+ );
657
+ }
658
+ $query_args['meta_query'] = $meta_query;
659
+ $displays = get_posts( $query_args );
660
+
661
+ if ( 'versions' == $args['return'] ) {
662
+ $display_versions = array();
663
+ if ( is_array( $displays ) && count( $displays ) > 0 ) {
664
+ foreach ( $displays as $i => $display_id ) {
665
+ $version = get_post_meta( $display_id, '_ditty_display_version', true );
666
+ $display_versions[] = $version;
667
+ }
668
+ }
669
+ if ( ! empty( $display_versions ) ) {
670
+ return $display_versions;
671
+ }
672
+ } else {
673
+ return $displays;
674
+ }
675
+ }
676
+
677
+ /**
678
+ * Return the default displays
679
+ *
680
+ * @since 3.0
681
+ * @var array $default_displays
682
+ */
683
+ function ditty_default_displays() {
684
+ $default_displays = array();
685
+ $display_types = ditty_display_types();
686
+ if ( is_array( $display_types ) && count( $display_types ) > 0 ) {
687
+ foreach ( $display_types as $display_type => $data ) {
688
+ $type_object = ditty_display_type_object( $display_type );
689
+ $templates = $type_object->templates();
690
+
691
+ $default_displays[$display_type] = array(
692
+ 'label' => $data['label'],
693
+ 'templates' => $templates,
694
+ );
695
+ }
696
+ }
697
+
698
+ return $default_displays;
699
+ }
700
+
701
+ /**
702
+ * Return the default display for Dittys
703
+ *
704
+ * @since 3.0
705
+ * @var bool
706
+ */
707
+ function ditty_default_display( $post_id ) {
708
+ $display_types = ditty_display_types();
709
+
710
+ // Check if saved default display exists
711
+ $default_display = ditty_settings( 'default_display' );
712
+ if ( $default_display && 'publish' == get_post_status( $default_display ) ) {
713
+ $display_type == get_post_meta( $default_display, '_ditty_display_type', true );
714
+ if ( array_key_exists( $display_type, $display_types ) ) {
715
+ return $default_display;
716
+ }
717
+ }
718
+
719
+ $display_id = Ditty()->displays->install_default( 'ticker', 'default' );
720
+ return $display_id;
721
+ }
722
+
723
+ /**
724
+ * Check if a display exists by selector
725
+ * @since 3.0
726
+ */
727
+ function ditty_display_exists( $display_id ) {
728
+ if ( 'publish' == get_post_status( $display_id ) ) {
729
+ return true;
730
+ }
731
+ }
732
+
733
+ /**
734
+ * Setup general text strings
735
+ *
736
+ * @since 3.0
737
+ * @access public
738
+ * @var string $strings,
739
+ */
740
+ function ditty_admin_strings( $slug = false ) {
741
+ global $ditty_admin_strings;
742
+ if ( empty( $ditty_admin_strings ) ) {
743
+ $strings = array(
744
+ 'extension_valid' => __( 'License is active.', 'ditty-news-ticker' ),
745
+ 'extension_generic_error' => __( 'An error occurred, please try again.', 'ditty-news-ticker' ),
746
+ 'extension_remote_error' => __( 'An error occurred, please try again.', 'ditty-news-ticker' ),
747
+ 'extension_expired' => __( 'Your license key expired on %s.', 'ditty-news-ticker' ),
748
+ 'extension_disabled' => __( 'Your license key has been disabled.', 'ditty-news-ticker' ),
749
+ 'extension_revoked' => __( 'Your license key has been disabled.', 'ditty-news-ticker' ),
750
+ 'extension_missing' => __( 'Invalid license.', 'ditty-news-ticker' ),
751
+ 'extension_invalid' => __( 'Your license is not active for this URL.', 'ditty-news-ticker' ),
752
+ 'extension_site_inactive' => __( 'Your license is not active for this URL.', 'ditty-news-ticker' ),
753
+ 'extension_item_name_mismatch' => __( 'This appears to be an invalid license key.', 'ditty-news-ticker' ),
754
+ 'extension_no_activations_left' => __( 'Your license key has reached its activation limit.', 'ditty-news-ticker' ),
755
+ 'extension_deactivated' => __( 'License is deactivated.', 'ditty-news-ticker' ),
756
+ 'extension_failed' => __( 'Update failed.', 'ditty-news-ticker' ),
757
+ 'settings_save' => __( 'Save Settings', 'ditty-news-ticker' ),
758
+ 'settings_saving' => __( 'Saving...', 'ditty-news-ticker' ),
759
+ 'settings_changed' => __( 'Settings have changed, make sure to save them!', 'ditty-news-ticker' ),
760
+ 'settings_updated' => __( 'Settings Updated!', 'ditty-news-ticker' ),
761
+ 'settings_error' => __( 'Error Updating!', 'ditty-news-ticker' ),
762
+ );
763
+ $ditty_admin_strings = apply_filters( 'ditty_admin_strings', $strings );
764
+ }
765
+ if ( $slug ) {
766
+ if ( isset( $ditty_admin_strings[$slug] ) ) {
767
+ return $ditty_admin_strings[$slug];
768
+ }
769
+ } else {
770
+ return $ditty_admin_strings;
771
+ }
772
+ }
773
+
774
+ /**
775
+ * Setup general text strings
776
+ *
777
+ * @since 3.0
778
+ * @access public
779
+ * @var string $strings,
780
+ */
781
+ function ditty_strings( $slug = false ) {
782
+ global $ditty_strings;
783
+ if ( empty( $ditty_strings ) ) {
784
+ $strings = array(
785
+ 'add_title' => __( 'Add title', 'ditty-news-ticker' ),
786
+ 'confirm_delete_item' => __( 'Are you sure you want to delete this Item? This action cannot be undone.', 'ditty-news-ticker' ),
787
+ 'confirm_delete_display' => __( 'Are you sure you want to delete this Display?', 'ditty-news-ticker' ),
788
+ 'confirm_delete_layout' => __( 'Are you sure you want to delete this Layout?', 'ditty-news-ticker' ),
789
+ 'layout_css_error' => __( 'There is an error in your css.<br/>Click to close this message.', 'ditty-news-ticker' ),
790
+ );
791
+ $ditty_strings = apply_filters( 'ditty_strings', $strings );
792
+ }
793
+ if ( $slug ) {
794
+ if ( isset( $ditty_strings[$slug] ) ) {
795
+ return $ditty_strings[$slug];
796
+ }
797
+ } else {
798
+ return $ditty_strings;
799
+ }
800
+ }
801
+
802
+ /**
803
+ * Return an array of item types with just the type and labels
804
+ *
805
+ * @since 3.0
806
+ * @access public
807
+ * @var array $ditty_types_simple
808
+ */
809
+ function ditty_types_simple() {
810
+
811
+ $item_types = ditty_item_types();
812
+ $item_types_simple = array();
813
+
814
+ if ( is_array( $item_types ) && count( $item_types ) > 0 ) {
815
+ foreach ( $item_types as $i => $type ) {
816
+ $item_types_simple[ $ditty_type['type'] ] = $type['label'];
817
+ }
818
+ }
819
+
820
+ return $item_types_simple;
821
+ }
822
+
823
+
824
+ /**
825
+ * Check if a type exists
826
+ *
827
+ * @since 3.0
828
+ * @access public
829
+ * @var bool
830
+ */
831
+ function ditty_type_exists( $slug ) {
832
+ $item_types = ditty_item_types();
833
+ return array_key_exists( $slug, $item_types );
834
+ }
835
+
836
+ /**
837
+ * Return display items for a specific Ditty
838
+ *
839
+ * @since 3.0
840
+ * @access public
841
+ * @var array $display_items Array of item objects
842
+ */
843
+ function ditty_display_items( $ditty_id, $load_type = false ) {
844
+ $transient_name = "ditty_display_items_{$ditty_id}";
845
+ $display_items = get_transient( $transient_name );
846
+ if ( ! $display_items || 'force' == $load_type ) {
847
+ $display_items = array();
848
+ $items_meta = ditty_items_meta( $ditty_id );
849
+
850
+ // Add new draft meta
851
+ // if ( $draft_values = ditty_get_draft_values() ) {
852
+ // if ( isset( $draft_values['items'] ) && is_array( $draft_values['items'] ) && count( $draft_values['items'] ) > 0 ) {
853
+ // foreach ( $draft_values['items'] as $i => $draft_item_meta ) {
854
+ // if ( ! isset( $draft_item_meta['data'] ) || ! isset( $draft_item_meta['data']['item_id'] ) ) {
855
+ // continue;
856
+ // }
857
+ // if ( false !== strpos( $draft_item_meta['data']['item_id'], 'new-' ) ) {
858
+ // $items_meta[] = $draft_item_meta['data'];
859
+ // }
860
+ // }
861
+ // }
862
+ // }
863
+
864
+ if ( empty( $items_meta) && 'auto-draft' == get_post_status( $ditty_id ) ) {
865
+ $items_meta = array( ditty_get_new_item_meta( $ditty_id ) );
866
+ }
867
+ if ( is_array( $items_meta ) && count( $items_meta ) > 0 ) {
868
+ foreach ( $items_meta as $i => $meta ) {
869
+ if ( is_object( $meta ) ) {
870
+ $meta = ( array ) $meta;
871
+ }
872
+
873
+ // Check for updated draft meta
874
+ // if ( $draft_data = ditty_draft_item_get_data( $meta['item_id'] ) ) {
875
+ // if ( isset( $draft_data['item_value'] ) ) {
876
+ // $draft_data['item_value'] = maybe_serialize( $draft_data['item_value'] );
877
+ // }
878
+ // if ( isset( $draft_data['layout_value'] ) ) {
879
+ // $draft_data['layout_value'] = maybe_serialize( $draft_data['layout_value'] );
880
+ // }
881
+ // $meta = shortcode_atts( $meta, $draft_data );
882
+ // }
883
+
884
+ $prepared_items = ditty_prepare_display_items( $meta );
885
+ if ( is_array( $prepared_items ) && count( $prepared_items ) > 0 ) {
886
+ foreach ( $prepared_items as $i => $prepared_meta ) {
887
+ $display_item = new Ditty_Display_Item( $prepared_meta );
888
+ if ( $data = $display_item->compile_data() ) {
889
+ $display_items[] = $data;
890
+ }
891
+ }
892
+ }
893
+ }
894
+ }
895
+ $display_items = apply_filters( 'ditty_display_items', $display_items, $ditty_id );
896
+ set_transient( $transient_name, $display_items, ( MINUTE_IN_SECONDS * ditty_settings( 'live_refresh' ) ) );
897
+ }
898
+ return $display_items;
899
+ }
900
+
901
+ /**
902
+ * Return item data for a Ditty
903
+ *
904
+ * @since 3.0
905
+ * @access public
906
+ * @var array $items_meta Array of items connected to a Ditty
907
+ */
908
+ function ditty_items_meta( $ditty_id=false ) {
909
+ $ditty_id = $ditty_id ? $ditty_id : get_the_id();
910
+ global $items_meta;
911
+
912
+ if ( empty( $items_meta ) ) {
913
+ $items_meta = array();
914
+ }
915
+ if ( ! isset( $items_meta[$ditty_id] ) ) {
916
+ $normalized_meta = array();
917
+ $all_meta = Ditty()->db_items->get_items( $ditty_id );
918
+ if ( is_array( $all_meta ) && count( $all_meta ) > 0 ) {
919
+ foreach ( $all_meta as $i => $meta ) {
920
+ $value = maybe_unserialize( $meta->item_value );
921
+ $meta->item_value = $value;
922
+ unset( $meta->layout_id ); // TODO: Maybe remove?
923
+ $normalized_meta[] = apply_filters( 'ditty_item_meta', $meta, $meta->item_id, $ditty_id );
924
+ }
925
+ }
926
+ $items_meta[$ditty_id] = apply_filters( 'ditty_items_meta', $normalized_meta, $ditty_id );
927
+ }
928
+ return $items_meta[$ditty_id];
929
+ }
930
+
931
+ /**
932
+ * Return item data by id
933
+ *
934
+ * @since 3.0
935
+ * @access public
936
+ * @var array $meta Array of items connected to a Ditty
937
+ */
938
+ function ditty_item_meta( $item_id ) {
939
+ $meta = Ditty()->db_items->get( $item_id );
940
+ $ditty_id = ( isset( $meta->ditty_id ) ) ? $meta->ditty_id : 0;
941
+ $value = maybe_unserialize( $meta->item_value );
942
+ $meta->item_value = $value;
943
+ return apply_filters( 'ditty_item_meta', $meta, $item_id, $ditty_id );
944
+ }
945
+
946
+ /**
947
+ * Return an array of new item meta
948
+ *
949
+ * @since 3.0
950
+ * @access public
951
+ * @var array $item_meta Array of item data
952
+ */
953
+ function ditty_get_new_item_meta( $ditty_id ) {
954
+ $item_type_object = ditty_item_type_object( 'default' );
955
+ $item_value = $item_type_object->default_settings();
956
+ $variation_defaults = ditty_settings( 'variation_defaults' );
957
+ $layout_id = ( isset( $variation_defaults['default'] ) && isset( $variation_defaults['default']['default'] ) ) ? $variation_defaults['default']['default'] : 0;
958
+ $meta = array(
959
+ 'item_id' => uniqid( 'new-' ),
960
+ 'item_type' => 'default',
961
+ 'item_value' => $item_value,
962
+ 'ditty_id' => $ditty_id,
963
+ 'layout_value' => array( 'default' => $layout_id ),
964
+ );
965
+ return apply_filters( 'ditty_editor_new_item_meta', $meta, $ditty_id );
966
+ }
967
+
968
+ /**
969
+ * Check if you're on a display post
970
+ *
971
+ * @since 3.0
972
+ * @var bool
973
+ */
974
+ function ditty_is_display_post() {
975
+ if ( ! function_exists( 'get_current_screen' ) ) {
976
+ return false;
977
+ }
978
+
979
+ $screen = get_current_screen();
980
+ if( is_object( $screen ) && 'ditty_display' == $screen->post_type && 'post' == $screen->base ) {
981
+ return true;
982
+ }
983
+ }
984
+
985
+ /**
986
+ * Check if you're on a layout post
987
+ *
988
+ * @since 3.0
989
+ * @var bool
990
+ */
991
+ function ditty_is_layout_post() {
992
+ if ( ! function_exists( 'get_current_screen' ) ) {
993
+ return false;
994
+ }
995
+
996
+ $screen = get_current_screen();
997
+ if( is_object( $screen ) && 'ditty_layout' == $screen->post_type && 'post' == $screen->base ) {
998
+ return true;
999
+ }
1000
+ }
1001
+
1002
+
1003
+ /**
1004
+ * Check if you're on a Ditty post
1005
+ *
1006
+ * @since 3.0
1007
+ * @var bool
1008
+ */
1009
+ function is_ditty_post() {
1010
+ if ( ! function_exists( 'get_current_screen' ) ) {
1011
+ return false;
1012
+ }
1013
+ $screen = get_current_screen();
1014
+ if( is_object( $screen ) && 'ditty' == $screen->post_type && 'post' == $screen->base ) {
1015
+ return true;
1016
+ }
1017
+ }
1018
+
1019
+ /**
1020
+ * Check if a Ditty post exists
1021
+ *
1022
+ * @since 3.0
1023
+ * @var bool
1024
+ */
1025
+ function ditty_exists( $id ) {
1026
+ return is_string( get_post_status( $id ) );
1027
+ }
1028
+
1029
+ /**
1030
+ * Replace template tags
1031
+ *
1032
+ * @since 3.0
1033
+ * @var string
1034
+ */
1035
+ // function ditty_replace_html_tags( $tags, $value, $string ) {
1036
+ // $content = preg_replace_callback( "/{([A-z0-9\-\_]+)}/s", function ( $matches ) use( $tags, $value ) {
1037
+ //
1038
+ // // Get tag
1039
+ // $tag = $matches[1];
1040
+ //
1041
+ // // Return tag if tag not set
1042
+ // if ( ! array_key_exists( $tag, $tags ) ) {
1043
+ // return $matches[0];
1044
+ // }
1045
+ //
1046
+ // return call_user_func( $tags[$tag]['func'], $value );
1047
+ //
1048
+ // }, $string
1049
+ // );
1050
+ //
1051
+ // // Remove multiple white-spaces, tabs and new-lines
1052
+ // $pattern = '/\s+/S';
1053
+ // $content = preg_replace( $pattern, ' ', $content );
1054
+ //
1055
+ // // Strip out whitespace
1056
+ // //$content = preg_replace( "/[\r\n]+/", "", $content );
1057
+ //
1058
+ // return $content;
1059
+ // }
1060
+
1061
+ /**
1062
+ * Return an array of easing options
1063
+ *
1064
+ * @since 3.0
1065
+ * @var $eases array
1066
+ */
1067
+ function ditty_ease_array() {
1068
+ $eases = array(
1069
+ 'linear','swing','jswing','easeInQuad','easeInCubic','easeInQuart','easeInQuint','easeInSine','easeInExpo','easeInCirc','easeInElastic','easeInBack','easeInBounce','easeOutQuad','easeOutCubic','easeOutQuart','easeOutQuint','easeOutSine','easeOutExpo','easeOutCirc','easeOutElastic','easeOutBack','easeOutBounce','easeInOutQuad','easeInOutCubic','easeInOutQuart','easeInOutQuint','easeInOutSine','easeInOutExpo','easeInOutCirc','easeInOutElastic','easeInOutBack','easeInOutBounce'
1070
+ );
1071
+ return array_combine( $eases, $eases );
1072
+ }
1073
+
1074
+ /**
1075
+ * Return an array of slider transitions
1076
+ *
1077
+ * @since 3.0
1078
+ * @var $eases array
1079
+ */
1080
+ function ditty_slider_transitions() {
1081
+ $transitions = array(
1082
+ 'fade' => __( 'Fade', 'ditty-news-ticker' ),
1083
+ 'slideLeft' => __( 'Slide Left', 'ditty-news-ticker' ),
1084
+ 'slideRight' => __( 'Slide Right', 'ditty-news-ticker' ),
1085
+ 'slideDown' => __( 'Slide Down', 'ditty-news-ticker' ),
1086
+ 'slideUp' => __( 'Slide Up', 'ditty-news-ticker' ),
1087
+ );
1088
+ return $transitions;
1089
+ }
1090
+
1091
+ /**
1092
+ * Return an array of border style options
1093
+ *
1094
+ * @since 3.0
1095
+ * @var $eases array
1096
+ */
1097
+ function ditty_border_styles_array() {
1098
+ $styles = array(
1099
+ 'none', 'dotted','dashed','solid','double','groove','ridge','inset','outset','hidden'
1100
+ );
1101
+ return array_combine( $styles, array_map( 'ucfirst', $styles ) );
1102
+ }
1103
+
1104
+ /**
1105
+ * Prepare display items
1106
+ *
1107
+ * @since 3.0
1108
+ * @var $eases array
1109
+ */
1110
+ function ditty_prepare_display_items( $meta ) {
1111
+ if ( is_object( $meta ) ) {
1112
+ $meta = ( array ) $meta;
1113
+ }
1114
+ $prepared_items = array();
1115
+ if ( ! $item_type_object = ditty_item_type_object( $meta['item_type'] ) ) {
1116
+ return $prepared_items();
1117
+ }
1118
+ $defaults = $item_type_object->default_settings();
1119
+ $args = shortcode_atts( $defaults, $meta['item_value'] );
1120
+ $meta['item_value'] = $args;
1121
+
1122
+ return $item_type_object->prepare_items( $meta );
1123
+ }
1124
+
1125
+ /**
1126
+ * Sanitize array values
1127
+ *
1128
+ * @since 3.0
1129
+ * @var $eases array
1130
+ */
1131
+ // function ditty_sanitize_array( $values ) {
1132
+ // if ( ! is_array( $values ) ) {
1133
+ // return $values;
1134
+ // }
1135
+ // $sanitized_values = array();
1136
+ // if ( is_array( $values ) && count( $values ) > 0 ) {
1137
+ // foreach ( $values as $key => $value ) {
1138
+ // $sanitized_values[$key] = sanitize_text_field( $value );
1139
+ // }
1140
+ // }
1141
+ // return $sanitized_values;
1142
+ // }
1143
+
1144
+ /**
1145
+ * Render the Ditty container
1146
+ *
1147
+ * @since 3.0
1148
+ */
1149
+ function ditty_render( $atts ) {
1150
+ global $ditty_singles;
1151
+ if ( empty( $ditty_singles ) ) {
1152
+ $ditty_singles = array();
1153
+ }
1154
+
1155
+ $defaults = array(
1156
+ 'id' => '',
1157
+ 'display' => '',
1158
+ 'display_settings' => '',
1159
+ 'uniqid' => '',
1160
+ 'class' => '',
1161
+ 'show_editor' => 0,
1162
+ 'load_type' => '',
1163
+ );
1164
+ $args = shortcode_atts( $defaults, $atts );
1165
+
1166
+ // Make sure the ditty exists & is published
1167
+ if ( ! ditty_exists( intval( $args['id'] ) ) ) {
1168
+ return false;
1169
+ }
1170
+ if ( ! is_admin() && 'publish' !== get_post_status( intval( $args['id'] ) ) ) {
1171
+ return false;
1172
+ }
1173
+
1174
+ if ( '' == $args['uniqid'] ) {
1175
+ $args['uniqid'] = uniqid( 'ditty-' );
1176
+ }
1177
+
1178
+ $class = 'ditty ditty--pre';
1179
+ if ( '' != $args['class'] ) {
1180
+ $class .= ' ' . esc_attr( $args['class'] );
1181
+ }
1182
+
1183
+ $ditty_settings = get_post_meta( $args['id'], '_ditty_settings', true );
1184
+ $ajax_load = ( isset( $ditty_settings['ajax_loading'] ) && 'yes' == $ditty_settings['ajax_loading'] ) ? '1' : 0;
1185
+ $live_updates = ( isset( $ditty_settings['live_updates'] ) && 'yes' == $ditty_settings['live_updates'] ) ? '1' : 0;
1186
+
1187
+ ditty_add_scripts( $args['id'], $args['display']);
1188
+
1189
+ $ditty_atts = array(
1190
+ 'class' => $class,
1191
+ 'data-id' => $args['id'],
1192
+ 'data-uniqid' => $args['uniqid'],
1193
+ 'data-display' => ( '' != $args['display'] ) ? $args['display'] : false,
1194
+ 'data-display_settings' => ( '' != $args['display_settings'] ) ? $args['display_settings'] : false,
1195
+ 'data-show_editor' => ( 0 != intval( $args['show_editor'] ) ) ? '1' : false,
1196
+ 'data-load_type' => ( '' != $args['load_type'] ) ? $args['load_type'] : false,
1197
+ 'data-ajax_load' => $ajax_load,
1198
+ 'data-live_updates' => $live_updates,
1199
+ );
1200
+
1201
+ if ( 0 == $ajax_load ) {
1202
+ $ditty_singles[] = $ditty_atts;
1203
+ }
1204
+ return '<div ' . ditty_attr_to_html( $ditty_atts ) . '></div>';
1205
+ }
1206
+
1207
+ /**
1208
+ * Parse ditty script types and add to global
1209
+ *
1210
+ * @since 3.0
1211
+ */
1212
+ function ditty_add_scripts( $ditty_id, $display = '' ) {
1213
+
1214
+ global $ditty_item_scripts;
1215
+ if ( empty( $ditty_item_scripts ) ) {
1216
+ $ditty_item_scripts = array();
1217
+ }
1218
+ global $ditty_display_scripts;
1219
+ if ( empty( $ditty_display_scripts ) ) {
1220
+ $ditty_display_scripts = array();
1221
+ }
1222
+
1223
+ // Store the item types
1224
+ $items = Ditty()->db_items->get_items( $ditty_id );
1225
+ if ( is_array( $items ) && count( $items ) > 0 ) {
1226
+ foreach ( $items as $i => $item ) {
1227
+ if ( $item_type_object = ditty_item_type_object( $item->item_type ) ) {
1228
+ if ( $script_id = $item_type_object->get_script_id() ) {
1229
+ $ditty_item_scripts[$script_id] = $script_id;
1230
+ }
1231
+ }
1232
+ }
1233
+ }
1234
+
1235
+ // Store the display types
1236
+ if ( '' === $display ) {
1237
+ $display = get_post_meta( $ditty_id, '_ditty_display', true );
1238
+ }
1239
+ $display_obj = new Ditty_Display( $display );
1240
+ $display_type = $display_obj->get_display_type();
1241
+ $ditty_display_scripts[$display_type] = $display_type;
1242
+ }
1243
+
1244
+ /**
1245
+ * Return formatted content
1246
+ *
1247
+ * @since 3.0
1248
+ */
1249
+ function ditty_formatted_content( $content, $args=array() ) {
1250
+ $defaults = array(
1251
+ 'wp_kses_post' => true,
1252
+ 'stripslashes' => true,
1253
+ 'wptexturize' => true,
1254
+ 'convert_chars' => true,
1255
+ 'wpautop' => true,
1256
+ 'do_shortcode' => true,
1257
+ );
1258
+ $atts = wp_parse_args( $args, $defaults );
1259
+
1260
+ if ( $atts['wp_kses_post'] ) {
1261
+ $content = wp_kses_post( $content );
1262
+ }
1263
+ if ( $atts['stripslashes'] ) {
1264
+ $content = stripslashes( $content );
1265
+ }
1266
+ if ( $atts['wptexturize'] ) {
1267
+ $content = wptexturize( $content );
1268
+ }
1269
+ if ( $atts['convert_chars'] ) {
1270
+ $content = convert_chars( $content );
1271
+ }
1272
+ if ( $atts['wpautop'] ) {
1273
+ $content = wpautop( $content );
1274
+ }
1275
+ if ( $atts['do_shortcode'] ) {
1276
+ $content = do_shortcode( $content );
1277
+ }
1278
+ return $content;
1279
+ }
1280
+
1281
+ /**
1282
+ * Check if a Ditty license is active
1283
+ *
1284
+ * @since 3.0
1285
+ * @access public
1286
+ * @var bool
1287
+ */
1288
+ function ditty_get_license_status( $extension ) {
1289
+ return Ditty()->extensions->get_license_status( $extension );
1290
+ }
1291
+
1292
+ /**
1293
+ * Convert an array to element attributes
1294
+ *
1295
+ * @since 3.0
1296
+ * @access public
1297
+ * @var bool
1298
+ */
1299
+ function ditty_attr_to_html( $attr = array() ) {
1300
+ $html_array = array();
1301
+ if ( is_array( $attr ) && count( $attr ) > 0 ) {
1302
+ foreach ( $attr as $name => $value ) {
1303
+ if ( false === $value ) {
1304
+ continue;
1305
+ }
1306
+ $html_array[] = $name . '="' . esc_attr( $value ) . '"';
1307
+ }
1308
+ }
1309
+ if ( ! empty( $html_array ) ) {
1310
+ return implode( ' ', $html_array );
1311
+ }
1312
+ }
1313
+
1314
+ /**
1315
+ * Get global Ditty
1316
+ *
1317
+ * @since 3.0
1318
+ * @var array $parsed_atts
1319
+ */
1320
+ function ditty_get_globals() {
1321
+ $prepared_ditty = array();
1322
+ $global_ditty = ditty_settings( 'global_ditty' );
1323
+ if ( is_array( $global_ditty ) && count( $global_ditty ) > 0 ) {
1324
+ foreach ( $global_ditty as $i => &$ditty ) {
1325
+ $ditty_settings = get_post_meta( $ditty['ditty'], '_ditty_settings', true );
1326
+ $ditty['selector'] = html_entity_decode( $ditty['selector'] );
1327
+ $ditty['live_updates'] = ( isset( $ditty_settings['live_updates'] ) && 'yes' == $ditty_settings['live_updates'] ) ? '1' : 0;
1328
+ $prepared_ditty[] = $ditty;
1329
+ }
1330
+ }
1331
+ return $prepared_ditty;
1332
+ }
1333
+
1334
+ /**
1335
+ * Convert an array to element attributes
1336
+ *
1337
+ * @since 3.0
1338
+ * @var string
1339
+ */
1340
+ function ditty_help_icon( $str = '' ) {
1341
+ if ( '' === $str ) {
1342
+ return false;
1343
+ }
1344
+ return '<i class="ditty-help-icon protip fas fa-question-circle" data-pt-title="' . $str . '"></i>';
1345
+ }
1346
+
1347
+ /**
1348
+ * Encrypt values
1349
+ *
1350
+ * @since 3.0
1351
+ * @var string $output
1352
+ */
1353
+ function ditty_encrypt( $string = '', $key_1 = 'pbQttfc*y2bdNV', $key_2 = '3tq!D6AK@XpVz4' ) {
1354
+ $key = hash( 'sha256', $key_1 );
1355
+ $iv = substr( hash( 'sha256', $key_2 ), 0, 16 );
1356
+ $output = base64_encode( openssl_encrypt( $string, "AES-256-CBC", $key, 0, $iv ) );
1357
+ return $output;
1358
+ }
1359
+
1360
+ /**
1361
+ * Decrypt values
1362
+ *
1363
+ * @since 3.0
1364
+ * @var string $output
1365
+ */
1366
+ function ditty_decrypt( $string = '', $key_1 = 'pbQttfc*y2bdNV', $key_2 = '3tq!D6AK@XpVz4' ) {
1367
+ $key = hash( 'sha256', $key_1 );
1368
+ $iv = substr( hash( 'sha256', $key_2 ), 0, 16 );
1369
+ $output = openssl_decrypt( base64_decode( $string ), "AES-256-CBC", $key, 0, $iv );
1370
+ return $output;
1371
+ }
1372
+
1373
+ /**
1374
+ * Decrypt values
1375
+ *
1376
+ * @since 3.0
1377
+ * @var string $output
1378
+ */
1379
+ function ditty_news_ticker_enabled() {
1380
+ if ( '' != ditty_settings( 'ditty_news_ticker' ) ) {
1381
+ return true;
1382
+ }
1383
+ }
1384
+
1385
+ /**
1386
+ * Return the current version
1387
+ *
1388
+ * @since 3.0
1389
+ * @var string $output
1390
+ */
1391
+ function ditty_version() {
1392
+ return DITTY_VERSION;
1393
+ }
1394
+
1395
+ /**
1396
+ * Retrieve meta field for a item.
1397
+ *
1398
+ * @since 3.0
1399
+ */
1400
+ function ditty_item_get_meta( $item_id, $meta_key = '', $single = true ) {
1401
+ if ( $draft_meta = ditty_draft_item_get_meta( $item_id, $meta_key ) ) {
1402
+ return $draft_meta;
1403
+ } else {
1404
+ return Ditty()->db_item_meta->get_meta( $item_id, $meta_key, $single );
1405
+ }
1406
+ }
1407
+
1408
+ /**
1409
+ * Add meta data field to a item.
1410
+ *
1411
+ * @since 3.0
1412
+ */
1413
+ function ditty_item_add_meta( $item_id, $meta_key = '', $meta_value, $unique = false ) {
1414
+ return Ditty()->db_item_meta->add_meta( $item_id, $meta_key, $meta_value, $unique );
1415
+ }
1416
+
1417
+ /**
1418
+ * Update item meta field based on item ID.
1419
+ *
1420
+ * @since 3.0
1421
+ */
1422
+ function ditty_item_update_meta( $item_id, $meta_key = '', $meta_value, $prev_value = '' ) {
1423
+ return Ditty()->db_item_meta->update_meta( $item_id, $meta_key, $meta_value, $prev_value );
1424
+ }
1425
+
1426
+ /**
1427
+ * Remove metadata matching criteria from a item.
1428
+ *
1429
+ * @since 3.0
1430
+ */
1431
+ function ditty_item_delete_meta( $item_id, $meta_key = '', $meta_value = '' ) {
1432
+ return Ditty()->db_item_meta->delete_meta( $item_id, $meta_key, $meta_value );
1433
+ }
1434
+
1435
+ /**
1436
+ * Get all item meta for a specified item.
1437
+ *
1438
+ * @since 3.0
1439
+ */
1440
+ function ditty_item_custom_meta( $item_id ) {
1441
+ return Ditty()->db_item_meta->custom_meta( $item_id );
1442
+ }
includes/hooks.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Delete items from deleted Dittys
5
+ *
6
+ * @since 3.0
7
+ * @access public
8
+ * @var null
9
+ */
10
+ function ditty_delete_post_items( $post_id ) {
11
+ global $post;
12
+ if ( isset( $post->post_type ) && ! ( 'ditty' == $post->post_type ) ) {
13
+ return $post_id;
14
+ }
15
+
16
+ // don't save if user doesn't have permission
17
+ if ( ! current_user_can( 'delete_dittys', $post_id ) ) {
18
+ return $post_id;
19
+ }
20
+
21
+ // Delete a Ditty's items
22
+ $items_meta = ditty_items_meta( $post_id );
23
+ if ( is_array( $items_meta ) && count( $items_meta ) > 0 ) {
24
+ foreach ( $items_meta as $i => $item ) {
25
+ Ditty()->db_items->delete( $item->item_id );
26
+ }
27
+ }
28
+ }
29
+ add_action( 'delete_post', 'ditty_delete_post_items' );
30
+
31
+ /**
32
+ * Check post content for Ditty blocks
33
+ *
34
+ * @since 3.0
35
+ * @access public
36
+ * @var null
37
+ */
38
+ function ditty_check_content_for_blocks() {
39
+
40
+ // Parse post content for Ditty blocks
41
+ if ( is_admin() ) {
42
+ return false;
43
+ }
44
+
45
+ // Parse widgets for Ditty blocks
46
+ $widget_blocks = get_option( 'widget_block' );
47
+ if ( is_array( $widget_blocks ) && count( $widget_blocks ) > 0 ) {
48
+ foreach ( $widget_blocks as $i => $widget_block ) {
49
+ if ( ! is_array( $widget_block ) ) {
50
+ continue;
51
+ }
52
+ $blocks = parse_blocks( $widget_block['content'] );
53
+ if ( is_array( $blocks ) && count( $blocks ) > 0 ) {
54
+ foreach ( $blocks as $i => $block ) {
55
+ if ( 'metaphorcreations/ditty-block' === $block['blockName'] ) {
56
+ $ditty = $block['attrs']['ditty'];
57
+ $display = isset( $block['attrs']['display'] ) ? $block['attrs']['display'] : '';
58
+ ditty_add_scripts( $ditty, $display );
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+
65
+ // Parse post content for Ditty blocks
66
+ if ( ! is_singular() ) {
67
+ return false;
68
+ }
69
+ global $post;
70
+ $blocks = parse_blocks( $post->post_content );
71
+ if ( is_array( $blocks ) && count( $blocks ) > 0 ) {
72
+ foreach ( $blocks as $i => $block ) {
73
+ if ( 'metaphorcreations/ditty-block' === $block['blockName'] ) {
74
+ $ditty = $block['attrs']['ditty'];
75
+ $display = isset( $block['attrs']['display'] ) ? $block['attrs']['display'] : '';
76
+ ditty_add_scripts( $ditty, $display );
77
+ }
78
+ }
79
+ }
80
+ }
81
+ add_filter( 'wp', 'ditty_check_content_for_blocks' );
82
+
83
+
84
+ /**
85
+ * Customize wp_kses allowed html
86
+ *
87
+ * @since 3.0
88
+ * @access public
89
+ * @var array $allowed
90
+ */
91
+ function ditty_kses_allowed_html( $allowed, $context ) {
92
+ if ( is_array( $context ) ) {
93
+ return $allowed;
94
+ }
95
+
96
+ if ( 'post' == $context ) {
97
+ $allowed['a']['nofollow'] = true;
98
+ }
99
+
100
+ return $allowed;
101
+ }
102
+ add_filter( 'wp_kses_allowed_html', 'ditty_kses_allowed_html', 10, 2 );
103
+
104
+ /**
105
+ * Filter the available item tags for layout editing
106
+ *
107
+ * @since 3.0
108
+ */
109
+ function ditty_default_layout_tags_list( $tags, $item_type ) {
110
+ if ( 'default' == $item_type || 'wp_editor' == $item_type ) {
111
+ $allowed_tags = array(
112
+ 'content',
113
+ );
114
+ $tags = array_intersect_key( $tags, array_flip( $allowed_tags ) );
115
+ }
116
+ return $tags;
117
+ }
118
+ add_filter( 'ditty_layout_tags_list', 'ditty_default_layout_tags_list', 10, 2 );
119
+
120
+ /**
121
+ * Add custom classes to style menu items
122
+ *
123
+ * @since 3.0
124
+ * @access public
125
+ * @var array $allowed
126
+ */
127
+ function ditty_dashboard_menu_classes( $classes ) {
128
+ if ( 'disabled' == ditty_settings( 'ditty_layout_ui' ) ) {
129
+ $classes .= ' ditty_layout_ui--disabled';
130
+ }
131
+ if ( 'disabled' == ditty_settings( 'ditty_display_ui' ) ) {
132
+ $classes .= ' ditty_display_ui--disabled';
133
+ }
134
+ return $classes;
135
+ }
136
+ add_filter( 'admin_body_class', 'ditty_dashboard_menu_classes', 99 );
includes/img/d.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69.31 71.1" fill="currentColor"><path d="M0 46.4c0-17.2 8.6-29.1 24.6-29.1a19.93 19.93 0 0 1 6.6 1V0H45v59.2l1 10.3H34.2l-.9-5.2h-.5a15.21 15.21 0 0 1-13 6.8C3.8 71.1 0 58.4 0 46.4Zm31.2 7.4V28.6a13.7 13.7 0 0 0-6-1.3c-8.7 0-11.3 8.7-11.3 17.8 0 8.5 1.9 15.8 8.9 15.8 5.1 0 8.4-3.8 8.4-7.1ZM61.91 65.6a7 7 0 0 1-7.2-7.4c0-5 2.8-7.7 7.1-7.7s7.5 2.6 7.5 7.4c0 5.1-3.1 7.7-7.4 7.7ZM61.91 43.1a7 7 0 0 1-7.2-7.4c0-5 2.8-7.7 7.1-7.7s7.5 2.6 7.5 7.4c0 5.1-3.1 7.7-7.4 7.7ZM61.91 20.6a7 7 0 0 1-7.2-7.4c0-5 2.8-7.7 7.1-7.7s7.5 2.6 7.5 7.4c0 5.1-3.1 7.7-7.4 7.7Z"/></svg>
includes/img/ditty-logo-black.png ADDED
Binary file
includes/index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden
includes/js/admin/class-ditty-extension.js ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Ditty Extension class
3
+ *
4
+ * @since 3.0
5
+ * @return null
6
+ */
7
+
8
+ (function ($) {
9
+ 'use strict';
10
+
11
+ var defaults = {
12
+ };
13
+
14
+ var Ditty_Extension = function ( elmt, options ) {
15
+
16
+ this.elmt = elmt;
17
+ this.settings = $.extend( {}, defaults, $.ditty_extension.defaults, options );
18
+ this.$elmt = $( elmt );
19
+ this.$panels = $( elmt ).find( '.ditty-extension__panels' );
20
+ this.initPanel = this.$panels.data( 'init_panel' );
21
+
22
+ this._init();
23
+ };
24
+
25
+ Ditty_Extension.prototype = {
26
+
27
+ _init: function () {
28
+
29
+ // Add listeners
30
+ this.$elmt.on( 'click', '.ditty-extension__tab', { self: this }, this._tabClick );
31
+ this.$elmt.on( 'click', 'button[name="submit"]', { self: this }, this._updatePanel );
32
+ this.$elmt.on( 'click', '.ditty-extension__license__submit', { self: this, action: 'ditty_extension_license_activate' }, this._licenseUpdate );
33
+ this.$elmt.on( 'click', '.ditty-extension__license__refresh', { self: this, action: 'ditty_extension_license_refresh' }, this._licenseUpdate );
34
+ this.$elmt.on( 'click', '.ditty-extension__license__deactivate', { self: this, action: 'ditty_extension_license_deactivate' }, this._licenseUpdate );
35
+ this.$panels.on( 'ditty_slider_before_slide_update', { self: this }, this._beforePanelUpdate );
36
+ this._initSlider();
37
+ },
38
+
39
+ /**
40
+ * Initialize the slider
41
+ *
42
+ * @since 3.0
43
+ * @return null
44
+ */
45
+ _initSlider: function () {
46
+ var args = {
47
+ transition : 'fade',
48
+ transitionSpeed : 0.75,
49
+ heightSpeed : 0.75,
50
+ touchSwipe : false,
51
+ slidesEl : '.ditty-extension__panel',
52
+ slideId : ( '' !== this.initPanel ) ? this.initPanel : false
53
+ };
54
+ this.$panels.ditty_slider( args );
55
+ },
56
+
57
+ /**
58
+ * Initialize the slider
59
+ *
60
+ * @since 3.0
61
+ * @return null
62
+ */
63
+ _beforePanelUpdate: function ( e, index, slide ) {
64
+ var self = e.data.self;
65
+ self.$elmt.find( '.ditty-extension__tab' ).removeClass( 'active' );
66
+ self.$elmt.find( '.ditty-extension__tab[data-slide_id="' + slide.id + '"]' ).addClass( 'active' );
67
+ },
68
+
69
+ /**
70
+ * Tab click
71
+ *
72
+ * @since 3.0
73
+ * @return null
74
+ */
75
+ _tabClick: function ( e ) {
76
+ e.preventDefault();
77
+ var self = e.data.self;
78
+ var $tab = $( this ),
79
+ slideId = $tab.data( 'slide_id' ),
80
+ transition = 'slideLeft',
81
+ $currentTab = self.$elmt.find( '.ditty-extension__tab.active' );
82
+
83
+ if ( $currentTab === $tab ) {
84
+ return false;
85
+ }
86
+
87
+ if ( $tab.index() < $currentTab.index() ) {
88
+ transition = 'slideRight';
89
+ }
90
+
91
+ //self.$elmt.find( '.ditty-extension__tab' ).removeClass( 'active' );
92
+ //$tab.addClass( 'active' );
93
+
94
+ self.$panels.ditty_slider( 'options', 'transition', transition );
95
+ self.$panels.ditty_slider( 'showSlideById', slideId );
96
+ },
97
+
98
+ /**
99
+ * Panel update listener
100
+ *
101
+ * @since 3.0
102
+ * @return null
103
+ */
104
+ _updatePanel: function ( e ) {
105
+ e.preventDefault();
106
+ var self = e.data.self;
107
+
108
+ var $button = $( this ),
109
+ $panel = $button.parents( '.ditty-extension__panel' ),
110
+ $form = $button.parents( '.ditty-extension__form' ),
111
+ $icon = $button.find( 'i' ),
112
+ iconClass = $icon.attr( 'class' ),
113
+ extension = self.$elmt.data( 'extension' ),
114
+ panel = $panel.data( 'slide_id' );
115
+
116
+ if ( self.$elmt.hasClass( 'updating' ) ) {
117
+ return false;
118
+ }
119
+
120
+ self.$elmt.addClass( 'updating' );
121
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
122
+
123
+ $form.ajaxSubmit( {
124
+ url : dittyAdminVars.ajaxurl,
125
+ type : 'post',
126
+ dataType : 'json',
127
+ data : {
128
+ action : 'ditty_extension_panel_update',
129
+ extension : extension,
130
+ panel : panel,
131
+ security : dittyAdminVars.security
132
+ },
133
+ success: function( response ) {
134
+ $icon.attr( 'class', iconClass );
135
+ self.$elmt.removeClass( 'updating' );
136
+ $( '#ditty-extensions' ).trigger( 'ditty_extension_panel_updated', [ response, self.$elmt, $panel ] );
137
+ }
138
+ } );
139
+ },
140
+
141
+ /**
142
+ * Update a license
143
+ *
144
+ * @since 3.0
145
+ * @return null
146
+ */
147
+ _licenseUpdate: function ( e ) {
148
+ e.preventDefault();
149
+ var self = e.data.self,
150
+ action = e.data.action;
151
+
152
+ var $button = $( this ),
153
+ $message = self.$elmt.find( '.ditty-extension__license__message' ),
154
+ $input = $button.siblings( '.ditty-extension__license__input' ),
155
+ license = $input.val(),
156
+ extension = $button.data( 'extension' ),
157
+ extensionId = $button.data( 'extension_id' ),
158
+ extensionName = $button.data( 'extension_name' ),
159
+ $icon = $button.children( 'i' );
160
+
161
+ if ( self.$elmt.hasClass( 'updating' ) ) {
162
+ return false;
163
+ }
164
+
165
+ self.$elmt.addClass( 'updating' );
166
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
167
+
168
+ // Load the new display data
169
+ var data = {
170
+ action : action,
171
+ license : license,
172
+ extension : extension,
173
+ extension_id : extensionId,
174
+ extension_name : extensionName,
175
+ security : dittyAdminVars.security
176
+ };
177
+ $.post( dittyAdminVars.ajaxurl, data, function( response ) {
178
+ if ( response ) {
179
+ self.$elmt.attr( 'data-license_status', response.status );
180
+ $message.text( response.message );
181
+ }
182
+ if ( response.license_key ) {
183
+ if ( 'DELETE' === response.license_key ) {
184
+ $input.val( '' );
185
+ } else {
186
+ $input.val( response.license_key );
187
+ }
188
+ }
189
+ $icon.attr( 'class', $icon.data( 'class' ) );
190
+ self.$elmt.removeClass( 'updating' );
191
+ }, 'json' );
192
+ },
193
+
194
+ /**
195
+ * Return data for the object
196
+ *
197
+ * @since 3.0
198
+ * @return null
199
+ */
200
+ _getOption: function( key ) {
201
+ switch( key ) {
202
+ default:
203
+ return this.settings[key];
204
+ }
205
+ },
206
+
207
+ /**
208
+ * Set data for the object
209
+ *
210
+ * @since 3.0
211
+ * @return null
212
+ */
213
+ _setOption: function( key, value ) {
214
+ if ( undefined === value ) {
215
+ return false;
216
+ }
217
+
218
+ this.settings[key] = value;
219
+ },
220
+
221
+ /**
222
+ * Get or set ditty options
223
+ *
224
+ * @since 3.0
225
+ * @return null
226
+ */
227
+ options: function ( key, value ) {
228
+ var self = this;
229
+ if ( typeof key === 'object' ) {
230
+ $.each( key, function( k, v ) {
231
+ self._setOption( k, v );
232
+ });
233
+ } else if ( typeof key === 'string' ) {
234
+ if ( value === undefined ) {
235
+ return self._getOption( key );
236
+ }
237
+ self._setOption( key, value );
238
+ } else {
239
+ return self.settings;
240
+ }
241
+ },
242
+
243
+ /**
244
+ * Destroy this object
245
+ *
246
+ * @since 3.0
247
+ * @return null
248
+ */
249
+ destroy: function () {
250
+ // Remove listeners
251
+ this.$elmt.off( 'click', '.ditty-extension__tab', { self: this }, this._tabClick );
252
+ this.$elmt.off( 'click', 'button[name="submit"]', { self: this }, this._updatePanel );
253
+ this.$elmt.off( 'click', '.ditty-extension__license__submit, .ditty-extension__license__refresh', { self: this, action: 'ditty_extension_license_activate' }, this._licenseUpdate );
254
+ this.$elmt.off( 'click', '.ditty-extension__license__deactivate', { self: this, action: 'ditty_extension_license_deactivate' }, this._licenseUpdate );
255
+ this.$panels.off( 'ditty_slider_after_slide_update', { self: this }, this._afterPanelUpdate );
256
+
257
+ this.$panels.ditty_slider( 'destroy' );
258
+ this.elmt._ditty_extension = null;
259
+ }
260
+ };
261
+
262
+ $.fn.ditty_extension = function( options ) {
263
+ var args = arguments,
264
+ error = false,
265
+ returns;
266
+
267
+ if ( options === undefined || typeof options === 'object' ) {
268
+ return this.each( function () {
269
+ if ( ! this._ditty_extension ) {
270
+ this._ditty_extension = new Ditty_Extension( this, options );
271
+ }
272
+ });
273
+ } else if ( typeof options === 'string' ) {
274
+ this.each( function () {
275
+ var instance = this._ditty_extension;
276
+
277
+ if ( ! instance ) {
278
+ throw new Error( 'No Ditty_Extension applied to this element.' );
279
+ }
280
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
281
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
282
+ } else {
283
+ error = true;
284
+ }
285
+ } );
286
+
287
+ if ( error ) {
288
+ throw new Error( 'No method "' + options + '" in Ditty_Extension.' );
289
+ }
290
+
291
+ return returns !== undefined ? returns : this;
292
+ }
293
+ };
294
+
295
+ $.ditty_extension = {};
296
+ $.ditty_extension.defaults = defaults;
297
+
298
+ } )( jQuery );
includes/js/admin/class-ditty-settings.js ADDED
@@ -0,0 +1,453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Ditty Settings
3
+ *
4
+ * @since 3.0
5
+ * @return null
6
+ */
7
+
8
+ (function ($) {
9
+ 'use strict';
10
+
11
+ var defaults = {
12
+ };
13
+
14
+ var Ditty_Settings = function ( elmt, options ) {
15
+
16
+ this.elmt = elmt;
17
+ this.settings = $.extend( {}, defaults, $.ditty_settings.defaults, options );
18
+ this.$elmt = $( elmt );
19
+ this.$form = this.$elmt.find( '.ditty-settings__form' );
20
+ this.$panels = this.$elmt.find( '.ditty-settings__panels' );
21
+ this.saveBtns = this.$elmt.find( '.ditty-settings__save' );
22
+ this.tabs = this.$elmt.find( '.ditty-settings__tab' );
23
+ this.$notice_update = this.$elmt.find( '.ditty-notification--updated' );
24
+ this.$notice_error = this.$elmt.find( '.ditty-notification--error' );
25
+ this.$notice_warning = this.$elmt.find( '.ditty-notification--warning' );
26
+ this.initData = null;
27
+ this._init();
28
+ };
29
+
30
+
31
+ Ditty_Settings.prototype = {
32
+
33
+ /**
34
+ * Initialize the data list
35
+ *
36
+ * @since 3.0
37
+ * @return null
38
+ */
39
+ _init: function () {
40
+
41
+ // Initialize the slider
42
+ this._initSlider();
43
+
44
+ // Add listeners
45
+ $( 'body' ).on( 'ditty_field_clone_update', { self: this }, this._enableSettingsUpdates );
46
+ this.saveBtns.on( 'click', { self: this }, this._submitForm );
47
+ this.tabs.on( 'click', { self: this }, this._tabClick );
48
+ this.$panels.on( 'ditty_slider_init', { self: this }, this._sliderInit );
49
+ this.$panels.on( 'ditty_slider_before_slide_update', { self: this }, this._beforeSlideUpdate );
50
+ this.$form.on( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
51
+ this.$form.on( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
52
+ this.$form.on( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
53
+ this.$form.on( 'click', '.ditty-default-layout-install', { self: this }, this._installLayout );
54
+ this.$form.on( 'click', '.ditty-default-display-install', { self: this }, this._installDisplay );
55
+ },
56
+
57
+ /**
58
+ * Initialize the extensions
59
+ *
60
+ * @since 3.0
61
+ * @return null
62
+ */
63
+ _initSlider: function () {
64
+ var initPanel = this.$panels.data( 'init_panel' );
65
+ this.$panels.ditty_slider( {
66
+ transition : 'fade',
67
+ transitionSpeed : 0.75,
68
+ heightSpeed : 0.75,
69
+ touchSwipe : false,
70
+ slidesEl : '.ditty-settings__panel',
71
+ slideId : ( '' !== initPanel ) ? initPanel : false
72
+ } );
73
+ },
74
+
75
+ /**
76
+ * Slider init
77
+ *
78
+ * @since 3.0
79
+ * @return null
80
+ */
81
+ _sliderInit: function( e ) {
82
+ var self = e.data.self;
83
+ self.initData = self.$form.serialize();
84
+ },
85
+
86
+ /**
87
+ * Before slide update
88
+ *
89
+ * @since 3.0
90
+ * @return null
91
+ */
92
+ _beforeSlideUpdate: function( e, index, slide ) {
93
+ var self = e.data.self;
94
+ self._initFields( slide.$elmt );
95
+ self.$elmt.find( '.ditty-settings__tab' ).removeClass( 'active' );
96
+ self.$elmt.find( '.ditty-settings__tab[data-panel="' + slide.id + '"]' ).addClass( 'active' );
97
+ },
98
+
99
+ /**
100
+ * Preview button add updates class
101
+ *
102
+ * @since 3.0
103
+ * @return null
104
+ */
105
+ _enableSettingsUpdates: function( e ) {
106
+ var self = ( e ) ? e.data.self : this;
107
+ self.saveBtns.addClass( 'has-updates' );
108
+ //self.notice_warning.slideDown();
109
+ },
110
+
111
+ /**
112
+ * Preview button remove updates class
113
+ *
114
+ * @since 3.0
115
+ * @return null
116
+ */
117
+ _disableSettingsUpdates: function() {
118
+ this.saveBtns.removeClass( 'has-updates' );
119
+ },
120
+
121
+ /**
122
+ * Check for updates
123
+ *
124
+ * @since 3.0
125
+ * @return null
126
+ */
127
+ _checkUpdates: function( e ) {
128
+ var self = e ? e.data.self : this;
129
+ var currentData = self.$form.serialize();
130
+ if ( currentData !== self.initData ) {
131
+ self._enableSettingsUpdates();
132
+ } else {
133
+ self._disableSettingsUpdates();
134
+ }
135
+ },
136
+
137
+ /**
138
+ * Initialize dynamic fields
139
+ *
140
+ * @since 3.0
141
+ * @return null
142
+ */
143
+ _initFields: function ( $fields ) {
144
+ $fields.find( '.ditty-data-list' ).ditty_ui_data_list();
145
+ $fields.trigger( 'ditty_init_fields' );
146
+ $.protip( {
147
+ defaults: {
148
+ position: 'top',
149
+ size: 'small',
150
+ scheme: 'black',
151
+ classes: 'ditty-protip'
152
+ }
153
+ } );
154
+ },
155
+
156
+ /**
157
+ * Show or hide post types
158
+ *
159
+ * @since 3.0
160
+ * @return null
161
+ */
162
+ _togglePostTypes: function () {
163
+ if ( $( 'input[name="ditty_layout_ui"]' ).length ) {
164
+ var layoutUiVal = $( 'input[name="ditty_layout_ui"]:checked' ).val(),
165
+ $layoutMenu = $( '#adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_layout"]' );
166
+ if ( 'disabled' === layoutUiVal ) {
167
+ $layoutMenu.hide();
168
+ } else {
169
+ $layoutMenu.css( 'display', 'block' );
170
+ }
171
+ }
172
+ if ( $( 'input[name="ditty_display_ui"]' ).length ) {
173
+ var displayUiVal = $( 'input[name="ditty_display_ui"]:checked' ).val(),
174
+ $displayMenu = $( '#adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_display"]' );
175
+ if ( 'disabled' === displayUiVal ) {
176
+ $displayMenu.hide();
177
+ } else {
178
+ $displayMenu.css( 'display', 'block' );
179
+ }
180
+ }
181
+ },
182
+
183
+ /**
184
+ * Listen for a tab click
185
+ *
186
+ * @since 3.0
187
+ * @return null
188
+ */
189
+ _tabClick: function( e ) {
190
+ e.preventDefault();
191
+ var self = e.data.self,
192
+ $tab = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
193
+ slideId = $tab.data( 'panel' ),
194
+ $currentTab = self.$elmt.find( '.ditty-settings__tab.active' );
195
+
196
+ if ( $currentTab === $tab ) {
197
+ return false;
198
+ }
199
+
200
+ self.$elmt.find( '.ditty-extension__tab' ).removeClass( 'active' );
201
+ $tab.addClass( 'active' );
202
+
203
+ self.$panels.ditty_slider( 'showSlideById', slideId );
204
+ },
205
+
206
+ /**
207
+ * Update inputs after save and sanitize
208
+ *
209
+ * @since 3.0
210
+ * @return null
211
+ */
212
+ _upateInputs: function( updates ) {
213
+ $.each( updates, function( inputName, updatedValue ) {
214
+ if ( $( 'input[name="' + inputName + '"]' ).length ) {
215
+ $( 'input[name="' + inputName + '"]' ).val( updatedValue );
216
+ }
217
+ } );
218
+ },
219
+
220
+ /**
221
+ * Submit updates
222
+ *
223
+ * @since 3.0
224
+ * @return null
225
+ */
226
+ _submitForm: function( e ) {
227
+ e.preventDefault();
228
+ var self = e.data.self;
229
+
230
+ if ( self.$elmt.hasClass( 'updating' ) ) {
231
+ return false;
232
+ }
233
+
234
+ self.$elmt.trigger( 'ditty_pre_save_fields' );
235
+ self.$elmt.addClass( 'updating' );
236
+ self.saveBtns.text( dittyAdminVars.adminStrings.settingsSaving );
237
+
238
+ self.$form.ajaxSubmit( {
239
+ url : dittyAdminVars.ajaxurl,
240
+ type : 'post',
241
+ dataType : 'json',
242
+ data : {
243
+ action : 'ditty_settings_save',
244
+ security : dittyAdminVars.security
245
+ },
246
+ success: function( data ) {
247
+ if ( data.input_updates ) {
248
+ self._upateInputs( data.input_updates );
249
+ }
250
+ self.initData = self.$form.serialize();
251
+ self.saveBtns.text( dittyAdminVars.adminStrings.settings_updated );
252
+ setTimeout( function() {
253
+ self.saveBtns.text( dittyAdminVars.adminStrings.settings_save );
254
+ }, 2000 );
255
+ self.$elmt.removeClass( 'updating' );
256
+ self._disableSettingsUpdates();
257
+
258
+ //self.$notice_update.slideDown();
259
+
260
+ // Check the post types display
261
+ self._togglePostTypes();
262
+ }
263
+ } );
264
+ },
265
+
266
+ /**
267
+ * Install a layout
268
+ *
269
+ * @since 3.0
270
+ * @return null
271
+ */
272
+ _installLayout: function( e ) {
273
+ e.preventDefault();
274
+ var self = e.data.self,
275
+ $button = $( e.target ).is( 'button' ) ? $( e.target ) : $( e.target ).parents( 'button' ),
276
+ $icon = $button.find( 'i' ),
277
+ iconClass = $icon.attr( 'class' );
278
+
279
+ if ( $button.hasClass( 'updating' ) ) {
280
+ return false;
281
+ }
282
+ $button.addClass( 'updating' );
283
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
284
+
285
+ var data = {
286
+ action : 'ditty_install_layout',
287
+ layout_template : $button.data( 'layout_template' ),
288
+ layout_version : $button.data( 'layout_version' ),
289
+ security : dittyAdminVars.security
290
+ };
291
+ $.post( dittyAdminVars.ajaxurl, data, function( response ) {
292
+ $icon.attr( 'class', iconClass );
293
+ self.$elmt.removeClass( 'updating' );
294
+ if ( response ) {
295
+ $button.replaceWith( response.button );
296
+ }
297
+ } );
298
+ },
299
+
300
+ /**
301
+ * Install a display
302
+ *
303
+ * @since 3.0
304
+ * @return null
305
+ */
306
+ _installDisplay: function( e ) {
307
+ e.preventDefault();
308
+ var self = e.data.self,
309
+ $button = $( e.target ).is( 'button' ) ? $( e.target ) : $( e.target ).parents( 'button' ),
310
+ $icon = $button.find( 'i' ),
311
+ iconClass = $icon.attr( 'class' );
312
+
313
+ if ( $button.hasClass( 'updating' ) ) {
314
+ return false;
315
+ }
316
+ $button.addClass( 'updating' );
317
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
318
+
319
+ var data = {
320
+ action : 'ditty_install_display',
321
+ display_type : $button.data( 'display_type' ),
322
+ display_template : $button.data( 'display_template' ),
323
+ display_version : $button.data( 'display_version' ),
324
+ security : dittyAdminVars.security
325
+ };
326
+ $.post( dittyAdminVars.ajaxurl, data, function( response ) {
327
+ $icon.attr( 'class', iconClass );
328
+ self.$elmt.removeClass( 'updating' );
329
+ if ( response ) {
330
+ $button.replaceWith( response.button );
331
+ }
332
+ } );
333
+ },
334
+
335
+ /**
336
+ * Return a specific setting
337
+ *
338
+ * @since 3.0
339
+ * @return null
340
+ */
341
+ _options: function ( key ) {
342
+ return this.settings[key];
343
+ },
344
+
345
+ /**
346
+ * Setup triggers
347
+ *
348
+ * @since 3.0
349
+ * @return null
350
+ */
351
+ trigger: function ( fn, customParams ) {
352
+ var params = [this.settings];
353
+ if ( customParams ) {
354
+ params = customParams;
355
+ }
356
+
357
+ this.$elmt.trigger( 'ditty_settings_' + fn, params );
358
+
359
+ if ( typeof this.settings[fn] === 'function' ) {
360
+ this.settings[fn].apply( this.$elmt, params );
361
+ }
362
+ },
363
+
364
+ /**
365
+ * Allow settings to be modified
366
+ *
367
+ * @since 3.0
368
+ * @return null
369
+ */
370
+ options: function ( key, value ) {
371
+
372
+ if ( typeof key === 'object' ) {
373
+ this.settings = $.extend( {}, defaults, $.ditty_settings.defaults, key );
374
+ } else if ( typeof key === 'string' ) {
375
+ if ( value === undefined ) {
376
+ return this.settings[key];
377
+ }
378
+ this.settings[key] = value;
379
+ } else {
380
+ return this.settings;
381
+ }
382
+
383
+ this.trigger( 'options_update' );
384
+ },
385
+
386
+ /**
387
+ * Destroy the editor
388
+ *
389
+ * @since 3.0
390
+ * @return null
391
+ */
392
+ destroy: function () {
393
+
394
+ // Remove listeners
395
+ $( 'body' ).off( 'ditty_field_clone_update', { self: this }, this._enableSettingsUpdates );
396
+ this.saveBtns.off( 'click', { self: this }, this._submitForm );
397
+ this.tabs.off( 'click', { self: this }, this._tabClick );
398
+ this.$panels.off( 'ditty_slider_init', { self: this }, this._sliderInit );
399
+ this.$panels.off( 'ditty_slider_before_slide_update', { self: this }, this._beforeSlideUpdate );
400
+ this.$form.off( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
401
+ this.$form.off( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
402
+ this.$form.off( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
403
+ this.$form.off( 'click', '.ditty-default-layout-install', { self: this }, this._installLayout );
404
+ this.$form.off( 'click', '.ditty-default-display-install', { self: this }, this._installDisplay );
405
+
406
+ this.$panels.ditty_slider( 'destroy' );
407
+ this.elmt._ditty_settings = null;
408
+ }
409
+ };
410
+
411
+ /**
412
+ * Create the data list
413
+ *
414
+ * @since 3.0
415
+ * @return null
416
+ */
417
+ $.fn.ditty_settings = function( options ) {
418
+ var args = arguments,
419
+ error = false,
420
+ returns;
421
+
422
+ if ( options === undefined || typeof options === 'object' ) {
423
+ return this.each( function () {
424
+ if ( ! this._ditty_settings ) {
425
+ this._ditty_settings = new Ditty_Settings( this, options );
426
+ }
427
+ });
428
+ } else if ( typeof options === 'string' ) {
429
+ this.each( function () {
430
+ var instance = this._ditty_settings;
431
+
432
+ if ( ! instance ) {
433
+ throw new Error( 'No Ditty_Settings applied to this element.' );
434
+ }
435
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
436
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
437
+ } else {
438
+ error = true;
439
+ }
440
+ } );
441
+
442
+ if ( error ) {
443
+ throw new Error( 'No method "' + options + '" in Ditty_Settings.' );
444
+ }
445
+
446
+ return returns !== undefined ? returns : this;
447
+ }
448
+ };
449
+
450
+ $.ditty_settings = {};
451
+ $.ditty_settings.defaults = defaults;
452
+
453
+ } )( jQuery );
includes/js/admin/ditty-displays.js ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ jQuery( document ).ready( function( $ ) {
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ var isDisplayPost = ( $( 'input[name="post_type"]' ).length && 'ditty_display' == $( 'input[name="post_type"]' ).val() ),
9
+ ajaxSubmitComplete = false;
10
+
11
+ $( 'form#post' ).on( 'submit', function( e ) {
12
+ if ( isDisplayPost && ! ajaxSubmitComplete ) {
13
+ e.preventDefault();
14
+
15
+ var $button = $( '#publishing-action' ).children( 'input[type="submit"]' ),
16
+ $spinner = $( '#publishing-action' ).children( '.spinner' );
17
+
18
+ $button.attr( 'disabled', 'disabled' );
19
+ $spinner.css( 'visibility', 'visible' );
20
+
21
+ var data = {
22
+ action : 'ditty_admin_display_update',
23
+ display_id : $( 'input[name="post_ID"]' ).val(),
24
+ security : dittyAdminVars.security
25
+ };
26
+ $( '#ditty-display-settings' ).ajaxSubmit( {
27
+ url : dittyAdminVars.ajaxurl,
28
+ type : 'post',
29
+ dataType : 'json',
30
+ data : data,
31
+ success: function( response ) {
32
+ ajaxSubmitComplete = true;
33
+ $( 'form#post' ).submit();
34
+ }
35
+ } );
36
+ }
37
+ } );
38
+
39
+ }() );
40
+
41
+ } );
includes/js/admin/ditty-extensions.js ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ jQuery( document ).ready( function( $ ) {
3
+ // Setup strict mode
4
+ (function() {
5
+
6
+ "use strict";
7
+
8
+ // Setup protip
9
+ $.protip( {
10
+ defaults: {
11
+ position: 'top',
12
+ size: 'small',
13
+ scheme: 'black',
14
+ classes: 'ditty-protip'
15
+ }
16
+ } );
17
+
18
+ /**
19
+ * Listen for an accordion toggle click
20
+ *
21
+ * @since 3.0
22
+ * @return null
23
+ */
24
+ // $( '#ditty-extensions' ).on( 'click', '.ditty-accordion__toggle', function( e ) {
25
+ // e.preventDefault();
26
+ // var $accordion = $( this ).parent(),
27
+ // $content = $( this ).next();
28
+ //
29
+ // if ( $accordion.hasClass( 'active' ) ) {
30
+ // $accordion.removeClass( 'active' );
31
+ // $content.stop().slideUp( { duration: 750, easing: "easeInOutQuint" } );
32
+ // } else {
33
+ // $accordion.addClass( 'active' );
34
+ // $content.stop().slideDown( { duration: 750, easing: "easeInOutQuint" }, function() {
35
+ // $content.css( 'height', 'auto' );
36
+ // } );
37
+ // }
38
+ // } );
39
+ //
40
+ /**
41
+ * Initialize the extensions
42
+ *
43
+ * @since 3.0
44
+ * @return null
45
+ */
46
+ function ditty_extensions_init() {
47
+ $( '#ditty-extensions' ).find( '.ditty-extension' ).each( function( index ) {
48
+
49
+ var $extension = $( this ),
50
+ $panels = $extension.find( '.ditty-extension__panels' );
51
+
52
+ if ( $panels.length ) {
53
+ $extension.ditty_extension();
54
+ }
55
+
56
+ $( '#ditty-extensions' ).trigger( 'ditty_init_fields' );
57
+
58
+ setTimeout( function() {
59
+ $extension.addClass( 'ditty-extension--init' );
60
+ }, index * 250 );
61
+
62
+ } );
63
+ }
64
+ ditty_extensions_init();
65
+
66
+ }() );
67
+
68
+ } );
includes/js/class-ditty-display-list.js ADDED
@@ -0,0 +1,862 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* global dittyEditorInit:true */
3
+ /* global dittyLayoutCss:true */
4
+ /* global dittyUpdateItems:true */
5
+ /* //global console:true */
6
+
7
+ /**
8
+ * Ditty Slider class
9
+ *
10
+ * @since 3.0
11
+ * @return null
12
+ */
13
+
14
+ (function ($) {
15
+ 'use strict';
16
+
17
+ var defaults = {
18
+ id : 0,
19
+ title : '',
20
+ display : 0,
21
+ status : '',
22
+ spacing : 30,
23
+ paging : 0, // 0, 1
24
+ perPage : 0,
25
+ transition : 'fade', // fade, slideLeft, slideREight, slideDown, slideUp
26
+ transitionEase : 'easeInOutQuint',
27
+ transitionSpeed : 1.5, // 1 - 10
28
+ autoplay : 0, // 0, 1
29
+ autoplayPause : 0, // 0, 1
30
+ autoplaySpeed : 8, // 1 - 60
31
+ height : 0,
32
+ heightEase : 'easeInOutQuint',
33
+ heightSpeed : 1.5, // 1 - 10
34
+ arrows : 'none',
35
+ arrowsIconColor : '',
36
+ arrowsBgColor : '',
37
+ arrowsPosition : 'center',
38
+ arrowsPadding : {},
39
+ arrowsStatic : 0,
40
+ navPrev : '<i class="fas fa-angle-left"></i>',
41
+ navNext : '<i class="fas fa-angle-right"></i>',
42
+ bullets : 'none',
43
+ bulletsColor : '',
44
+ bulletsColorActive : '',
45
+ bulletsPosition : 'bottomCenter',
46
+ bulletsSpacing : 2,
47
+ bulletsPadding : {},
48
+ bullet : '',
49
+ maxWidth : '',
50
+ bgColor : '',
51
+ padding : {},
52
+ margin : {},
53
+ borderColor : {},
54
+ borderStyle : {},
55
+ borderWidth : {},
56
+ borderRadius : {},
57
+ contentsBgColor : '',
58
+ contentsPadding : {},
59
+ contentsBorderColor : {},
60
+ contentsBorderStyle : {},
61
+ contentsBorderWidth : {},
62
+ contentsBorderRadius : {},
63
+ pageBgColor : '',
64
+ pagePadding : {},
65
+ pageBorderColor : {},
66
+ pageBorderStyle : {},
67
+ pageBorderWidth : {},
68
+ pageBorderRadius : {},
69
+ itemTextColor : '',
70
+ itemBgColor : '',
71
+ itemBorderColor : {},
72
+ itemBorderStyle : {},
73
+ itemBorderWidth : {},
74
+ itemBorderRadius : {},
75
+ itemPadding : {},
76
+ page : 0,
77
+ shuffle : 0,
78
+ showEditor : 0,
79
+ // init : function () {},
80
+ items : [
81
+ // {
82
+ // id: null,
83
+ // uniq_id: null,
84
+ // parent_id: null,
85
+ // html: null,
86
+ // status: null,
87
+ // ...
88
+ ]
89
+ };
90
+
91
+ var Ditty_List = function ( elmt, options ) {
92
+
93
+ this.displayType = 'list';
94
+ this.elmt = elmt;
95
+ this.$elmt = $( elmt );
96
+ this.settings = $.extend( {}, defaults, $.ditty_list.defaults, options );
97
+ this.total = this.settings.items.length;
98
+ this.totalPages = 1;
99
+ this.page = this.settings.page;
100
+ this.pages = [];
101
+ this.enabledItems = [];
102
+ this.visibleItems = [];
103
+ this.editItem = null;
104
+
105
+ if ( 1 === parseInt( this.settings.shuffle ) ) {
106
+ this.shuffle();
107
+ }
108
+
109
+ this._init();
110
+ };
111
+
112
+ Ditty_List.prototype = {
113
+
114
+ _init: function () {
115
+
116
+ // Remove the pre class
117
+ this.$elmt.removeClass( 'ditty--pre' );
118
+
119
+ // Add classes and data attributes
120
+ this.$elmt.addClass( 'ditty ditty-list' );
121
+ this.$elmt.attr( 'data-id', this.settings.id );
122
+ this.$elmt.attr( 'data-type', this.displayType );
123
+ this.$elmt.attr( 'data-display', this.settings.display );
124
+
125
+ // Calculate the number of pages
126
+ this._calculatePages();
127
+
128
+ // Initialize the slider
129
+ this._initSlider();
130
+
131
+ // Show the editor or start live updates
132
+ if ( this.settings.showEditor ) {
133
+ dittyEditorInit( this );
134
+ } else {
135
+ this.trigger( 'start_live_updates' );
136
+ }
137
+ },
138
+
139
+ /**
140
+ * Initialize the slider
141
+ *
142
+ * @since 3.0
143
+ * @return null
144
+ */
145
+ _initSlider: function () {
146
+
147
+ // Modify any settings to fit a slider
148
+ var sliderSettings = [];
149
+ $.each( this.settings, function( key, value ) {
150
+ var sliderKey = key.replace( 'page', 'slide' );
151
+ sliderSettings[sliderKey] = value;
152
+ } );
153
+ sliderSettings.slides = this.pages;
154
+
155
+ // Create a new slider and bind actions
156
+ this.$elmt.ditty_slider( sliderSettings );
157
+ this.$elmt.on( 'ditty_slider_init', { self: this }, this._triggerInit );
158
+ this.$elmt.on( 'ditty_slider_update', { self: this }, this._triggerUpdate );
159
+ this.$elmt.on( 'ditty_slider_after_slide_update', { self: this }, this._triggerShowSlide );
160
+ },
161
+
162
+ /**
163
+ * Destroy the slider
164
+ *
165
+ * @since 3.0
166
+ * @return null
167
+ */
168
+ _destroySlider: function () {
169
+ if ( this.$elmt.ditty_slider ) {
170
+ this.$elmt.off( 'ditty_slider_init', { self: this }, this._triggerInit );
171
+ this.$elmt.off( 'ditty_slider_update', { self: this }, this._triggerUpdate );
172
+ this.$elmt.off( 'ditty_slider_after_slide_update', { self: this }, this._triggerShowSlide );
173
+ this.$elmt.ditty_slider( 'destroy' );
174
+ }
175
+ },
176
+
177
+ /**
178
+ * Update the slider
179
+ *
180
+ * @since 3.0
181
+ * @return null
182
+ */
183
+ _updateSlider: function ( index ) {
184
+ var newIndex = index ? index : this.$elmt.ditty_slider( 'options', 'slide');
185
+ this.$elmt.ditty_slider( 'options', 'slides', this.settings.pages );
186
+ this.$elmt.ditty_slider( 'options', 'slide', -1 );
187
+ this.$elmt.ditty_slider( 'showSlide', newIndex );
188
+ },
189
+
190
+ /**
191
+ * Style individual items
192
+ *
193
+ * @since 3.0
194
+ * @return null
195
+ */
196
+ _styleItem: function( $item ) {
197
+ $item.children( '.ditty-item__elements' ).css( {
198
+ color: this.settings.itemTextColor,
199
+ backgroundColor: this.settings.itemBgColor,
200
+ borderColor: this.settings.itemBorderColor,
201
+ borderStyle: this.settings.itemBorderStyle
202
+ } );
203
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemPadding );
204
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemBorderRadius );
205
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemBorderWidth );
206
+ $item.css( {
207
+ paddingBottom: this.settings.spacing + 'px'
208
+ } );
209
+ },
210
+
211
+ /**
212
+ * Create a page of items
213
+ *
214
+ * @since 3.0
215
+ * @return null
216
+ */
217
+ _createPage: function( index ) {
218
+ var self = this,
219
+ $page = $( '<div class="ditty-list__page ditty-list__page--' + index + '"></div>' ),
220
+ items = this._getItemsByPageIndex( index );
221
+
222
+ $.each( items, function( index, value ) {
223
+ var $item = $( value.html );
224
+ self._styleItem( $item );
225
+
226
+ // Add the layout css to the DOM
227
+ if ( value.css ) {
228
+ dittyLayoutCss( value.css, value.layout_id );
229
+ }
230
+ $page.append( $item );
231
+ } );
232
+
233
+ // Remove the spacing from the last item
234
+ $page.children().last().css( { paddingBottom: 0 } );
235
+
236
+ var page = {
237
+ id : 'page' + parseInt( index + 1 ),
238
+ html : $page,
239
+ items : items
240
+ };
241
+
242
+ return page;
243
+ },
244
+
245
+ /**
246
+ * Calculate and create pages
247
+ *
248
+ * @since 3.0
249
+ * @return null
250
+ */
251
+ _calculatePages: function () {
252
+ var self = this,
253
+ items = [];
254
+ $.each( this.settings.items, function( index, item ) {
255
+ if ( self._isItemEnabled( index ) ) {
256
+ items.push( item );
257
+ }
258
+ } );
259
+ this.enabledItems = items;
260
+ this.total = items.length;
261
+
262
+ if ( parseInt( this.settings.paging ) && parseInt( this.settings.perPage ) > 0 ) {
263
+ this.totalPages = Math.ceil( parseInt( this.total ) / parseInt( this.settings.perPage ) );
264
+ } else {
265
+ this.totalPages = 1;
266
+ }
267
+
268
+ this.pages = [];
269
+ for( var i = 0; i < this.totalPages; i++ ) {
270
+ this.pages.push( this._createPage( i ) );
271
+ }
272
+ },
273
+
274
+ /**
275
+ * Get a page index by item index
276
+ *
277
+ * @since 3.0
278
+ * @return null
279
+ */
280
+ _getPageByItemIndex: function ( index ) {
281
+ var pageIndex = Math.ceil( ( parseInt( index ) + 1 ) / this.settings.perPage ) - 1;
282
+ return pageIndex;
283
+ },
284
+
285
+ /**
286
+ * Get items by page index
287
+ *
288
+ * @since 3.0
289
+ * @return null
290
+ */
291
+ _getItemsByPageIndex: function ( index ) {
292
+ var items = this.enabledItems;
293
+
294
+ // Pull the items for the current index
295
+ if ( parseInt( this.totalPages ) > 1 ) {
296
+ var start = parseInt( this.settings.perPage ) * index,
297
+ end = start + parseInt( this.settings.perPage );
298
+ items = this.enabledItems.slice( start, end );
299
+ }
300
+ return items;
301
+ },
302
+
303
+ /**
304
+ * Shuffle items items TODO
305
+ *
306
+ * @since 3.0
307
+ * @return null
308
+ */
309
+ shuffle: function () {
310
+ var temp,
311
+ rand;
312
+
313
+ for ( var i = this.total - 1; i > 0; i-- ) {
314
+ rand = Math.floor( Math.random() * ( i + 1 ) );
315
+ temp = this.settings.items[i];
316
+
317
+ this.settings.items[i] = this.settings.items[rand];
318
+ this.settings.items[rand] = temp;
319
+ }
320
+ },
321
+
322
+ /**
323
+ * Check if a item is enabled
324
+ *
325
+ * @since 3.0
326
+ * @return null
327
+ */
328
+ _isItemEnabled: function( index ) {
329
+ if ( undefined === this.settings.items[parseInt( index )] ) {
330
+ return false;
331
+ }
332
+ if ( undefined === this.settings.items[parseInt( index )].is_disabled ) {
333
+ return true;
334
+ } else {
335
+ if ( this.settings.items[parseInt( index )].is_disabled.length > 0 ) {
336
+ return false;
337
+ } else {
338
+ return true;
339
+ }
340
+ }
341
+ },
342
+
343
+ /**
344
+ * Get the disabled status of all items
345
+ *
346
+ * @since 3.0
347
+ * @return null
348
+ */
349
+ _disabledItemsStatus: function () {
350
+ var self = this,
351
+ statuses = {};
352
+ $.each( this.settings.items, function( i, item ) {
353
+ if ( self._isItemEnabled( i ) ) {
354
+ statuses[item.id] = 'enabled';
355
+ } else {
356
+ statuses[item.id] = 'disabled';
357
+ }
358
+ } );
359
+ return statuses;
360
+ },
361
+
362
+ /**
363
+ * Add a disabled type to a item
364
+ *
365
+ * @since 3.0
366
+ * @return null
367
+ */
368
+ addItemDisabled: function ( id, slug ) {
369
+ var self = this;
370
+ $.each( this.settings.items, function( i, item ) {
371
+ if ( String( item.id ) === String( id ) ) {
372
+ if ( ! $.isArray( self.settings.items[i].is_disabled ) ) {
373
+ self.settings.items[i].is_disabled = [];
374
+ }
375
+ self.settings.items[i].is_disabled.push( slug );
376
+ }
377
+ } );
378
+ this.updateItems( this.settings.items );
379
+ this.trigger( 'disabled_items_update' );
380
+ },
381
+
382
+ /**
383
+ * Remove a disabled type from a item
384
+ *
385
+ * @since 3.0
386
+ * @return null
387
+ */
388
+ removeItemDisabled: function ( id, slug ) {
389
+ var self = this;
390
+ $.each( this.settings.items, function( i, item ) {
391
+ if ( String( item.id ) === String( id ) ) {
392
+ if ( $.isArray( self.settings.items[i].is_disabled ) && self.settings.items[i].is_disabled.length ) {
393
+ self.settings.items[i].is_disabled = $.grep( self.settings.items[i].is_disabled, function( value ) {
394
+ return value !== slug;
395
+ } );
396
+ }
397
+ }
398
+ } );
399
+ this.updateItems( this.settings.items );
400
+ this.trigger( 'disabled_items_update' );
401
+ },
402
+
403
+ /**
404
+ * Show a specific item by index or id
405
+ *
406
+ * @since 3.0
407
+ * @return null
408
+ */
409
+ showItem: function ( id ) {
410
+ var itemIndexes = [];
411
+ $.each( this.settings.items, function( i, item ) {
412
+ if ( String( item.id ) === String( id ) ) {
413
+ itemIndexes.push( i );
414
+ }
415
+ } );
416
+ if ( 0 !== itemIndexes.length ) {
417
+ var page = this._getPageByItemIndex( parseInt( itemIndexes[0] ) );
418
+ this.$elmt.ditty_slider( 'showSlide', page );
419
+ }
420
+ },
421
+
422
+ /**
423
+ * Add a new item
424
+ *
425
+ * @since 3.0
426
+ * @return null
427
+ */
428
+ addItem: function ( item, index, type ) {
429
+ var newItems = this.settings.items.slice(),
430
+ indexExists = true;
431
+
432
+ if ( index >= this.total || index < 0 ) {
433
+ indexExists = false;
434
+ }
435
+
436
+ // Replace a item
437
+ if ( 'replace' === type && indexExists ) {
438
+ newItems.splice( index, 1, item );
439
+
440
+ // Add a item
441
+ } else {
442
+ if ( null === index || '' === index ) {
443
+ newItems.splice( parseInt( this.item ) + 1, 0, item );
444
+ } else {
445
+ if ( index >= this.total ) {
446
+ newItems.push( item );
447
+ } else if ( index < 0 ) {
448
+ newItems.splice( 0, 0, item );
449
+ } else {
450
+ newItems.splice( index, 0, item );
451
+ }
452
+ }
453
+ }
454
+ this.updateItems( newItems );
455
+ },
456
+
457
+ /**
458
+ * Delete a item by index
459
+ *
460
+ * @since 3.0
461
+ * @return null
462
+ */
463
+ deleteItem: function ( id ) {
464
+ var updatedItems = [];
465
+ $.each( this.settings.items, function( index, item ) {
466
+ if ( String( item.id ) !== String( id ) ) {
467
+ updatedItems.push( item );
468
+ }
469
+ } );
470
+ this.updateItems( updatedItems );
471
+ },
472
+
473
+ /**
474
+ * Update the current items
475
+ *
476
+ * @since 3.0
477
+ * @return null
478
+ */
479
+ updateItems: function ( newItems, itemId, type, forceSwapAll ) {
480
+ if ( undefined === newItems ) {
481
+ return false;
482
+ }
483
+
484
+ var self = this,
485
+ currentIndex = this.$elmt.ditty_slider( 'options', 'slide' ),
486
+ forceSwaps = [];
487
+
488
+ // Update a single item id
489
+ if ( itemId ) {
490
+ var tempCurrentItems = this.settings.items.slice(),
491
+ tempNewItems = [],
492
+ tempSwapped = false;
493
+
494
+ $.each( tempCurrentItems, function( index, item ) {
495
+ if ( String( item.id ) === String( itemId ) ) {
496
+
497
+ // Add after the id
498
+ if ( 'after' === type ) {
499
+ tempNewItems.push( item );
500
+ $.each( newItems, function( index, newItem ) {
501
+ tempNewItems.push( newItem );
502
+ } );
503
+ tempSwapped = true;
504
+
505
+ // Add before the id
506
+ } else if ( 'before' === type ) {
507
+ $.each( newItems, function( index, newItem ) {
508
+ tempNewItems.push( newItem );
509
+ } );
510
+ tempNewItems.push( item );
511
+ tempSwapped = true;
512
+
513
+ // Else swap the ID
514
+ } else {
515
+ if ( ! tempSwapped ) {
516
+ $.each( newItems, function( index, newItem ) {
517
+ tempNewItems.push( newItem );
518
+ forceSwaps.push( String( newItem.uniq_id ) );
519
+ } );
520
+ tempSwapped = true;
521
+ }
522
+ }
523
+ } else {
524
+ tempNewItems.push( item );
525
+ }
526
+ } );
527
+ if ( ! tempSwapped ) {
528
+ $.each( this.settings.items, function( index, item ) {
529
+ tempNewItems.push( item );
530
+ } );
531
+ tempSwapped = true;
532
+ }
533
+ newItems = tempNewItems;
534
+ }
535
+ this.settings.items = newItems;
536
+ this.total = newItems.length;
537
+ this._calculatePages();
538
+ this.$elmt.ditty_slider( 'options', 'slides', this.pages );
539
+
540
+ var $currentPage = this.$elmt.ditty_slider( 'options', 'currentSlide' ),
541
+ currentItems = $currentPage.children( '.ditty-item' ),
542
+ newIndex = this.$elmt.ditty_slider( 'options', 'slide' ),
543
+ itemSwaps = [];
544
+
545
+ if ( currentIndex !== newIndex ) {
546
+ return false;
547
+ }
548
+
549
+ var newPageItems,
550
+ newPageItemsCount = 0,
551
+ $lastCurrentItem = null,
552
+ lastCurrentItemPadding = -1,
553
+ currentItemsUpdated = [];
554
+
555
+ if ( this.pages[newIndex] ) {
556
+ newPageItems = this.pages[newIndex].items;
557
+ newPageItemsCount = newPageItems.length;
558
+
559
+ // Add new page items
560
+ $.each( newPageItems, function( index, newItem ) {
561
+ var $newItem = $( newItem.html );
562
+
563
+ // Add the css and style the items
564
+ if ( newItem.css ) {
565
+ dittyLayoutCss( newItem.css, newItem.layout_id );
566
+ }
567
+ self._styleItem( $newItem );
568
+ if ( index === newPageItemsCount - 1 ) {
569
+ $newItem.css( { paddingBottom: 0 } );
570
+ }
571
+
572
+ // Swap existing items
573
+ if ( currentItems[index] ) {
574
+ var $currentItem = $( currentItems[index] );
575
+ $lastCurrentItem = $currentItem;
576
+
577
+ currentItemsUpdated.push( index );
578
+ if ( forceSwapAll || ( String( $currentItem.data( 'item_uniq_id' ) ) !== String( newItem.uniq_id ) ) || forceSwaps.includes( String( newItem.uniq_id ) ) ) {
579
+ itemSwaps.push( {
580
+ currentItem: $currentItem,
581
+ newItem: $newItem
582
+ } );
583
+ }
584
+
585
+ // Add new items
586
+ } else {
587
+ var $tempItem = $( '<div class="ditty-temp-item"></div>' );
588
+ $currentPage.append( $tempItem );
589
+ itemSwaps.push( {
590
+ currentItem: $tempItem,
591
+ newItem: $newItem
592
+ } );
593
+
594
+ lastCurrentItemPadding = parseInt( self.settings.spacing );
595
+ }
596
+ } );
597
+ }
598
+
599
+ // Remove old page items
600
+ $.each( currentItems, function( index ) {
601
+ if ( ! currentItemsUpdated.includes( index ) ) {
602
+ var $currentItem = $( currentItems[index] ),
603
+ $tempItem = $( '<div class="ditty-temp-item"></div>' );
604
+ itemSwaps.push( {
605
+ currentItem: $currentItem,
606
+ newItem: $tempItem
607
+ } );
608
+
609
+ lastCurrentItemPadding = 0;
610
+ }
611
+ } );
612
+
613
+ // Add padding to the last current item
614
+ if ( null !== $lastCurrentItem && lastCurrentItemPadding >= 0 ) {
615
+ $lastCurrentItem.css( {
616
+ paddingBottom: lastCurrentItemPadding + 'px'
617
+ } );
618
+ }
619
+
620
+ dittyUpdateItems( itemSwaps );
621
+ this.trigger( 'update' );
622
+ },
623
+
624
+ /**
625
+ * Return the currently visible items
626
+ *
627
+ * @since 3.0
628
+ * @return null
629
+ */
630
+ getActiveItems: function () {
631
+ return this._getItemsByPageIndex( this.page );
632
+ },
633
+
634
+ /**
635
+ * Trigger the init
636
+ *
637
+ * @since 3.0
638
+ * @return null
639
+ */
640
+ _triggerInit: function ( e ) {
641
+ var self = e.data.self;
642
+ self.trigger( 'init' );
643
+ },
644
+
645
+ /**
646
+ * Trigger an update
647
+ *
648
+ * @since 3.0
649
+ * @return null
650
+ */
651
+ _triggerUpdate: function ( e ) {
652
+ var self = e.data.self;
653
+ self.trigger( 'update' );
654
+ },
655
+
656
+ /**
657
+ * Trigger a slide update
658
+ *
659
+ * @since 3.0
660
+ * @return null
661
+ */
662
+ _triggerShowSlide: function ( e, slide ) {
663
+ var self = e.data.self;
664
+ self.page = slide;
665
+ self.trigger( 'active_items_update' );
666
+ },
667
+
668
+ /**
669
+ * Trigger events
670
+ *
671
+ * @since 3.0
672
+ * @return null
673
+ */
674
+ trigger: function ( fn ) {
675
+ var params = [];
676
+
677
+ switch( fn ) {
678
+ case 'active_items_update':
679
+ params = [this, this.getActiveItems()];
680
+ break;
681
+ case 'disabled_items_update':
682
+ params = [this._disabledItemsStatus()];
683
+ break;
684
+ case 'start_live_updates':
685
+ params = [this.settings.id];
686
+ break;
687
+ default:
688
+ params = [
689
+ this.settings,
690
+ this.$elmt
691
+ ];
692
+ break;
693
+ }
694
+
695
+ this.$elmt.trigger( 'ditty_' + fn, params );
696
+ if ( typeof this.settings[fn] === 'function' ) {
697
+ this.settings[fn].apply( this.$elmt, params );
698
+ }
699
+ //params.unshift( this );
700
+ $( 'body' ).trigger( 'ditty_' + fn, params );
701
+ },
702
+
703
+ /**
704
+ * Return data for the object
705
+ *
706
+ * @since 3.0
707
+ * @return null
708
+ */
709
+ _getOption: function( key ) {
710
+ switch( key ) {
711
+ case 'ditty':
712
+ return this;
713
+ case 'type':
714
+ return this.displayType;
715
+ case 'display':
716
+ return this.settings.display;
717
+ case 'items':
718
+ return this.settings.items;
719
+ default:
720
+ return this.settings[key];
721
+ }
722
+ },
723
+
724
+ /**
725
+ * Set data for the object
726
+ *
727
+ * @since 3.0
728
+ * @return null
729
+ */
730
+ _setOption: function( key, value ) {
731
+
732
+ if ( undefined === value ) {
733
+ return false;
734
+ }
735
+
736
+ var sliderKey = key,
737
+ sliderValue = value,
738
+ updateSlider = true;
739
+
740
+ var self = this;
741
+
742
+ switch( key ) {
743
+ case 'items':
744
+ updateSlider = false;
745
+ this.updateItems( value );
746
+ break;
747
+ case 'perPage':
748
+ case 'paging':
749
+ updateSlider = false;
750
+ this.settings[key] = value;
751
+ this.updateItems( this.settings.items );
752
+ break;
753
+ case 'spacing':
754
+ this.settings[key] = value;
755
+ this.$elmt.find( '.ditty-item' ).each( function() {
756
+ $( this ).css( { paddingBottom: self.settings.spacing + 'px' } );
757
+ });
758
+ this.$elmt.find( '.ditty-list__page' ).each( function() {
759
+ $( this ).children( '.ditty-item:last-child' ).css( { paddingBottom: 0 } );
760
+ });
761
+ break;
762
+ case 'itemTextColor':
763
+ case 'itemBgColor':
764
+ case 'itemBorderColor':
765
+ case 'itemBorderStyle':
766
+ case 'itemBorderWidth':
767
+ case 'itemBorderRadius':
768
+ case 'itemPadding':
769
+ this.settings[key] = value;
770
+ this.$elmt.find( '.ditty-item' ).each( function() {
771
+ self._styleItem( $( this ) );
772
+ } );
773
+ break;
774
+ default:
775
+ this.settings[key] = value;
776
+ break;
777
+ }
778
+
779
+ // Convert page to slide
780
+ if ( updateSlider ) {
781
+ sliderKey = sliderKey.replace( 'page', 'slide' );
782
+ this.$elmt.ditty_slider( 'options', sliderKey, sliderValue );
783
+ }
784
+ },
785
+
786
+ /**
787
+ * Get or set ditty options
788
+ *
789
+ * @since 3.0
790
+ * @return null
791
+ */
792
+ options: function ( key, value ) {
793
+ var self = this;
794
+ if ( typeof key === 'object' ) {
795
+ $.each( key, function( k, v ) {
796
+ self._setOption( k, v );
797
+ });
798
+ } else if ( typeof key === 'string' ) {
799
+ if ( value === undefined ) {
800
+ return self._getOption( key );
801
+ }
802
+ self._setOption( key, value );
803
+ } else {
804
+ return self.settings;
805
+ }
806
+ },
807
+
808
+ /**
809
+ * Destroy this object
810
+ *
811
+ * @since 3.0
812
+ * @return null
813
+ */
814
+ destroy: function () {
815
+ this._destroySlider();
816
+ this.$elmt.removeClass( 'ditty ditty-list' );
817
+ this.$elmt.removeAttr( 'data-id' );
818
+ this.$elmt.removeAttr( 'data-type' );
819
+ this.$elmt.removeAttr( 'data-display' );
820
+ this.$elmt.removeAttr( 'style' );
821
+ this.$elmt.empty();
822
+ this.elmt._ditty_list = null;
823
+ }
824
+ };
825
+
826
+ $.fn.ditty_list = function( options ) {
827
+ var args = arguments,
828
+ error = false,
829
+ returns;
830
+
831
+ if ( options === undefined || typeof options === 'object' ) {
832
+ return this.each( function () {
833
+ if ( ! this._ditty_list ) {
834
+ this._ditty_list = new Ditty_List( this, options );
835
+ }
836
+ });
837
+ } else if ( typeof options === 'string' ) {
838
+ this.each( function () {
839
+ var instance = this._ditty_list;
840
+
841
+ if ( ! instance ) {
842
+ throw new Error( 'No Ditty_List applied to this element.' );
843
+ }
844
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
845
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
846
+ } else {
847
+ error = true;
848
+ }
849
+ } );
850
+
851
+ if ( error ) {
852
+ throw new Error( 'No method "' + options + '" in Ditty_List.' );
853
+ }
854
+
855
+ return returns !== undefined ? returns : this;
856
+ }
857
+ };
858
+
859
+ $.ditty_list = {};
860
+ $.ditty_list.defaults = defaults;
861
+
862
+ } )( jQuery );
includes/js/class-ditty-display-list.min.js ADDED
@@ -0,0 +1,862 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* global dittyEditorInit:true */
3
+ /* global dittyLayoutCss:true */
4
+ /* global dittyUpdateItems:true */
5
+ /* //global console:true */
6
+
7
+ /**
8
+ * Ditty Slider class
9
+ *
10
+ * @since 3.0
11
+ * @return null
12
+ */
13
+
14
+ (function ($) {
15
+ 'use strict';
16
+
17
+ var defaults = {
18
+ id : 0,
19
+ title : '',
20
+ display : 0,
21
+ status : '',
22
+ spacing : 30,
23
+ paging : 0, // 0, 1
24
+ perPage : 0,
25
+ transition : 'fade', // fade, slideLeft, slideREight, slideDown, slideUp
26
+ transitionEase : 'easeInOutQuint',
27
+ transitionSpeed : 1.5, // 1 - 10
28
+ autoplay : 0, // 0, 1
29
+ autoplayPause : 0, // 0, 1
30
+ autoplaySpeed : 8, // 1 - 60
31
+ height : 0,
32
+ heightEase : 'easeInOutQuint',
33
+ heightSpeed : 1.5, // 1 - 10
34
+ arrows : 'none',
35
+ arrowsIconColor : '',
36
+ arrowsBgColor : '',
37
+ arrowsPosition : 'center',
38
+ arrowsPadding : {},
39
+ arrowsStatic : 0,
40
+ navPrev : '<i class="fas fa-angle-left"></i>',
41
+ navNext : '<i class="fas fa-angle-right"></i>',
42
+ bullets : 'none',
43
+ bulletsColor : '',
44
+ bulletsColorActive : '',
45
+ bulletsPosition : 'bottomCenter',
46
+ bulletsSpacing : 2,
47
+ bulletsPadding : {},
48
+ bullet : '',
49
+ maxWidth : '',
50
+ bgColor : '',
51
+ padding : {},
52
+ margin : {},
53
+ borderColor : {},
54
+ borderStyle : {},
55
+ borderWidth : {},
56
+ borderRadius : {},
57
+ contentsBgColor : '',
58
+ contentsPadding : {},
59
+ contentsBorderColor : {},
60
+ contentsBorderStyle : {},
61
+ contentsBorderWidth : {},
62
+ contentsBorderRadius : {},
63
+ pageBgColor : '',
64
+ pagePadding : {},
65
+ pageBorderColor : {},
66
+ pageBorderStyle : {},
67
+ pageBorderWidth : {},
68
+ pageBorderRadius : {},
69
+ itemTextColor : '',
70
+ itemBgColor : '',
71
+ itemBorderColor : {},
72
+ itemBorderStyle : {},
73
+ itemBorderWidth : {},
74
+ itemBorderRadius : {},
75
+ itemPadding : {},
76
+ page : 0,
77
+ shuffle : 0,
78
+ showEditor : 0,
79
+ // init : function () {},
80
+ items : [
81
+ // {
82
+ // id: null,
83
+ // uniq_id: null,
84
+ // parent_id: null,
85
+ // html: null,
86
+ // status: null,
87
+ // ...
88
+ ]
89
+ };
90
+
91
+ var Ditty_List = function ( elmt, options ) {
92
+
93
+ this.displayType = 'list';
94
+ this.elmt = elmt;
95
+ this.$elmt = $( elmt );
96
+ this.settings = $.extend( {}, defaults, $.ditty_list.defaults, options );
97
+ this.total = this.settings.items.length;
98
+ this.totalPages = 1;
99
+ this.page = this.settings.page;
100
+ this.pages = [];
101
+ this.enabledItems = [];
102
+ this.visibleItems = [];
103
+ this.editItem = null;
104
+
105
+ if ( 1 === parseInt( this.settings.shuffle ) ) {
106
+ this.shuffle();
107
+ }
108
+
109
+ this._init();
110
+ };
111
+
112
+ Ditty_List.prototype = {
113
+
114
+ _init: function () {
115
+
116
+ // Remove the pre class
117
+ this.$elmt.removeClass( 'ditty--pre' );
118
+
119
+ // Add classes and data attributes
120
+ this.$elmt.addClass( 'ditty ditty-list' );
121
+ this.$elmt.attr( 'data-id', this.settings.id );
122
+ this.$elmt.attr( 'data-type', this.displayType );
123
+ this.$elmt.attr( 'data-display', this.settings.display );
124
+
125
+ // Calculate the number of pages
126
+ this._calculatePages();
127
+
128
+ // Initialize the slider
129
+ this._initSlider();
130
+
131
+ // Show the editor or start live updates
132
+ if ( this.settings.showEditor ) {
133
+ dittyEditorInit( this );
134
+ } else {
135
+ this.trigger( 'start_live_updates' );
136
+ }
137
+ },
138
+
139
+ /**
140
+ * Initialize the slider
141
+ *
142
+ * @since 3.0
143
+ * @return null
144
+ */
145
+ _initSlider: function () {
146
+
147
+ // Modify any settings to fit a slider
148
+ var sliderSettings = [];
149
+ $.each( this.settings, function( key, value ) {
150
+ var sliderKey = key.replace( 'page', 'slide' );
151
+ sliderSettings[sliderKey] = value;
152
+ } );
153
+ sliderSettings.slides = this.pages;
154
+
155
+ // Create a new slider and bind actions
156
+ this.$elmt.ditty_slider( sliderSettings );
157
+ this.$elmt.on( 'ditty_slider_init', { self: this }, this._triggerInit );
158
+ this.$elmt.on( 'ditty_slider_update', { self: this }, this._triggerUpdate );
159
+ this.$elmt.on( 'ditty_slider_after_slide_update', { self: this }, this._triggerShowSlide );
160
+ },
161
+
162
+ /**
163
+ * Destroy the slider
164
+ *
165
+ * @since 3.0
166
+ * @return null
167
+ */
168
+ _destroySlider: function () {
169
+ if ( this.$elmt.ditty_slider ) {
170
+ this.$elmt.off( 'ditty_slider_init', { self: this }, this._triggerInit );
171
+ this.$elmt.off( 'ditty_slider_update', { self: this }, this._triggerUpdate );
172
+ this.$elmt.off( 'ditty_slider_after_slide_update', { self: this }, this._triggerShowSlide );
173
+ this.$elmt.ditty_slider( 'destroy' );
174
+ }
175
+ },
176
+
177
+ /**
178
+ * Update the slider
179
+ *
180
+ * @since 3.0
181
+ * @return null
182
+ */
183
+ _updateSlider: function ( index ) {
184
+ var newIndex = index ? index : this.$elmt.ditty_slider( 'options', 'slide');
185
+ this.$elmt.ditty_slider( 'options', 'slides', this.settings.pages );
186
+ this.$elmt.ditty_slider( 'options', 'slide', -1 );
187
+ this.$elmt.ditty_slider( 'showSlide', newIndex );
188
+ },
189
+
190
+ /**
191
+ * Style individual items
192
+ *
193
+ * @since 3.0
194
+ * @return null
195
+ */
196
+ _styleItem: function( $item ) {
197
+ $item.children( '.ditty-item__elements' ).css( {
198
+ color: this.settings.itemTextColor,
199
+ backgroundColor: this.settings.itemBgColor,
200
+ borderColor: this.settings.itemBorderColor,
201
+ borderStyle: this.settings.itemBorderStyle
202
+ } );
203
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemPadding );
204
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemBorderRadius );
205
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemBorderWidth );
206
+ $item.css( {
207
+ paddingBottom: this.settings.spacing + 'px'
208
+ } );
209
+ },
210
+
211
+ /**
212
+ * Create a page of items
213
+ *
214
+ * @since 3.0
215
+ * @return null
216
+ */
217
+ _createPage: function( index ) {
218
+ var self = this,
219
+ $page = $( '<div class="ditty-list__page ditty-list__page--' + index + '"></div>' ),
220
+ items = this._getItemsByPageIndex( index );
221
+
222
+ $.each( items, function( index, value ) {
223
+ var $item = $( value.html );
224
+ self._styleItem( $item );
225
+
226
+ // Add the layout css to the DOM
227
+ if ( value.css ) {
228
+ dittyLayoutCss( value.css, value.layout_id );
229
+ }
230
+ $page.append( $item );
231
+ } );
232
+
233
+ // Remove the spacing from the last item
234
+ $page.children().last().css( { paddingBottom: 0 } );
235
+
236
+ var page = {
237
+ id : 'page' + parseInt( index + 1 ),
238
+ html : $page,
239
+ items : items
240
+ };
241
+
242
+ return page;
243
+ },
244
+
245
+ /**
246
+ * Calculate and create pages
247
+ *
248
+ * @since 3.0
249
+ * @return null
250
+ */
251
+ _calculatePages: function () {
252
+ var self = this,
253
+ items = [];
254
+ $.each( this.settings.items, function( index, item ) {
255
+ if ( self._isItemEnabled( index ) ) {
256
+ items.push( item );
257
+ }
258
+ } );
259
+ this.enabledItems = items;
260
+ this.total = items.length;
261
+
262
+ if ( parseInt( this.settings.paging ) && parseInt( this.settings.perPage ) > 0 ) {
263
+ this.totalPages = Math.ceil( parseInt( this.total ) / parseInt( this.settings.perPage ) );
264
+ } else {
265
+ this.totalPages = 1;
266
+ }
267
+
268
+ this.pages = [];
269
+ for( var i = 0; i < this.totalPages; i++ ) {
270
+ this.pages.push( this._createPage( i ) );
271
+ }
272
+ },
273
+
274
+ /**
275
+ * Get a page index by item index
276
+ *
277
+ * @since 3.0
278
+ * @return null
279
+ */
280
+ _getPageByItemIndex: function ( index ) {
281
+ var pageIndex = Math.ceil( ( parseInt( index ) + 1 ) / this.settings.perPage ) - 1;
282
+ return pageIndex;
283
+ },
284
+
285
+ /**
286
+ * Get items by page index
287
+ *
288
+ * @since 3.0
289
+ * @return null
290
+ */
291
+ _getItemsByPageIndex: function ( index ) {
292
+ var items = this.enabledItems;
293
+
294
+ // Pull the items for the current index
295
+ if ( parseInt( this.totalPages ) > 1 ) {
296
+ var start = parseInt( this.settings.perPage ) * index,
297
+ end = start + parseInt( this.settings.perPage );
298
+ items = this.enabledItems.slice( start, end );
299
+ }
300
+ return items;
301
+ },
302
+
303
+ /**
304
+ * Shuffle items items TODO
305
+ *
306
+ * @since 3.0
307
+ * @return null
308
+ */
309
+ shuffle: function () {
310
+ var temp,
311
+ rand;
312
+
313
+ for ( var i = this.total - 1; i > 0; i-- ) {
314
+ rand = Math.floor( Math.random() * ( i + 1 ) );
315
+ temp = this.settings.items[i];
316
+
317
+ this.settings.items[i] = this.settings.items[rand];
318
+ this.settings.items[rand] = temp;
319
+ }
320
+ },
321
+
322
+ /**
323
+ * Check if a item is enabled
324
+ *
325
+ * @since 3.0
326
+ * @return null
327
+ */
328
+ _isItemEnabled: function( index ) {
329
+ if ( undefined === this.settings.items[parseInt( index )] ) {
330
+ return false;
331
+ }
332
+ if ( undefined === this.settings.items[parseInt( index )].is_disabled ) {
333
+ return true;
334
+ } else {
335
+ if ( this.settings.items[parseInt( index )].is_disabled.length > 0 ) {
336
+ return false;
337
+ } else {
338
+ return true;
339
+ }
340
+ }
341
+ },
342
+
343
+ /**
344
+ * Get the disabled status of all items
345
+ *
346
+ * @since 3.0
347
+ * @return null
348
+ */
349
+ _disabledItemsStatus: function () {
350
+ var self = this,
351
+ statuses = {};
352
+ $.each( this.settings.items, function( i, item ) {
353
+ if ( self._isItemEnabled( i ) ) {
354
+ statuses[item.id] = 'enabled';
355
+ } else {
356
+ statuses[item.id] = 'disabled';
357
+ }
358
+ } );
359
+ return statuses;
360
+ },
361
+
362
+ /**
363
+ * Add a disabled type to a item
364
+ *
365
+ * @since 3.0
366
+ * @return null
367
+ */
368
+ addItemDisabled: function ( id, slug ) {
369
+ var self = this;
370
+ $.each( this.settings.items, function( i, item ) {
371
+ if ( String( item.id ) === String( id ) ) {
372
+ if ( ! $.isArray( self.settings.items[i].is_disabled ) ) {
373
+ self.settings.items[i].is_disabled = [];
374
+ }
375
+ self.settings.items[i].is_disabled.push( slug );
376
+ }
377
+ } );
378
+ this.updateItems( this.settings.items );
379
+ this.trigger( 'disabled_items_update' );
380
+ },
381
+
382
+ /**
383
+ * Remove a disabled type from a item
384
+ *
385
+ * @since 3.0
386
+ * @return null
387
+ */
388
+ removeItemDisabled: function ( id, slug ) {
389
+ var self = this;
390
+ $.each( this.settings.items, function( i, item ) {
391
+ if ( String( item.id ) === String( id ) ) {
392
+ if ( $.isArray( self.settings.items[i].is_disabled ) && self.settings.items[i].is_disabled.length ) {
393
+ self.settings.items[i].is_disabled = $.grep( self.settings.items[i].is_disabled, function( value ) {
394
+ return value !== slug;
395
+ } );
396
+ }
397
+ }
398
+ } );
399
+ this.updateItems( this.settings.items );
400
+ this.trigger( 'disabled_items_update' );
401
+ },
402
+
403
+ /**
404
+ * Show a specific item by index or id
405
+ *
406
+ * @since 3.0
407
+ * @return null
408
+ */
409
+ showItem: function ( id ) {
410
+ var itemIndexes = [];
411
+ $.each( this.settings.items, function( i, item ) {
412
+ if ( String( item.id ) === String( id ) ) {
413
+ itemIndexes.push( i );
414
+ }
415
+ } );
416
+ if ( 0 !== itemIndexes.length ) {
417
+ var page = this._getPageByItemIndex( parseInt( itemIndexes[0] ) );
418
+ this.$elmt.ditty_slider( 'showSlide', page );
419
+ }
420
+ },
421
+
422
+ /**
423
+ * Add a new item
424
+ *
425
+ * @since 3.0
426
+ * @return null
427
+ */
428
+ addItem: function ( item, index, type ) {
429
+ var newItems = this.settings.items.slice(),
430
+ indexExists = true;
431
+
432
+ if ( index >= this.total || index < 0 ) {
433
+ indexExists = false;
434
+ }
435
+
436
+ // Replace a item
437
+ if ( 'replace' === type && indexExists ) {
438
+ newItems.splice( index, 1, item );
439
+
440
+ // Add a item
441
+ } else {
442
+ if ( null === index || '' === index ) {
443
+ newItems.splice( parseInt( this.item ) + 1, 0, item );
444
+ } else {
445
+ if ( index >= this.total ) {
446
+ newItems.push( item );
447
+ } else if ( index < 0 ) {
448
+ newItems.splice( 0, 0, item );
449
+ } else {
450
+ newItems.splice( index, 0, item );
451
+ }
452
+ }
453
+ }
454
+ this.updateItems( newItems );
455
+ },
456
+
457
+ /**
458
+ * Delete a item by index
459
+ *
460
+ * @since 3.0
461
+ * @return null
462
+ */
463
+ deleteItem: function ( id ) {
464
+ var updatedItems = [];
465
+ $.each( this.settings.items, function( index, item ) {
466
+ if ( String( item.id ) !== String( id ) ) {
467
+ updatedItems.push( item );
468
+ }
469
+ } );
470
+ this.updateItems( updatedItems );
471
+ },
472
+
473
+ /**
474
+ * Update the current items
475
+ *
476
+ * @since 3.0
477
+ * @return null
478
+ */
479
+ updateItems: function ( newItems, itemId, type, forceSwapAll ) {
480
+ if ( undefined === newItems ) {
481
+ return false;
482
+ }
483
+
484
+ var self = this,
485
+ currentIndex = this.$elmt.ditty_slider( 'options', 'slide' ),
486
+ forceSwaps = [];
487
+
488
+ // Update a single item id
489
+ if ( itemId ) {
490
+ var tempCurrentItems = this.settings.items.slice(),
491
+ tempNewItems = [],
492
+ tempSwapped = false;
493
+
494
+ $.each( tempCurrentItems, function( index, item ) {
495
+ if ( String( item.id ) === String( itemId ) ) {
496
+
497
+ // Add after the id
498
+ if ( 'after' === type ) {
499
+ tempNewItems.push( item );
500
+ $.each( newItems, function( index, newItem ) {
501
+ tempNewItems.push( newItem );
502
+ } );
503
+ tempSwapped = true;
504
+
505
+ // Add before the id
506
+ } else if ( 'before' === type ) {
507
+ $.each( newItems, function( index, newItem ) {
508
+ tempNewItems.push( newItem );
509
+ } );
510
+ tempNewItems.push( item );
511
+ tempSwapped = true;
512
+
513
+ // Else swap the ID
514
+ } else {
515
+ if ( ! tempSwapped ) {
516
+ $.each( newItems, function( index, newItem ) {
517
+ tempNewItems.push( newItem );
518
+ forceSwaps.push( String( newItem.uniq_id ) );
519
+ } );
520
+ tempSwapped = true;
521
+ }
522
+ }
523
+ } else {
524
+ tempNewItems.push( item );
525
+ }
526
+ } );
527
+ if ( ! tempSwapped ) {
528
+ $.each( this.settings.items, function( index, item ) {
529
+ tempNewItems.push( item );
530
+ } );
531
+ tempSwapped = true;
532
+ }
533
+ newItems = tempNewItems;
534
+ }
535
+ this.settings.items = newItems;
536
+ this.total = newItems.length;
537
+ this._calculatePages();
538
+ this.$elmt.ditty_slider( 'options', 'slides', this.pages );
539
+
540
+ var $currentPage = this.$elmt.ditty_slider( 'options', 'currentSlide' ),
541
+ currentItems = $currentPage.children( '.ditty-item' ),
542
+ newIndex = this.$elmt.ditty_slider( 'options', 'slide' ),
543
+ itemSwaps = [];
544
+
545
+ if ( currentIndex !== newIndex ) {
546
+ return false;
547
+ }
548
+
549
+ var newPageItems,
550
+ newPageItemsCount = 0,
551
+ $lastCurrentItem = null,
552
+ lastCurrentItemPadding = -1,
553
+ currentItemsUpdated = [];
554
+
555
+ if ( this.pages[newIndex] ) {
556
+ newPageItems = this.pages[newIndex].items;
557
+ newPageItemsCount = newPageItems.length;
558
+
559
+ // Add new page items
560
+ $.each( newPageItems, function( index, newItem ) {
561
+ var $newItem = $( newItem.html );
562
+
563
+ // Add the css and style the items
564
+ if ( newItem.css ) {
565
+ dittyLayoutCss( newItem.css, newItem.layout_id );
566
+ }
567
+ self._styleItem( $newItem );
568
+ if ( index === newPageItemsCount - 1 ) {
569
+ $newItem.css( { paddingBottom: 0 } );
570
+ }
571
+
572
+ // Swap existing items
573
+ if ( currentItems[index] ) {
574
+ var $currentItem = $( currentItems[index] );
575
+ $lastCurrentItem = $currentItem;
576
+
577
+ currentItemsUpdated.push( index );
578
+ if ( forceSwapAll || ( String( $currentItem.data( 'item_uniq_id' ) ) !== String( newItem.uniq_id ) ) || forceSwaps.includes( String( newItem.uniq_id ) ) ) {
579
+ itemSwaps.push( {
580
+ currentItem: $currentItem,
581
+ newItem: $newItem
582
+ } );
583
+ }
584
+
585
+ // Add new items
586
+ } else {
587
+ var $tempItem = $( '<div class="ditty-temp-item"></div>' );
588
+ $currentPage.append( $tempItem );
589
+ itemSwaps.push( {
590
+ currentItem: $tempItem,
591
+ newItem: $newItem
592
+ } );
593
+
594
+ lastCurrentItemPadding = parseInt( self.settings.spacing );
595
+ }
596
+ } );
597
+ }
598
+
599
+ // Remove old page items
600
+ $.each( currentItems, function( index ) {
601
+ if ( ! currentItemsUpdated.includes( index ) ) {
602
+ var $currentItem = $( currentItems[index] ),
603
+ $tempItem = $( '<div class="ditty-temp-item"></div>' );
604
+ itemSwaps.push( {
605
+ currentItem: $currentItem,
606
+ newItem: $tempItem
607
+ } );
608
+
609
+ lastCurrentItemPadding = 0;
610
+ }
611
+ } );
612
+
613
+ // Add padding to the last current item
614
+ if ( null !== $lastCurrentItem && lastCurrentItemPadding >= 0 ) {
615
+ $lastCurrentItem.css( {
616
+ paddingBottom: lastCurrentItemPadding + 'px'
617
+ } );
618
+ }
619
+
620
+ dittyUpdateItems( itemSwaps );
621
+ this.trigger( 'update' );
622
+ },
623
+
624
+ /**
625
+ * Return the currently visible items
626
+ *
627
+ * @since 3.0
628
+ * @return null
629
+ */
630
+ getActiveItems: function () {
631
+ return this._getItemsByPageIndex( this.page );
632
+ },
633
+
634
+ /**
635
+ * Trigger the init
636
+ *
637
+ * @since 3.0
638
+ * @return null
639
+ */
640
+ _triggerInit: function ( e ) {
641
+ var self = e.data.self;
642
+ self.trigger( 'init' );
643
+ },
644
+
645
+ /**
646
+ * Trigger an update
647
+ *
648
+ * @since 3.0
649
+ * @return null
650
+ */
651
+ _triggerUpdate: function ( e ) {
652
+ var self = e.data.self;
653
+ self.trigger( 'update' );
654
+ },
655
+
656
+ /**
657
+ * Trigger a slide update
658
+ *
659
+ * @since 3.0
660
+ * @return null
661
+ */
662
+ _triggerShowSlide: function ( e, slide ) {
663
+ var self = e.data.self;
664
+ self.page = slide;
665
+ self.trigger( 'active_items_update' );
666
+ },
667
+
668
+ /**
669
+ * Trigger events
670
+ *
671
+ * @since 3.0
672
+ * @return null
673
+ */
674
+ trigger: function ( fn ) {
675
+ var params = [];
676
+
677
+ switch( fn ) {
678
+ case 'active_items_update':
679
+ params = [this, this.getActiveItems()];
680
+ break;
681
+ case 'disabled_items_update':
682
+ params = [this._disabledItemsStatus()];
683
+ break;
684
+ case 'start_live_updates':
685
+ params = [this.settings.id];
686
+ break;
687
+ default:
688
+ params = [
689
+ this.settings,
690
+ this.$elmt
691
+ ];
692
+ break;
693
+ }
694
+
695
+ this.$elmt.trigger( 'ditty_' + fn, params );
696
+ if ( typeof this.settings[fn] === 'function' ) {
697
+ this.settings[fn].apply( this.$elmt, params );
698
+ }
699
+ //params.unshift( this );
700
+ $( 'body' ).trigger( 'ditty_' + fn, params );
701
+ },
702
+
703
+ /**
704
+ * Return data for the object
705
+ *
706
+ * @since 3.0
707
+ * @return null
708
+ */
709
+ _getOption: function( key ) {
710
+ switch( key ) {
711
+ case 'ditty':
712
+ return this;
713
+ case 'type':
714
+ return this.displayType;
715
+ case 'display':
716
+ return this.settings.display;
717
+ case 'items':
718
+ return this.settings.items;
719
+ default:
720
+ return this.settings[key];
721
+ }
722
+ },
723
+
724
+ /**
725
+ * Set data for the object
726
+ *
727
+ * @since 3.0
728
+ * @return null
729
+ */
730
+ _setOption: function( key, value ) {
731
+
732
+ if ( undefined === value ) {
733
+ return false;
734
+ }
735
+
736
+ var sliderKey = key,
737
+ sliderValue = value,
738
+ updateSlider = true;
739
+
740
+ var self = this;
741
+
742
+ switch( key ) {
743
+ case 'items':
744
+ updateSlider = false;
745
+ this.updateItems( value );
746
+ break;
747
+ case 'perPage':
748
+ case 'paging':
749
+ updateSlider = false;
750
+ this.settings[key] = value;
751
+ this.updateItems( this.settings.items );
752
+ break;
753
+ case 'spacing':
754
+ this.settings[key] = value;
755
+ this.$elmt.find( '.ditty-item' ).each( function() {
756
+ $( this ).css( { paddingBottom: self.settings.spacing + 'px' } );
757
+ });
758
+ this.$elmt.find( '.ditty-list__page' ).each( function() {
759
+ $( this ).children( '.ditty-item:last-child' ).css( { paddingBottom: 0 } );
760
+ });
761
+ break;
762
+ case 'itemTextColor':
763
+ case 'itemBgColor':
764
+ case 'itemBorderColor':
765
+ case 'itemBorderStyle':
766
+ case 'itemBorderWidth':
767
+ case 'itemBorderRadius':
768
+ case 'itemPadding':
769
+ this.settings[key] = value;
770
+ this.$elmt.find( '.ditty-item' ).each( function() {
771
+ self._styleItem( $( this ) );
772
+ } );
773
+ break;
774
+ default:
775
+ this.settings[key] = value;
776
+ break;
777
+ }
778
+
779
+ // Convert page to slide
780
+ if ( updateSlider ) {
781
+ sliderKey = sliderKey.replace( 'page', 'slide' );
782
+ this.$elmt.ditty_slider( 'options', sliderKey, sliderValue );
783
+ }
784
+ },
785
+
786
+ /**
787
+ * Get or set ditty options
788
+ *
789
+ * @since 3.0
790
+ * @return null
791
+ */
792
+ options: function ( key, value ) {
793
+ var self = this;
794
+ if ( typeof key === 'object' ) {
795
+ $.each( key, function( k, v ) {
796
+ self._setOption( k, v );
797
+ });
798
+ } else if ( typeof key === 'string' ) {
799
+ if ( value === undefined ) {
800
+ return self._getOption( key );
801
+ }
802
+ self._setOption( key, value );
803
+ } else {
804
+ return self.settings;
805
+ }
806
+ },
807
+
808
+ /**
809
+ * Destroy this object
810
+ *
811
+ * @since 3.0
812
+ * @return null
813
+ */
814
+ destroy: function () {
815
+ this._destroySlider();
816
+ this.$elmt.removeClass( 'ditty ditty-list' );
817
+ this.$elmt.removeAttr( 'data-id' );
818
+ this.$elmt.removeAttr( 'data-type' );
819
+ this.$elmt.removeAttr( 'data-display' );
820
+ this.$elmt.removeAttr( 'style' );
821
+ this.$elmt.empty();
822
+ this.elmt._ditty_list = null;
823
+ }
824
+ };
825
+
826
+ $.fn.ditty_list = function( options ) {
827
+ var args = arguments,
828
+ error = false,
829
+ returns;
830
+
831
+ if ( options === undefined || typeof options === 'object' ) {
832
+ return this.each( function () {
833
+ if ( ! this._ditty_list ) {
834
+ this._ditty_list = new Ditty_List( this, options );
835
+ }
836
+ });
837
+ } else if ( typeof options === 'string' ) {
838
+ this.each( function () {
839
+ var instance = this._ditty_list;
840
+
841
+ if ( ! instance ) {
842
+ throw new Error( 'No Ditty_List applied to this element.' );
843
+ }
844
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
845
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
846
+ } else {
847
+ error = true;
848
+ }
849
+ } );
850
+
851
+ if ( error ) {
852
+ throw new Error( 'No method "' + options + '" in Ditty_List.' );
853
+ }
854
+
855
+ return returns !== undefined ? returns : this;
856
+ }
857
+ };
858
+
859
+ $.ditty_list = {};
860
+ $.ditty_list.defaults = defaults;
861
+
862
+ } )( jQuery );
includes/js/class-ditty-display-ticker.js ADDED
@@ -0,0 +1,1352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* global dittyEditorInit:true */
3
+ /* global dittyLayoutCss:true */
4
+
5
+ /**
6
+ * Ditty class
7
+ *
8
+ * @since 3.0
9
+ * @return null
10
+ */
11
+
12
+ (function ($) {
13
+ 'use strict';
14
+
15
+ var defaults = {
16
+ id : 0,
17
+ title : '',
18
+ display : 0,
19
+ status : '',
20
+ direction : 'left',
21
+ spacing : 20,
22
+ speed : 10, // 1 - 10
23
+ hoverPause : 0, // 0, 1
24
+ height : null,
25
+ minHeight : null,
26
+ maxHeight : null,
27
+ heightEase : 'easeInOutQuint',
28
+ heightSpeed : 1.5, // 1 - 10
29
+ scrollInit : 'empty',
30
+ scrollDelay : 2,
31
+ maxWidth : '',
32
+ bgColor : '',
33
+ padding : {},
34
+ margin : {},
35
+ borderColor : {},
36
+ borderStyle : {},
37
+ borderWidth : {},
38
+ borderRadius : {},
39
+ contentsBgColor : '',
40
+ contentsPadding : {},
41
+ contentsBorderColor : {},
42
+ contentsBorderStyle : {},
43
+ contentsBorderWidth : {},
44
+ contentsBorderRadius : {},
45
+ itemTextColor : '',
46
+ itemBgColor : '',
47
+ itemBorderColor : {},
48
+ itemBorderStyle : {},
49
+ itemBorderWidth : {},
50
+ itemBorderRadius : {},
51
+ itemPadding : {},
52
+ itemMaxWidth : '',
53
+ item : 0,
54
+ shuffle : 0,
55
+ showEditor : 0,
56
+ // init : function () {},
57
+ // play : function () {},
58
+ // pause : function () {},
59
+ // walk : function () {},
60
+ items : [
61
+ // {
62
+ // id: null,
63
+ // uniq_id: null,
64
+ // parent_dd: null,
65
+ // html: null,
66
+ // is_disabled: null,
67
+ // ...
68
+ ]
69
+ };
70
+
71
+ var Ditty_Ticker = function ( elmt, options ) {
72
+
73
+ this.displayType = 'ticker';
74
+ this.elmt = elmt;
75
+ this.settings = $.extend( {}, defaults, $.ditty_ticker.defaults, options );
76
+ this.nextItem = null;
77
+ this.total = this.settings.items.length;
78
+ this.$elmt = $( elmt );
79
+ this.$contents = null;
80
+ this.$items = null;
81
+ this.$currentItem = null;
82
+ this.$lastItem = null;
83
+ this.scrollPercent = 0.13;
84
+ this.running = false;
85
+ this.interval = false;
86
+ // this.easeTimer = false;
87
+ this.currentHeight = this.settings.height;
88
+ this.visibleItems = [];
89
+ // this.editItem = null;
90
+ // this.cachedItems = [];
91
+
92
+ // this.directions = [
93
+ // 'left',
94
+ // 'right',
95
+ // 'up',
96
+ // 'down'
97
+ // ];
98
+ //
99
+ // if ( this.settings.directionsRegister instanceof Array === false ) {
100
+ // this.settings.directionsRegister = [ this.settings.directionsRegister ];
101
+ // }
102
+ //
103
+ // this.directions = this.directions.concat( this.settings.directionsRegister );
104
+
105
+ if ( 1 === parseInt( this.settings.shuffle ) ) {
106
+ this.shuffle();
107
+ }
108
+
109
+ this._init();
110
+ };
111
+
112
+ Ditty_Ticker.prototype = {
113
+
114
+ _init: function () {
115
+ var self = this,
116
+ $contents,
117
+ $items;
118
+
119
+
120
+
121
+ // Remove the pre class
122
+ this.$elmt.removeClass( 'ditty--pre' );
123
+
124
+ // Add classes and data attributes
125
+ this.$elmt.addClass( 'ditty ditty-ticker' );
126
+ this.$elmt.attr( 'data-id', this.settings.id );
127
+ this.$elmt.attr( 'data-type', this.displayType );
128
+ this.$elmt.attr( 'data-display', this.settings.display );
129
+
130
+ // Create the ticker contents
131
+ $contents = $( '<div class="ditty-ticker__contents"></div>' );
132
+ this.$contents = $contents;
133
+
134
+ // Create the ticker items container
135
+ $items = $( '<div class="ditty-ticker__items"></div>' );
136
+ this.$items = $items;
137
+
138
+ // Set the initial height
139
+ this.$items.height( this.currentHeight );
140
+
141
+ // Add the new elements
142
+ $contents.append( $items );
143
+ this.$elmt.append( $contents );
144
+
145
+ // Setup styles
146
+ this._styleDisplay();
147
+
148
+ // Add listeners
149
+ this.$contents.on( 'mouseenter', { self: this }, this._mouseenter );
150
+ this.$contents.on( 'mouseleave', { self: this }, this._mouseleave );
151
+
152
+ // Show the editor or start live updates
153
+ if ( this.settings.showEditor ) {
154
+ dittyEditorInit( this );
155
+ } else {
156
+ this.trigger( 'start_live_updates' );
157
+ }
158
+
159
+ // Trigger the init
160
+ setTimeout( function () {
161
+
162
+ // Preload images
163
+ for ( var i = 0; i < this.total; i++ ) {
164
+ this._preloadItem( this.settings.items[i] );
165
+ }
166
+
167
+ // Initialize the items
168
+ self._initializeItems();
169
+
170
+ self.trigger( 'init' );
171
+ }, 1 );
172
+ },
173
+
174
+ _initializeItems: function () {
175
+
176
+ if ( 'filled' === this.settings.scrollInit ) {
177
+
178
+ // Fill the ticker
179
+ this._fillTicker();
180
+
181
+ } else {
182
+
183
+ // Start
184
+ if ( ! this.running ) {
185
+ this._timerStart();
186
+ }
187
+ }
188
+ },
189
+
190
+ _preloadItem: function ( item ) {
191
+ var img;
192
+ $( item.html ).find( 'img' ).each( function() {
193
+ img = new Image();
194
+ img.src = $( this ).attr( 'src' );
195
+ } );
196
+ },
197
+
198
+ _positionItems: function( distance ) {
199
+ var self = this;
200
+
201
+ // Initialize the first item
202
+ if ( 0 === self.visibleItems.length ) {
203
+ var firstItem = self.settings.item;
204
+ if ( ! this._isItemEnabled( firstItem ) ) {
205
+ firstItem = this._getNextItem( firstItem );
206
+ }
207
+ self._initializeItem( firstItem );
208
+ }
209
+
210
+ $.each( self.visibleItems, function( index, value ) {
211
+ if ( ! value ) {
212
+ return;
213
+ }
214
+
215
+ // Set the new position
216
+ var $item = self.visibleItems[index].$item,
217
+ newPos = self._calculateItemPosition( index, distance );
218
+
219
+ self.visibleItems[index].posX = newPos.posX;
220
+ self.visibleItems[index].posY = newPos.posY;
221
+
222
+ // Move the item to the new position
223
+ self._itemSetTransform( $item, newPos );
224
+
225
+ // Check if a new item should start
226
+ if ( self._newItemShouldStart( $item, newPos ) ) {
227
+ self._initializeItem( parseInt( self.nextItem ) );
228
+ }
229
+
230
+ // Check if the item should be removed from the visible array
231
+ if ( self._itemShouldTerminate( $item, newPos ) ) {
232
+ self._terminateItem( index );
233
+ }
234
+ } );
235
+ },
236
+
237
+ _timerStart: function () {
238
+
239
+ var self = this;
240
+
241
+ this.running = true;
242
+ this.trigger( 'start' );
243
+
244
+ cancelAnimationFrame( this.interval );
245
+
246
+ function ditty_tickerLoop() {
247
+ self._positionItems();
248
+ self.interval = requestAnimationFrame( ditty_tickerLoop );
249
+ }
250
+
251
+ self.interval = requestAnimationFrame( ditty_tickerLoop );
252
+ },
253
+
254
+ _timerStop: function() {
255
+ cancelAnimationFrame( this.interval );
256
+ this.running = false;
257
+ this.trigger( 'stop' );
258
+ },
259
+
260
+ _mouseenter: function ( e ) {
261
+
262
+ var self = e.data.self;
263
+ if ( self.settings.hoverPause ) {
264
+ self._timerStop();
265
+ }
266
+ },
267
+
268
+ _mouseleave: function ( e ) {
269
+
270
+ var self = e.data.self;
271
+ if ( self.settings.hoverPause ) {
272
+ self._timerStart();
273
+ }
274
+ },
275
+
276
+ _newItemShouldStart: function( $item, position ) {
277
+
278
+ if ( this.$currentItem[0] !== $item[0] ) {
279
+ return false;
280
+ }
281
+
282
+ var shouldStart = false;
283
+ switch( this.settings.direction ) {
284
+ case 'left':
285
+ if ( position.posX <= ( this.$items.outerWidth() - $item.outerWidth() ) ) {
286
+ shouldStart = true;
287
+ }
288
+ break;
289
+ case 'right':
290
+ if ( position.posX >= 0 ) {
291
+ shouldStart = true;
292
+ }
293
+ break;
294
+ case 'down':
295
+ if ( position.posY >= 0 ) {
296
+ shouldStart = true;
297
+ }
298
+ break;
299
+ case 'up':
300
+ if ( position.posY <= ( this.$items.outerHeight() - $item.outerHeight() ) ) {
301
+ shouldStart = true;
302
+ }
303
+ break;
304
+ }
305
+
306
+ return shouldStart;
307
+ },
308
+
309
+ _initializeItem: function( index, positionType ) {
310
+
311
+ if ( undefined === this.settings.items[index] ) {
312
+ return false;
313
+ }
314
+
315
+ // Create and add a new item
316
+ var $item = $( this.settings.items[index].html );
317
+ $item.css( {
318
+ top: 0,
319
+ left: 0
320
+ } );
321
+ if ( this.$items.children( '.ditty-item--' + this.settings.items[index].id ).not( '.ditty-item--clone' ).length > 0 ) {
322
+ $item.addClass( 'ditty-item--clone' );
323
+ }
324
+
325
+ // Style the item
326
+ this._styleItem( $item );
327
+
328
+ // Add the layout css to the DOM
329
+ if ( this.settings.items[index].css ) {
330
+ dittyLayoutCss( this.settings.items[index].css, this.settings.items[index].layout_id );
331
+ }
332
+
333
+ this._itemSpacing( $item );
334
+ this._itemSetTransform( $item, this._itemResetPosition( $item ) );
335
+ this.$items.append( $item );
336
+
337
+ $item.css( {
338
+ display: 'block',
339
+ top: 0,
340
+ left: 0,
341
+ opacity: 1
342
+ } );
343
+
344
+ // Add a visible class
345
+ $item.addClass( 'ditty-item--current' );
346
+
347
+ // Remove the current class from the old current item
348
+ if ( null !== this.$currentItem ) {
349
+ this.$currentItem.removeClass( 'ditty-item--current' );
350
+ }
351
+
352
+ // Set this as the current item
353
+ this.$currentItem = $item;
354
+
355
+ if ( null === this.$lastItem ) {
356
+ $item.addClass( 'ditty-item--last' );
357
+ this.$lastItem = $item;
358
+ }
359
+
360
+ // Set the current item
361
+ this.settings.item = index;
362
+
363
+ // Set the next item
364
+ this.nextItem = this._getNextItem( index );
365
+
366
+ if ( 'custom' !== positionType ) {
367
+ var position = this._itemResetPosition( $item );
368
+ this._itemSetTransform( $item, position );
369
+ this.visibleItems.push( {
370
+ $item : $item,
371
+ itemId : this.settings.items[index].id,
372
+ posX : position.posX,
373
+ posY : position.posY
374
+ } );
375
+
376
+ // Set the ticker height
377
+ this._setCurrentHeight();
378
+ }
379
+
380
+ this.trigger( 'active_items_update' );
381
+
382
+ // Return the item
383
+ return $item;
384
+ },
385
+
386
+ _getNextItem: function( index ) {
387
+
388
+ var self = this,
389
+ nextItem = false,
390
+ $i;
391
+
392
+ // If the next item was changed externally, use it
393
+ if ( ( null !== this.nextItem ) && ( index !== this.nextItem ) ) {
394
+ var customIndex = parseInt( this.nextItem );
395
+ if ( customIndex < this.total && customIndex >= 0 && self._isItemEnabled( customIndex ) ) {
396
+ nextItem = parseInt( this.nextItem );
397
+ }
398
+ }
399
+
400
+ // Find the next enabled item
401
+ if ( ! nextItem ) {
402
+ for( $i = index; $i < this.total; $i++ ) {
403
+ if ( $i !== index && self._isItemEnabled( $i ) ) {
404
+ nextItem = parseInt( $i );
405
+ break;
406
+ }
407
+ }
408
+ }
409
+ if ( ! nextItem ) {
410
+ for( $i = 0; $i < this.total; $i++ ) {
411
+ if ( self._isItemEnabled( $i ) ) {
412
+ nextItem = parseInt( $i );
413
+ break;
414
+ }
415
+ }
416
+ }
417
+
418
+ // Set the next item
419
+ return nextItem;
420
+ },
421
+
422
+ /**
423
+ * Check if a item should terminate
424
+ *
425
+ * @since 3.0
426
+ * @return null
427
+ */
428
+ _itemShouldTerminate: function( $item, position ) {
429
+
430
+ var shouldTerminate = false;
431
+ switch( this.settings.direction ) {
432
+ case 'left':
433
+ if ( position.posX < -$item.outerWidth() ) {
434
+ shouldTerminate = true;
435
+ }
436
+ break;
437
+ case 'right':
438
+ if ( position.posX > this.$items.outerWidth() ) {
439
+ shouldTerminate = true;
440
+ }
441
+ break;
442
+ case 'up':
443
+ if ( position.posY < -$item.outerHeight() ) {
444
+ shouldTerminate = true;
445
+ }
446
+ break;
447
+ case 'down':
448
+ if ( position.posY > this.$items.outerHeight() ) {
449
+ shouldTerminate = true;
450
+ }
451
+ break;
452
+ }
453
+
454
+ return shouldTerminate;
455
+ },
456
+
457
+ /**
458
+ * Terminate a items
459
+ *
460
+ * @since 3.0
461
+ * @return null
462
+ */
463
+ _terminateItem: function( index ) {
464
+
465
+ var $item = this.visibleItems[index].$item,
466
+ $nextItem = $item.next();
467
+
468
+ // Remove the item
469
+ $item.remove();
470
+ this.visibleItems.splice( index, 1 );
471
+
472
+ if ( $nextItem.length ) {
473
+ $nextItem.addClass( 'ditty-item--last' );
474
+ this.$lastItem = $nextItem;
475
+ }
476
+
477
+ // Set the ticker height
478
+ this._setCurrentHeight();
479
+
480
+ this.trigger( 'active_items_update' );
481
+ },
482
+
483
+ /**
484
+ * Set the height of the ticker
485
+ *
486
+ * @since 3.0
487
+ * @return null
488
+ */
489
+ _setCurrentHeight: function () {
490
+ var height = this.currentHeight;
491
+
492
+ if ( 'up' === this.settings.direction || 'down' === this.settings.direction ) {
493
+ height = this.$items.outerHeight();
494
+ this.$items.css( {
495
+ height: '100%'
496
+ } );
497
+
498
+ } else {
499
+ height = 0;
500
+ $.each( this.visibleItems, function( index, value ) {
501
+ var itemHeight = value.$item.outerHeight();
502
+ if ( itemHeight > height ) {
503
+ height = itemHeight;
504
+ }
505
+ } );
506
+
507
+ if ( height !== this.currentHeight ) {
508
+
509
+ this.$items.stop().animate( {
510
+ height: height + 'px'
511
+ }, parseFloat( this.settings.heightSpeed ) * 1000, this.settings.heightEase, function() {
512
+ // Animation complete.
513
+ });
514
+ }
515
+ }
516
+
517
+ if ( height !== this.currentHeight ) {
518
+ this.currentHeight = height;
519
+ this.trigger( 'height_updated' );
520
+ }
521
+ },
522
+
523
+ /**
524
+ * Set the spacing between items
525
+ *
526
+ * @since 3.0
527
+ * @return null
528
+ */
529
+ _itemSpacing: function( $item ) {
530
+
531
+ switch( this.settings.direction ) {
532
+ case 'left':
533
+ case 'right':
534
+ $item.css( {
535
+ paddingLeft : ( this.settings.spacing / 2 ) + 'px',
536
+ paddingRight : ( this.settings.spacing / 2 ) + 'px',
537
+ paddingTop : 0,
538
+ paddingBottom : 0
539
+ } );
540
+ break;
541
+ case 'up':
542
+ case 'down':
543
+ $item.css( {
544
+ paddingLeft : 0,
545
+ paddingRight : 0,
546
+ paddingTop : ( this.settings.spacing / 2 ) + 'px',
547
+ paddingBottom : ( this.settings.spacing / 2 ) + 'px'
548
+ } );
549
+ break;
550
+ }
551
+ },
552
+
553
+ /**
554
+ * Transform the item position
555
+ *
556
+ * @since 3.0
557
+ * @return null
558
+ */
559
+ _itemSetTransform: function( $item, position ) {
560
+
561
+ var posX = position.posX,
562
+ posY = position.posY;
563
+
564
+ if ( posX !== 0 ) {
565
+ posX = posX + 'px';
566
+ }
567
+
568
+ if ( posY !== 0 ) {
569
+ posY = posY + 'px';
570
+ }
571
+
572
+ $item.css( {
573
+ transform: 'translate( ' + posX + ', ' + posY + ' )'
574
+ } );
575
+ },
576
+
577
+ /**
578
+ * Return the new position of a item
579
+ *
580
+ * @since 3.0
581
+ * @return null
582
+ */
583
+ _calculateItemPosition: function( index, distance ) {
584
+
585
+ var posX = 0,
586
+ posY = 0,
587
+ increment = parseFloat( this.settings.speed ) * this.scrollPercent;
588
+
589
+ if ( distance ) {
590
+ increment = distance;
591
+ }
592
+
593
+ switch( this.settings.direction ) {
594
+ case 'left':
595
+ posX = parseFloat( this.visibleItems[index].posX ) - increment;
596
+ break;
597
+ case 'right':
598
+ posX = parseFloat( this.visibleItems[index].posX ) + increment;
599
+ break;
600
+ case 'up':
601
+ posY = parseFloat( this.visibleItems[index].posY ) - increment;
602
+ break;
603
+ case 'down':
604
+ posY = parseFloat( this.visibleItems[index].posY ) + increment;
605
+ break;
606
+ }
607
+
608
+ return { 'posX': posX, 'posY': posY };
609
+ },
610
+
611
+ /**
612
+ * Return the reset position of a item
613
+ *
614
+ * @since 3.0
615
+ * @return null
616
+ */
617
+ _itemResetPosition: function( $item ) {
618
+
619
+ var posX = 0,
620
+ posY = 0;
621
+
622
+ switch( this.settings.direction ) {
623
+ case 'left':
624
+ posX = this.$items.outerWidth();
625
+ break;
626
+ case 'right':
627
+ posX = '-' + $item.outerWidth();
628
+ break;
629
+ case 'up':
630
+ posY = this.$items.outerHeight();
631
+ break;
632
+ case 'down':
633
+ posY = '-' + $item.outerHeight();
634
+ break;
635
+ }
636
+
637
+ return { 'posX': posX, 'posY': posY };
638
+ },
639
+
640
+ /**
641
+ * Reverse the order of items
642
+ *
643
+ * @since 3.0
644
+ * @return null
645
+ */
646
+ _reverseItems: function() {
647
+
648
+ if ( this.$currentItem === this.$lastItem ) {
649
+ return false;
650
+ }
651
+
652
+ var $currentItem = this.$currentItem,
653
+ $lastItem = this.$lastItem;
654
+
655
+ this.$currentItem = $lastItem;
656
+ this.$lastItem = $currentItem;
657
+
658
+ this.$currentItem.removeClass( 'ditty-item--last' ).addClass( 'ditty-item--current' );
659
+ this.$lastItem.removeClass( 'ditty-item--current' ).addClass( 'ditty-item--last' );
660
+
661
+ var itemItems = this.$items.children( '.ditty-item' );
662
+ this.$items.append( itemItems.get().reverse() );
663
+ },
664
+
665
+ /**
666
+ * Reset the visible items
667
+ *
668
+ * @since 3.0
669
+ * @return null
670
+ */
671
+ _resetItems: function() {
672
+ this.$items.empty();
673
+ this.visibleItems = [];
674
+ this.trigger( 'active_items_update' );
675
+ },
676
+
677
+ /**
678
+ * Fill a ticker with items before scrolling
679
+ *
680
+ * @since 3.0
681
+ * @return null
682
+ */
683
+ _fillTicker: function() {
684
+
685
+ var self = this,
686
+ tickerW = parseFloat( this.$items.outerWidth() ),
687
+ tickerH = parseFloat( this.$items.outerHeight() ),
688
+ posX = 0,
689
+ posY = 0,
690
+ filled = false,
691
+ current = this.settings.item,
692
+ fillTimer = null;
693
+
694
+ if ( ! this._isItemEnabled( current ) ) {
695
+ current = this._getNextItem( current );
696
+ }
697
+
698
+ if ( 'right' === this.settings.direction ) {
699
+ posX = tickerW;
700
+ } else if ( 'down' === this.settings.direction ) {
701
+ posY = tickerH;
702
+ }
703
+
704
+ fillTimer = setInterval( function() {
705
+
706
+ var $item = self._initializeItem( current ),
707
+ data = self._filledItemInit( current, $item, posX, posY, tickerW, tickerH );
708
+
709
+ posX = data.posX;
710
+ posY = data.posY;
711
+ filled = data.filled;
712
+ current = self._getNextItem( current );
713
+
714
+ if ( filled ) {
715
+ clearInterval( fillTimer );
716
+
717
+ self.trigger( 'active_items_update' );
718
+
719
+ // Delay the start
720
+ setTimeout( function() {
721
+ if ( ! self.running ) {
722
+ self._timerStart();
723
+ }
724
+ }, parseFloat( self.settings.scrollDelay ) * 1000 );
725
+ }
726
+
727
+ }, 100 );
728
+ },
729
+
730
+ /**
731
+ * Initialize a item for a filled init ticker
732
+ *
733
+ * @since 3.0
734
+ * @return null
735
+ */
736
+ _filledItemInit: function( index, $item, posX, posY, tickerW, tickerH ) {
737
+
738
+ var itemId = $item.data( 'id' ),
739
+ itemW = parseFloat( $item.outerWidth() ),
740
+ itemH = parseFloat( $item.outerHeight() ),
741
+ translateX = 0,
742
+ translateY = 0,
743
+ filled = false;
744
+
745
+ $item.css( {
746
+ display: 'block',
747
+ opacity: 0
748
+ } );
749
+
750
+ switch( this.settings.direction ) {
751
+ case 'left':
752
+ translateX = posX;
753
+ this._itemSetTransform( $item, { 'posX': translateX, 'posY': posY } );
754
+ posX = posX + itemW;
755
+ if ( posX > tickerW ) {
756
+ filled = true;
757
+ }
758
+ break;
759
+ case 'right':
760
+ posX = posX - itemW;
761
+ translateX = posX;
762
+ this._itemSetTransform( $item, { 'posX': translateX, 'posY': posY } );
763
+ if ( posX < 0 ) {
764
+ filled = true;
765
+ }
766
+ break;
767
+ case 'up':
768
+ translateY = posY;
769
+ this._itemSetTransform( $item, { 'posX': posX, 'posY': translateY } );
770
+ posY = posY + itemH;
771
+ if ( posY > tickerH ) {
772
+ filled = true;
773
+ }
774
+ break;
775
+ case 'down':
776
+ posY = posY - itemH;
777
+ translateY = posY;
778
+ this._itemSetTransform( $item, { 'posX': posX, 'posY': translateY } );
779
+ if ( posY < 0 ) {
780
+ filled = true;
781
+ }
782
+ break;
783
+ }
784
+
785
+ $item.stop().animate( {
786
+ opacity: 1
787
+ }, 1000, 'linear', function() {
788
+ // Animation complete.
789
+ } );
790
+
791
+ this.visibleItems.push( {
792
+ $item : $item,
793
+ itemId : itemId,
794
+ posX : translateX,
795
+ posY : translateY
796
+ } );
797
+
798
+ // Set the ticker height
799
+ this._setCurrentHeight();
800
+
801
+ return { 'posX': posX, 'posY': posY, 'filled': filled };
802
+ },
803
+
804
+ /**
805
+ * Set the direction of the ticker
806
+ *
807
+ * @since 3.0
808
+ * @return null
809
+ */
810
+ _setDirection: function ( direction ) {
811
+ if ( ! $.inArray( direction, this.settings.directions ) ) {
812
+ return false;
813
+ }
814
+ if ( direction === this.settings.directions ) {
815
+ return false;
816
+ }
817
+ this.settings.direction = direction;
818
+ this._timerStop();
819
+ this._resetItems();
820
+ this._initializeItems();
821
+ this.trigger( 'direction' );
822
+ },
823
+
824
+ /**
825
+ * Style the display element
826
+ *
827
+ * @since 3.0
828
+ * @return null
829
+ */
830
+ _styleDisplay: function () {
831
+ this.$elmt.css( {
832
+ maxWidth: this.settings.maxWidth,
833
+ backgroundColor: this.settings.bgColor,
834
+ borderColor: this.settings.borderColor,
835
+ borderStyle: this.settings.borderStyle
836
+ } );
837
+ this.$elmt.css( this.settings.padding );
838
+ this.$elmt.css( this.settings.margin );
839
+ this.$elmt.css( this.settings.borderRadius );
840
+
841
+ this.$contents.css( {
842
+ backgroundColor: this.settings.contentsBgColor,
843
+ borderColor: this.settings.contentsBorderColor,
844
+ borderStyle: this.settings.contentsBorderStyle
845
+ } );
846
+ this.$contents.css( this.settings.contentsPadding );
847
+ this.$contents.css( this.settings.contentsBorderRadius );
848
+ this.$contents.css( this.settings.contentsBorderWidth );
849
+
850
+ if ( 'up' === this.settings.direction || 'down' === this.settings.direction ) {
851
+ var height = this.settings.height ? this.settings.height : '100%',
852
+ minHeight = this.settings.minHeight ? this.settings.minHeight : 0,
853
+ maxHeight = this.settings.maxHeight ? this.settings.maxHeight : 'none';
854
+ this.$elmt.css( {
855
+ height: height,
856
+ minHeight: minHeight,
857
+ maxHeight: maxHeight
858
+ } );
859
+ this.$contents.css( { height: height } );
860
+ } else {
861
+ this.$elmt.css( {
862
+ height: 'auto',
863
+ minHeight: 0,
864
+ maxHeight: 'none'
865
+ } );
866
+ this.$contents.css( { height: 'auto' } );
867
+ }
868
+ },
869
+
870
+ /**
871
+ * Style item elemtents
872
+ *
873
+ * @since 3.0
874
+ * @return null
875
+ */
876
+ _styleItem: function( $item ) {
877
+ $item.children( '.ditty-item__elements' ).css( {
878
+ color: this.settings.itemTextColor,
879
+ backgroundColor: this.settings.itemBgColor,
880
+ borderColor: this.settings.itemBorderColor,
881
+ borderStyle: this.settings.itemBorderStyle
882
+ } );
883
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemPadding );
884
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemBorderRadius );
885
+ $item.children( '.ditty-item__elements' ).css( this.settings.itemBorderWidth );
886
+ if ( '' !== this.settings.itemMaxWidth ) {
887
+ $item.children( '.ditty-item__elements' ).css( { maxWidth: this.settings.itemMaxWidth } );
888
+ }
889
+ },
890
+
891
+ /**
892
+ * Return data for the object
893
+ *
894
+ * @since 3.0
895
+ * @return null
896
+ */
897
+ _getOption: function( key ) {
898
+ switch( key ) {
899
+ case 'ditty':
900
+ return this;
901
+ case 'type':
902
+ return this.displayType;
903
+ case 'display':
904
+ return this.settings.display;
905
+ case 'items':
906
+ return this.settings.items;
907
+ case 'height':
908
+ return this.currentHeight;
909
+ default:
910
+ return this.settings[key];
911
+ }
912
+ },
913
+
914
+ /**
915
+ * Set data for the object
916
+ *
917
+ * @since 3.0
918
+ * @return null
919
+ */
920
+ _setOption: function( key, value ) {
921
+
922
+ if ( undefined === value ) {
923
+ return false;
924
+ }
925
+
926
+ switch( key ) {
927
+ case 'items':
928
+ this.updateItems( value );
929
+ break;
930
+ case 'minHeight':
931
+ case 'maxHeight':
932
+ case 'bgColor':
933
+ case 'padding':
934
+ case 'borderColor':
935
+ case 'borderStyle':
936
+ case 'borderWidth':
937
+ case 'borderRadius':
938
+ case 'contentsBgColor':
939
+ case 'contentsPadding':
940
+ case 'contentsBorderRadius':
941
+ this.settings[key] = value;
942
+ this._styleDisplay();
943
+ this._setCurrentHeight();
944
+ break;
945
+ default:
946
+ this.settings[key] = value;
947
+ break;
948
+ }
949
+
950
+ this.trigger( 'update' );
951
+ },
952
+
953
+ shuffle: function () {
954
+ var temp,
955
+ rand;
956
+
957
+ for ( var i = this.total - 1; i > 0; i-- ) {
958
+ rand = Math.floor( Math.random() * ( i + 1 ) );
959
+ temp = this.settings.items[i];
960
+
961
+ this.settings.items[i] = this.settings.items[rand];
962
+ this.settings.items[rand] = temp;
963
+ }
964
+ },
965
+
966
+ play: function () {
967
+ if ( ! this.running ) {
968
+ this._timerStart();
969
+ }
970
+ },
971
+
972
+ pause: function () {
973
+ if ( this.running ) {
974
+ this._timerStop();
975
+ }
976
+ },
977
+
978
+ direction: function ( value ) {
979
+ this._setDirection( value );
980
+ },
981
+
982
+ toggle: function () {
983
+ if ( this.running ) {
984
+ this.pause();
985
+ } else {
986
+ this.play();
987
+ }
988
+ },
989
+
990
+ running: function () {
991
+ return this.running;
992
+ },
993
+
994
+ current: function () {
995
+ return this.$currentItem;
996
+ },
997
+
998
+
999
+ /**
1000
+ * Check if a item is enabled
1001
+ *
1002
+ * @since 3.0
1003
+ * @return null
1004
+ */
1005
+ _isItemEnabled: function( index ) {
1006
+ if ( undefined === this.settings.items[parseInt( index )] ) {
1007
+ return false;
1008
+ }
1009
+ if ( undefined === this.settings.items[parseInt( index )].is_disabled ) {
1010
+ return true;
1011
+ } else {
1012
+ if ( this.settings.items[parseInt( index )].is_disabled.length > 0 ) {
1013
+ return false;
1014
+ } else {
1015
+ return true;
1016
+ }
1017
+ }
1018
+ },
1019
+
1020
+ /**
1021
+ * Get the disabled status of all items
1022
+ *
1023
+ * @since 3.0
1024
+ * @return null
1025
+ */
1026
+ _disabledItemsStatus: function () {
1027
+ var self = this,
1028
+ statusus = {};
1029
+ $.each( this.settings.items, function( i, item ) {
1030
+ if ( self._isItemEnabled( i ) ) {
1031
+ statusus[item.id] = 'enabled';
1032
+ } else {
1033
+ statusus[item.id] = 'disabled';
1034
+ }
1035
+ } );
1036
+ return statusus;
1037
+ },
1038
+
1039
+ /**
1040
+ * Add a disabled type to a item
1041
+ *
1042
+ * @since 3.0
1043
+ * @return null
1044
+ */
1045
+ addItemDisabled: function ( id, slug ) {
1046
+ var self = this;
1047
+ $.each( this.settings.items, function( i, item ) {
1048
+ if ( String( item.id ) === String( id ) ) {
1049
+ if ( ! $.isArray( self.settings.items[i].is_disabled ) ) {
1050
+ self.settings.items[i].is_disabled = [];
1051
+ }
1052
+ self.settings.items[i].is_disabled.push( slug );
1053
+ }
1054
+ } );
1055
+ this.trigger( 'disabled_items_update' );
1056
+ },
1057
+
1058
+ /**
1059
+ * Remove a disabled type from a item
1060
+ *
1061
+ * @since 3.0
1062
+ * @return null
1063
+ */
1064
+ removeItemDisabled: function ( id, slug ) {
1065
+ var self = this;
1066
+ $.each( this.settings.items, function( i, item ) {
1067
+ if ( String( item.id ) === String( id ) ) {
1068
+ if ( $.isArray( self.settings.items[i].is_disabled ) && self.settings.items[i].is_disabled.length ) {
1069
+ self.settings.items[i].is_disabled = $.grep( self.settings.items[i].is_disabled, function( value ) {
1070
+ return value !== slug;
1071
+ } );
1072
+ }
1073
+ }
1074
+ } );
1075
+ this.trigger( 'disabled_items_update' );
1076
+ },
1077
+
1078
+ /**
1079
+ * Show a specific item by index or id
1080
+ *
1081
+ * @since 3.0
1082
+ * @return null
1083
+ */
1084
+ showItem: function ( id ) {
1085
+ var itemIndexes = [];
1086
+ $.each( this.settings.items, function( i, item ) {
1087
+ if ( String( item.id ) === String( id ) ) {
1088
+ itemIndexes.push( i );
1089
+ }
1090
+ } );
1091
+ if ( 0 !== itemIndexes.length ) {
1092
+ this.nextItem = itemIndexes[0];
1093
+ return this.nextItem;
1094
+ }
1095
+ },
1096
+
1097
+ /**
1098
+ * Add a new item
1099
+ *
1100
+ * @since 3.0
1101
+ * @return null
1102
+ */
1103
+ addItem: function ( item, index, type ) {
1104
+ var newItems = this.settings.items.slice(),
1105
+ indexExists = true;
1106
+
1107
+ if ( index >= this.total || index < 0 ) {
1108
+ indexExists = false;
1109
+ }
1110
+
1111
+ // Replace a item
1112
+ if ( 'replace' === type && indexExists ) {
1113
+ newItems.splice( index, 1, item );
1114
+
1115
+ // Add a item
1116
+ } else {
1117
+ if ( null === index || '' === index ) {
1118
+ newItems.splice( this.nextItem, 0, item );
1119
+ } else {
1120
+ if ( index >= this.total ) {
1121
+ newItems.push( item );
1122
+ } else if ( index < 0 ) {
1123
+ newItems.splice( 0, 0, item );
1124
+ } else {
1125
+ newItems.splice( index, 0, item );
1126
+ }
1127
+ }
1128
+ }
1129
+ this.updateItems( newItems );
1130
+ },
1131
+
1132
+ /**
1133
+ * Delete a item by index
1134
+ *
1135
+ * @since 3.0
1136
+ * @return null
1137
+ */
1138
+ deleteItem: function ( id ) {
1139
+ var updatedItems = [];
1140
+ $.each( this.settings.items, function( index, item ) {
1141
+ if ( String( item.id ) !== String( id ) ) {
1142
+ updatedItems.push( item );
1143
+ }
1144
+ } );
1145
+ this.updateItems( updatedItems );
1146
+ },
1147
+
1148
+ /**
1149
+ * Update the current items
1150
+ *
1151
+ * @since 3.0
1152
+ * @return null
1153
+ */
1154
+ updateItems: function ( newItems, itemId, type, forceSwapAll ) {
1155
+ if ( undefined === newItems ) {
1156
+ return false;
1157
+ }
1158
+ var forceSwaps = [];
1159
+
1160
+ // Update a single item id
1161
+ if ( itemId ) {
1162
+ var tempCurrentItems = this.settings.items.slice(),
1163
+ tempNewItems = [],
1164
+ tempSwapped = false;
1165
+
1166
+ $.each( tempCurrentItems, function( index, item ) {
1167
+ if ( String( item.id ) === String( itemId ) ) {
1168
+
1169
+ // Add after the id
1170
+ if ( 'after' === type ) {
1171
+ tempNewItems.push( item );
1172
+ $.each( newItems, function( index, newItem ) {
1173
+ tempNewItems.push( newItem );
1174
+ } );
1175
+ tempSwapped = true;
1176
+
1177
+ // Add before the id
1178
+ } else if ( 'before' === type ) {
1179
+ $.each( newItems, function( index, newItem ) {
1180
+ tempNewItems.push( newItem );
1181
+ } );
1182
+ tempNewItems.push( item );
1183
+ tempSwapped = true;
1184
+
1185
+ // Else swap the ID
1186
+ } else {
1187
+ if ( ! tempSwapped ) {
1188
+ $.each( newItems, function( index, newItem ) {
1189
+ tempNewItems.push( newItem );
1190
+ forceSwaps.push( String( newItem.uniq_id ) );
1191
+ } );
1192
+ tempSwapped = true;
1193
+ }
1194
+ }
1195
+ } else {
1196
+ tempNewItems.push( item );
1197
+ }
1198
+ } );
1199
+ if ( ! tempSwapped ) {
1200
+ $.each( this.settings.items, function( index, item ) {
1201
+ tempNewItems.push( item );
1202
+ } );
1203
+ tempSwapped = true;
1204
+ }
1205
+ newItems = tempNewItems;
1206
+ }
1207
+
1208
+ this.settings.items = newItems;
1209
+ this.total = newItems.length;
1210
+ if ( this.nextItem >= this.total ) {
1211
+ this.nextItem = 0;
1212
+ }
1213
+ this.trigger( 'update' );
1214
+ },
1215
+
1216
+ /**
1217
+ * Return the currently visible items
1218
+ *
1219
+ * @since 3.0
1220
+ * @return null
1221
+ */
1222
+ getActiveItems: function () {
1223
+ var activeItems = [];
1224
+ $.each( this.visibleItems, function( index, value ) {
1225
+ activeItems.push( { id : value.itemId } );
1226
+ } );
1227
+ return activeItems;
1228
+ },
1229
+
1230
+ /**
1231
+ * Trigger events
1232
+ *
1233
+ * @since 3.0
1234
+ * @return null
1235
+ */
1236
+ trigger: function ( fn ) {
1237
+ var params = [];
1238
+ switch( fn ) {
1239
+ case 'active_items_update':
1240
+ params = [this, this.getActiveItems()];
1241
+ break;
1242
+ case 'disabled_items_update':
1243
+ params = [this._disabledItemsStatus()];
1244
+ break;
1245
+ case 'height_updated':
1246
+ params = [
1247
+ this.currentHeight,
1248
+ this.$elmt
1249
+ ];
1250
+ break;
1251
+ case 'start_live_updates':
1252
+ params = [this.settings.id];
1253
+ break;
1254
+ default:
1255
+ params = [
1256
+ this.settings,
1257
+ this.$elmt
1258
+ ];
1259
+ break;
1260
+ }
1261
+
1262
+ //params = [this.settings];
1263
+ this.$elmt.trigger( 'ditty_' + fn, params );
1264
+ if ( typeof this.settings[fn] === 'function' ) {
1265
+ this.settings[fn].apply( this.$elmt, params );
1266
+ }
1267
+ $( 'body' ).trigger( 'ditty_' + fn, params );
1268
+ },
1269
+
1270
+ /**
1271
+ * Get or set ditty options
1272
+ *
1273
+ * @since 3.0
1274
+ * @return null
1275
+ */
1276
+ options: function ( key, value ) {
1277
+ var self = this;
1278
+ if ( typeof key === 'object' ) {
1279
+ $.each( key, function( k, v ) {
1280
+ self._setOption( k, v );
1281
+ } );
1282
+ } else if ( typeof key === 'string' ) {
1283
+ if ( value === undefined ) {
1284
+ return self._getOption( key );
1285
+ }
1286
+ self._setOption( key, value );
1287
+ } else {
1288
+ return self.settings;
1289
+ }
1290
+ },
1291
+
1292
+ /**
1293
+ * Destroy this object
1294
+ *
1295
+ * @since 3.0
1296
+ * @return null
1297
+ */
1298
+ destroy: function () {
1299
+
1300
+ // Remove listeners
1301
+ this.$contents.off( 'mouseenter', { self: this }, this._mouseenter );
1302
+ this.$contents.off( 'mouseleave', { self: this }, this._mouseleave );
1303
+
1304
+ cancelAnimationFrame( this.interval );
1305
+
1306
+ this.$elmt.removeClass( 'ditty ditty-ticker' );
1307
+ this.$elmt.removeAttr( 'data-id' );
1308
+ this.$elmt.removeAttr( 'data-type' );
1309
+ this.$elmt.removeAttr( 'data-display' );
1310
+ this.$elmt.removeAttr( 'style' );
1311
+ this.$elmt.empty();
1312
+ this.elmt._ditty_ticker = null;
1313
+ }
1314
+ };
1315
+
1316
+ $.fn.ditty_ticker = function( options ) {
1317
+ var args = arguments,
1318
+ error = false,
1319
+ returns;
1320
+
1321
+ if ( options === undefined || typeof options === 'object' ) {
1322
+ return this.each( function () {
1323
+ if ( ! this._ditty_ticker ) {
1324
+ this._ditty_ticker = new Ditty_Ticker( this, options );
1325
+ }
1326
+ });
1327
+ } else if ( typeof options === 'string' ) {
1328
+ this.each( function () {
1329
+ var instance = this._ditty_ticker;
1330
+
1331
+ if ( ! instance ) {
1332
+ throw new Error( 'No Ditty_Ticker applied to this element.' );
1333
+ }
1334
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
1335
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
1336
+ } else {
1337
+ error = true;
1338
+ }
1339
+ } );
1340
+
1341
+ if ( error ) {
1342
+ throw new Error( 'No method "' + options + '" in Ditty_Ticker.' );
1343
+ }
1344
+
1345
+ return returns !== undefined ? returns : this;
1346
+ }
1347
+ };
1348
+
1349
+ $.ditty_ticker = {};
1350
+ $.ditty_ticker.defaults = defaults;
1351
+
1352
+ } )( jQuery );
includes/js/class-ditty-display-ticker.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function($){"use strict";var t={id:0,title:"",display:0,status:"",direction:"left",spacing:20,speed:10,hoverPause:0,height:null,minHeight:null,maxHeight:null,heightEase:"easeInOutQuint",heightSpeed:1.5,scrollInit:"empty",scrollDelay:2,maxWidth:"",bgColor:"",padding:{},margin:{},borderColor:{},borderStyle:{},borderWidth:{},borderRadius:{},contentsBgColor:"",contentsPadding:{},contentsBorderColor:{},contentsBorderStyle:{},contentsBorderWidth:{},contentsBorderRadius:{},itemTextColor:"",itemBgColor:"",itemBorderColor:{},itemBorderStyle:{},itemBorderWidth:{},itemBorderRadius:{},itemPadding:{},itemMaxWidth:"",item:0,shuffle:0,showEditor:0,items:[]},i=function(i,e){this.displayType="ticker",this.elmt=i,this.settings=$.extend({},t,$.ditty_ticker.defaults,e),this.nextItem=null,this.total=this.settings.items.length,this.$elmt=$(i),this.$contents=null,this.$items=null,this.$currentItem=null,this.$lastItem=null,this.scrollPercent=.13,this.running=!1,this.interval=!1,this.currentHeight=this.settings.height,this.visibleItems=[],1===parseInt(this.settings.shuffle)&&this.shuffle(),this._init()};i.prototype={_init:function(){var t,i,e=this;this.$elmt.removeClass("ditty--pre"),this.$elmt.addClass("ditty ditty-ticker"),this.$elmt.attr("data-id",this.settings.id),this.$elmt.attr("data-type",this.displayType),this.$elmt.attr("data-display",this.settings.display),t=$('<div class="ditty-ticker__contents"></div>'),this.$contents=t,i=$('<div class="ditty-ticker__items"></div>'),this.$items=i,this.$items.height(this.currentHeight),t.append(i),this.$elmt.append(t),this._styleDisplay(),this.$contents.on("mouseenter",{self:this},this._mouseenter),this.$contents.on("mouseleave",{self:this},this._mouseleave),this.settings.showEditor?dittyEditorInit(this):this.trigger("start_live_updates"),setTimeout((function(){for(var t=0;t<this.total;t++)this._preloadItem(this.settings.items[t]);e._initializeItems(),e.trigger("init")}),1)},_initializeItems:function(){"filled"===this.settings.scrollInit?this._fillTicker():this.running||this._timerStart()},_preloadItem:function(t){$(t.html).find("img").each((function(){(new Image).src=$(this).attr("src")}))},_positionItems:function(t){var i=this;if(0===i.visibleItems.length){var e=i.settings.item;this._isItemEnabled(e)||(e=this._getNextItem(e)),i._initializeItem(e)}$.each(i.visibleItems,(function(e,s){if(s){var n=i.visibleItems[e].$item,r=i._calculateItemPosition(e,t);i.visibleItems[e].posX=r.posX,i.visibleItems[e].posY=r.posY,i._itemSetTransform(n,r),i._newItemShouldStart(n,r)&&i._initializeItem(parseInt(i.nextItem)),i._itemShouldTerminate(n,r)&&i._terminateItem(e)}}))},_timerStart:function(){var t=this;this.running=!0,this.trigger("start"),cancelAnimationFrame(this.interval),t.interval=requestAnimationFrame((function i(){t._positionItems(),t.interval=requestAnimationFrame(i)}))},_timerStop:function(){cancelAnimationFrame(this.interval),this.running=!1,this.trigger("stop")},_mouseenter:function(t){var i=t.data.self;i.settings.hoverPause&&i._timerStop()},_mouseleave:function(t){var i=t.data.self;i.settings.hoverPause&&i._timerStart()},_newItemShouldStart:function(t,i){if(this.$currentItem[0]!==t[0])return!1;var e=!1;switch(this.settings.direction){case"left":i.posX<=this.$items.outerWidth()-t.outerWidth()&&(e=!0);break;case"right":i.posX>=0&&(e=!0);break;case"down":i.posY>=0&&(e=!0);break;case"up":i.posY<=this.$items.outerHeight()-t.outerHeight()&&(e=!0)}return e},_initializeItem:function(t,i){if(void 0===this.settings.items[t])return!1;var e=$(this.settings.items[t].html);if(e.css({top:0,left:0}),this.$items.children(".ditty-item--"+this.settings.items[t].id).not(".ditty-item--clone").length>0&&e.addClass("ditty-item--clone"),this._styleItem(e),this.settings.items[t].css&&dittyLayoutCss(this.settings.items[t].css,this.settings.items[t].layout_id),this._itemSpacing(e),this._itemSetTransform(e,this._itemResetPosition(e)),this.$items.append(e),e.css({display:"block",top:0,left:0,opacity:1}),e.addClass("ditty-item--current"),null!==this.$currentItem&&this.$currentItem.removeClass("ditty-item--current"),this.$currentItem=e,null===this.$lastItem&&(e.addClass("ditty-item--last"),this.$lastItem=e),this.settings.item=t,this.nextItem=this._getNextItem(t),"custom"!==i){var s=this._itemResetPosition(e);this._itemSetTransform(e,s),this.visibleItems.push({$item:e,itemId:this.settings.items[t].id,posX:s.posX,posY:s.posY}),this._setCurrentHeight()}return this.trigger("active_items_update"),e},_getNextItem:function(t){var i,e=this,s=!1;if(null!==this.nextItem&&t!==this.nextItem){var n=parseInt(this.nextItem);n<this.total&&n>=0&&e._isItemEnabled(n)&&(s=parseInt(this.nextItem))}if(!s)for(i=t;i<this.total;i++)if(i!==t&&e._isItemEnabled(i)){s=parseInt(i);break}if(!s)for(i=0;i<this.total;i++)if(e._isItemEnabled(i)){s=parseInt(i);break}return s},_itemShouldTerminate:function(t,i){var e=!1;switch(this.settings.direction){case"left":i.posX<-t.outerWidth()&&(e=!0);break;case"right":i.posX>this.$items.outerWidth()&&(e=!0);break;case"up":i.posY<-t.outerHeight()&&(e=!0);break;case"down":i.posY>this.$items.outerHeight()&&(e=!0)}return e},_terminateItem:function(t){var i=this.visibleItems[t].$item,e=i.next();i.remove(),this.visibleItems.splice(t,1),e.length&&(e.addClass("ditty-item--last"),this.$lastItem=e),this._setCurrentHeight(),this.trigger("active_items_update")},_setCurrentHeight:function(){var t=this.currentHeight;"up"===this.settings.direction||"down"===this.settings.direction?(t=this.$items.outerHeight(),this.$items.css({height:"100%"})):(t=0,$.each(this.visibleItems,(function(i,e){var s=e.$item.outerHeight();s>t&&(t=s)})),t!==this.currentHeight&&this.$items.stop().animate({height:t+"px"},1e3*parseFloat(this.settings.heightSpeed),this.settings.heightEase,(function(){}))),t!==this.currentHeight&&(this.currentHeight=t,this.trigger("height_updated"))},_itemSpacing:function(t){switch(this.settings.direction){case"left":case"right":t.css({paddingLeft:this.settings.spacing/2+"px",paddingRight:this.settings.spacing/2+"px",paddingTop:0,paddingBottom:0});break;case"up":case"down":t.css({paddingLeft:0,paddingRight:0,paddingTop:this.settings.spacing/2+"px",paddingBottom:this.settings.spacing/2+"px"})}},_itemSetTransform:function(t,i){var e=i.posX,s=i.posY;0!==e&&(e+="px"),0!==s&&(s+="px"),t.css({transform:"translate( "+e+", "+s+" )"})},_calculateItemPosition:function(t,i){var e=0,s=0,n=parseFloat(this.settings.speed)*this.scrollPercent;switch(i&&(n=i),this.settings.direction){case"left":e=parseFloat(this.visibleItems[t].posX)-n;break;case"right":e=parseFloat(this.visibleItems[t].posX)+n;break;case"up":s=parseFloat(this.visibleItems[t].posY)-n;break;case"down":s=parseFloat(this.visibleItems[t].posY)+n}return{posX:e,posY:s}},_itemResetPosition:function(t){var i=0,e=0;switch(this.settings.direction){case"left":i=this.$items.outerWidth();break;case"right":i="-"+t.outerWidth();break;case"up":e=this.$items.outerHeight();break;case"down":e="-"+t.outerHeight()}return{posX:i,posY:e}},_reverseItems:function(){if(this.$currentItem===this.$lastItem)return!1;var t=this.$currentItem,i=this.$lastItem;this.$currentItem=i,this.$lastItem=t,this.$currentItem.removeClass("ditty-item--last").addClass("ditty-item--current"),this.$lastItem.removeClass("ditty-item--current").addClass("ditty-item--last");var e=this.$items.children(".ditty-item");this.$items.append(e.get().reverse())},_resetItems:function(){this.$items.empty(),this.visibleItems=[],this.trigger("active_items_update")},_fillTicker:function(){var t=this,i=parseFloat(this.$items.outerWidth()),e=parseFloat(this.$items.outerHeight()),s=0,n=0,r=!1,h=this.settings.item,a=null;this._isItemEnabled(h)||(h=this._getNextItem(h)),"right"===this.settings.direction?s=i:"down"===this.settings.direction&&(n=e),a=setInterval((function(){var o=t._initializeItem(h),m=t._filledItemInit(h,o,s,n,i,e);s=m.posX,n=m.posY,r=m.filled,h=t._getNextItem(h),r&&(clearInterval(a),t.trigger("active_items_update"),setTimeout((function(){t.running||t._timerStart()}),1e3*parseFloat(t.settings.scrollDelay)))}),100)},_filledItemInit:function(t,i,e,s,n,r){var h=i.data("id"),a=parseFloat(i.outerWidth()),o=parseFloat(i.outerHeight()),m=0,d=0,l=!1;switch(i.css({display:"block",opacity:0}),this.settings.direction){case"left":m=e,this._itemSetTransform(i,{posX:m,posY:s}),(e+=a)>n&&(l=!0);break;case"right":m=e-=a,this._itemSetTransform(i,{posX:m,posY:s}),e<0&&(l=!0);break;case"up":d=s,this._itemSetTransform(i,{posX:e,posY:d}),(s+=o)>r&&(l=!0);break;case"down":d=s-=o,this._itemSetTransform(i,{posX:e,posY:d}),s<0&&(l=!0)}return i.stop().animate({opacity:1},1e3,"linear",(function(){})),this.visibleItems.push({$item:i,itemId:h,posX:m,posY:d}),this._setCurrentHeight(),{posX:e,posY:s,filled:l}},_setDirection:function(t){return!!$.inArray(t,this.settings.directions)&&(t!==this.settings.directions&&(this.settings.direction=t,this._timerStop(),this._resetItems(),this._initializeItems(),void this.trigger("direction")))},_styleDisplay:function(){if(this.$elmt.css({maxWidth:this.settings.maxWidth,backgroundColor:this.settings.bgColor,borderColor:this.settings.borderColor,borderStyle:this.settings.borderStyle}),this.$elmt.css(this.settings.padding),this.$elmt.css(this.settings.margin),this.$elmt.css(this.settings.borderRadius),this.$contents.css({backgroundColor:this.settings.contentsBgColor,borderColor:this.settings.contentsBorderColor,borderStyle:this.settings.contentsBorderStyle}),this.$contents.css(this.settings.contentsPadding),this.$contents.css(this.settings.contentsBorderRadius),this.$contents.css(this.settings.contentsBorderWidth),"up"===this.settings.direction||"down"===this.settings.direction){var t=this.settings.height?this.settings.height:"100%",i=this.settings.minHeight?this.settings.minHeight:0,e=this.settings.maxHeight?this.settings.maxHeight:"none";this.$elmt.css({height:t,minHeight:i,maxHeight:e}),this.$contents.css({height:t})}else this.$elmt.css({height:"auto",minHeight:0,maxHeight:"none"}),this.$contents.css({height:"auto"})},_styleItem:function(t){t.children(".ditty-item__elements").css({color:this.settings.itemTextColor,backgroundColor:this.settings.itemBgColor,borderColor:this.settings.itemBorderColor,borderStyle:this.settings.itemBorderStyle}),t.children(".ditty-item__elements").css(this.settings.itemPadding),t.children(".ditty-item__elements").css(this.settings.itemBorderRadius),t.children(".ditty-item__elements").css(this.settings.itemBorderWidth),""!==this.settings.itemMaxWidth&&t.children(".ditty-item__elements").css({maxWidth:this.settings.itemMaxWidth})},_getOption:function(t){switch(t){case"ditty":return this;case"type":return this.displayType;case"display":return this.settings.display;case"items":return this.settings.items;case"height":return this.currentHeight;default:return this.settings[t]}},_setOption:function(t,i){if(void 0===i)return!1;switch(t){case"items":this.updateItems(i);break;case"minHeight":case"maxHeight":case"bgColor":case"padding":case"borderColor":case"borderStyle":case"borderWidth":case"borderRadius":case"contentsBgColor":case"contentsPadding":case"contentsBorderRadius":this.settings[t]=i,this._styleDisplay(),this._setCurrentHeight();break;default:this.settings[t]=i}this.trigger("update")},shuffle:function(){for(var t,i,e=this.total-1;e>0;e--)i=Math.floor(Math.random()*(e+1)),t=this.settings.items[e],this.settings.items[e]=this.settings.items[i],this.settings.items[i]=t},play:function(){this.running||this._timerStart()},pause:function(){this.running&&this._timerStop()},direction:function(t){this._setDirection(t)},toggle:function(){this.running?this.pause():this.play()},running:function(){return this.running},current:function(){return this.$currentItem},_isItemEnabled:function(t){return void 0!==this.settings.items[parseInt(t)]&&(void 0===this.settings.items[parseInt(t)].is_disabled||!(this.settings.items[parseInt(t)].is_disabled.length>0))},_disabledItemsStatus:function(){var t=this,i={};return $.each(this.settings.items,(function(e,s){t._isItemEnabled(e)?i[s.id]="enabled":i[s.id]="disabled"})),i},addItemDisabled:function(t,i){var e=this;$.each(this.settings.items,(function(s,n){String(n.id)===String(t)&&($.isArray(e.settings.items[s].is_disabled)||(e.settings.items[s].is_disabled=[]),e.settings.items[s].is_disabled.push(i))})),this.trigger("disabled_items_update")},removeItemDisabled:function(t,i){var e=this;$.each(this.settings.items,(function(s,n){String(n.id)===String(t)&&$.isArray(e.settings.items[s].is_disabled)&&e.settings.items[s].is_disabled.length&&(e.settings.items[s].is_disabled=$.grep(e.settings.items[s].is_disabled,(function(t){return t!==i})))})),this.trigger("disabled_items_update")},showItem:function(t){var i=[];if($.each(this.settings.items,(function(e,s){String(s.id)===String(t)&&i.push(e)})),0!==i.length)return this.nextItem=i[0],this.nextItem},addItem:function(t,i,e){var s=this.settings.items.slice(),n=!0;(i>=this.total||i<0)&&(n=!1),"replace"===e&&n?s.splice(i,1,t):null===i||""===i?s.splice(this.nextItem,0,t):i>=this.total?s.push(t):i<0?s.splice(0,0,t):s.splice(i,0,t),this.updateItems(s)},deleteItem:function(t){var i=[];$.each(this.settings.items,(function(e,s){String(s.id)!==String(t)&&i.push(s)})),this.updateItems(i)},updateItems:function(t,i,e,s){if(void 0===t)return!1;var n=[];if(i){var r=this.settings.items.slice(),h=[],a=!1;$.each(r,(function(s,r){String(r.id)===String(i)?"after"===e?(h.push(r),$.each(t,(function(t,i){h.push(i)})),a=!0):"before"===e?($.each(t,(function(t,i){h.push(i)})),h.push(r),a=!0):a||($.each(t,(function(t,i){h.push(i),n.push(String(i.uniq_id))})),a=!0):h.push(r)})),a||($.each(this.settings.items,(function(t,i){h.push(i)})),a=!0),t=h}this.settings.items=t,this.total=t.length,this.nextItem>=this.total&&(this.nextItem=0),this.trigger("update")},getActiveItems:function(){var t=[];return $.each(this.visibleItems,(function(i,e){t.push({id:e.itemId})})),t},trigger:function(t){var i=[];switch(t){case"active_items_update":i=[this,this.getActiveItems()];break;case"disabled_items_update":i=[this._disabledItemsStatus()];break;case"height_updated":i=[this.currentHeight,this.$elmt];break;case"start_live_updates":i=[this.settings.id];break;default:i=[this.settings,this.$elmt]}this.$elmt.trigger("ditty_"+t,i),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,i),$("body").trigger("ditty_"+t,i)},options:function(t,i){var e=this;if("object"==typeof t)$.each(t,(function(t,i){e._setOption(t,i)}));else{if("string"!=typeof t)return e.settings;if(void 0===i)return e._getOption(t);e._setOption(t,i)}},destroy:function(){this.$contents.off("mouseenter",{self:this},this._mouseenter),this.$contents.off("mouseleave",{self:this},this._mouseleave),cancelAnimationFrame(this.interval),this.$elmt.removeClass("ditty ditty-ticker"),this.$elmt.removeAttr("data-id"),this.$elmt.removeAttr("data-type"),this.$elmt.removeAttr("data-display"),this.$elmt.removeAttr("style"),this.$elmt.empty(),this.elmt._ditty_ticker=null}},$.fn.ditty_ticker=function(t){var e,s=arguments,n=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_ticker||(this._ditty_ticker=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_ticker;if(!i)throw new Error("No Ditty_Ticker applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):n=!0})),n)throw new Error('No method "'+t+'" in Ditty_Ticker.');return void 0!==e?e:this}},$.ditty_ticker={},$.ditty_ticker.defaults=t}(jQuery);
includes/js/class-ditty-slider.js ADDED
@@ -0,0 +1,1424 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* global Hammer:true */
3
+
4
+ /**
5
+ * Ditty Slider class
6
+ *
7
+ * @since 3.0
8
+ * @return null
9
+ */
10
+
11
+ (function ($) {
12
+ 'use strict';
13
+
14
+ var defaults = {
15
+ transition : 'fade', // fade, slideLeft, slideRight, slideDown, slideUp
16
+ transitionEase : 'easeInOutQuint',
17
+ transitionSpeed : 1.5, // 1 - 10
18
+ autoplay : 0, // 0, 1
19
+ autoplayPause : 0, // 0, 1
20
+ autoplaySpeed : 7, // 1 - 60
21
+ height : 0,
22
+ heightEase : 'easeInOutQuint',
23
+ heightSpeed : 1.5, // 1 - 10
24
+ initTransition : 'fade', // fade, slideLeft, slideREight, slideDown, slideUp
25
+ initTransitionEase : 'easeInOutQuint',
26
+ initTransitionSpeed : 1.5, // 1 - 10
27
+ initHeightEase : 'easeInOutQuint',
28
+ initHeightSpeed : 0.5, // 1 - 10
29
+ arrows : 'none',
30
+ arrowsIconColor : '',
31
+ arrowsBgColor : '',
32
+ arrowsPosition : 'center',
33
+ arrowsPadding : {},
34
+ arrowsStatic : 0,
35
+ navPrev : '<i class="fas fa-angle-left"></i>',
36
+ navNext : '<i class="fas fa-angle-right"></i>',
37
+ bullets : 'none',
38
+ bulletsColor : '',
39
+ bulletsColorActive : '',
40
+ bulletsPosition : 'bottomCenter',
41
+ bulletsSpacing : 2,
42
+ bulletsPadding : {},
43
+ bullet : '',
44
+ maxWidth : '',
45
+ bgColor : '',
46
+ padding : {},
47
+ margin : {},
48
+ borderColor : {},
49
+ borderStyle : {},
50
+ borderWidth : {},
51
+ borderRadius : {},
52
+ contentsBgColor : '',
53
+ contentsPadding : {},
54
+ contentsBorderColor : {},
55
+ contentsBorderStyle : {},
56
+ contentsBorderWidth : {},
57
+ contentsBorderRadius : {},
58
+ slideBgColor : '',
59
+ slidePadding : {},
60
+ slideBorderColor : {},
61
+ slideBorderStyle : {},
62
+ slideBorderWidth : {},
63
+ slideBorderRadius : {},
64
+ slide : 0,
65
+ slideId : false,
66
+ touchSwipe : true,
67
+ //init : function () {},
68
+ slidesEl : false,
69
+ slides : [
70
+ // {
71
+ // id: null,
72
+ // html: null,
73
+ // ...
74
+ ]
75
+ };
76
+
77
+ var Ditty_Slider = function ( elmt, options ) {
78
+
79
+ this.elmt = elmt;
80
+ this.settings = $.extend( {}, defaults, $.ditty_slider.defaults, options );
81
+ this.slide = this.settings.slide;
82
+ this.slideObj = {};
83
+ this.total = this.settings.slides.length;
84
+ this.$elmt = $( elmt );
85
+ this.$contents = null;
86
+ this.$slides = null;
87
+ this.$bullets = null;
88
+ this.$arrows = null;
89
+ this.$currentSlide = null;
90
+ this.$lastSlide = null;
91
+ this.transitioning = false;
92
+ this.hovering = false;
93
+ this.timer = null;
94
+ this.currentHeight = this.settings.height;
95
+ this.animateTransition = false;
96
+ this.animateHeight = false;
97
+ this.slidesDisplayed = 0,
98
+ this.paused = false;
99
+ this.transitions = [
100
+ 'fade',
101
+ 'slideLeft',
102
+ 'slideRight',
103
+ 'slideDown',
104
+ 'slideUp'
105
+ ];
106
+
107
+ this._init();
108
+ };
109
+
110
+ Ditty_Slider.prototype = {
111
+
112
+ _init: function () {
113
+ var self = this,
114
+ $contents,
115
+ $slides;
116
+
117
+ // Add classes and data attributes
118
+ this.$elmt.addClass( 'ditty-slider' );
119
+
120
+ // Create the slider contents
121
+ $contents = $( '<div class="' + 'ditty-slider__contents"></div>' );
122
+ this.$contents = $contents;
123
+
124
+ // Create the slider slides
125
+ $slides = $( '<div class="' + 'ditty-slider__slides"></div>' );
126
+ this.$slides = $slides;
127
+
128
+ // Set the initial height
129
+ this.$slides.height( this.currentHeight );
130
+
131
+ // Add the new elements
132
+ $contents.append( $slides );
133
+ this.$elmt.append( $contents );
134
+
135
+ // Setup styles
136
+ this._styleDisplay();
137
+
138
+ // Setup bullets
139
+ this._setupBullets();
140
+
141
+ // Setup arrows
142
+ this._setupArrows();
143
+
144
+ // Bind mouse over/out events
145
+ $contents.on( 'mouseenter', { self: this }, this._mouseenter );
146
+ $contents.on( 'mouseleave', { self: this }, this._mouseleave );
147
+
148
+ // Enable touchswipe
149
+ if ( this.settings.touchSwipe ) {
150
+ delete Hammer.defaults.cssProps.userSelect;
151
+ var hammertime = new Hammer( $contents[0] );
152
+ hammertime.on( 'swipe', function( e ) {
153
+ switch( e.direction ) {
154
+ case 2:
155
+ self._swipeLeft();
156
+ break;
157
+ case 4:
158
+ self._swipeRight();
159
+ break;
160
+ default:
161
+ break;
162
+ }
163
+ } );
164
+ }
165
+
166
+ // Convert slide elements into slide data
167
+ this._convertSlideElements();
168
+
169
+ if ( this.settings.shuffle === true ) {
170
+ this.shuffle();
171
+ }
172
+
173
+ // Preload images
174
+ for ( var i = 0; i < this.total; i++ ) {
175
+ this._preloadSlide( this.settings.slides[i].html );
176
+ }
177
+
178
+ // Trigger the init
179
+ setTimeout( function () {
180
+ // Show the first slide
181
+ if ( self.settings.slideId ) {
182
+ self.showSlideById( self.settings.slideId, 'force' );
183
+ } else {
184
+ self._showSlide();
185
+ }
186
+ self.trigger( 'init' );
187
+ }, 1 );
188
+ },
189
+
190
+ /**
191
+ * Convert slide elements into slide data
192
+ *
193
+ * @since 3.0
194
+ * @return null
195
+ */
196
+ _convertSlideElements: function () {
197
+ if ( this.settings.slidesEl ) {
198
+ var self = this,
199
+ slidesElArray = this.$elmt.find( this.settings.slidesEl );
200
+
201
+ self.settings.slides = [];
202
+ slidesElArray.each( function( i ) {
203
+ var $slide = $( slidesElArray[i] ),
204
+ id = $slide.data( 'slide_id' ) ? $slide.data( 'slide_id' ) : false;
205
+
206
+ self.settings.slides.push( {
207
+ id : id,
208
+ html : $slide.prop( 'outerHTML' ),
209
+ $elmt : $slide
210
+ //cache : cache,
211
+ } );
212
+
213
+ self.$slides.append( $slide );
214
+ $slide.hide();
215
+ } );
216
+ self.total = self.settings.slides.length;
217
+ }
218
+ },
219
+
220
+ /**
221
+ * Preload images of a slide
222
+ *
223
+ * @since 3.0
224
+ * @return null
225
+ */
226
+ _preloadSlide: function ( slide ) {
227
+ var img;
228
+ $( slide ).find( 'img' ).each( function() {
229
+ var src = $( this ).attr( 'src' );
230
+ img = new Image();
231
+ $( img ).on( 'load', function () {
232
+ } ).attr( 'src', src );
233
+ } );
234
+ },
235
+
236
+ /**
237
+ * Start the timer
238
+ *
239
+ * @since 3.0
240
+ * @return null
241
+ */
242
+ _timerStart: function () {
243
+ var self = this;
244
+ if ( 0 === parseInt( this.settings.autoplay ) || this.total < 2 || this.timer || this.hovering || this.paused ) {
245
+ return false;
246
+ }
247
+
248
+ cancelAnimationFrame( this.timer );
249
+
250
+ var startTime = Date.now();
251
+ function ditty_sliderLoop() {
252
+ var currTime = Date.now(),
253
+ passedTime = Math.floor( ( currTime - startTime ) / 1000 );
254
+
255
+ if ( passedTime >= self.settings.autoplaySpeed ) {
256
+ startTime = currTime;
257
+ self._showSlide( self._getNextSlide() );
258
+ }
259
+
260
+ self.timer = requestAnimationFrame( ditty_sliderLoop );
261
+ }
262
+ self.timer = requestAnimationFrame( ditty_sliderLoop );
263
+ },
264
+
265
+ /**
266
+ * Stop the timer
267
+ *
268
+ * @since 3.0
269
+ * @return null
270
+ */
271
+ _timerStop: function () {
272
+ if ( this.timer ) {
273
+ cancelAnimationFrame( this.timer );
274
+ this.timer = null;
275
+ }
276
+ },
277
+
278
+ /**
279
+ * Mouse enter event
280
+ *
281
+ * @since 3.0
282
+ * @return null
283
+ */
284
+ _mouseenter: function ( e ) {
285
+ var self = e.data.self;
286
+ if ( self.settings.autoplay && self.settings.autoplayPause ) {
287
+ self.hovering = true;
288
+ self._timerStop();
289
+ }
290
+ },
291
+
292
+ /**
293
+ * Mouse leave event
294
+ *
295
+ * @since 3.0
296
+ * @return null
297
+ */
298
+ _mouseleave: function ( e ) {
299
+ var self = e.data.self;
300
+ if ( self.settings.autoplay && self.settings.autoplayPause ) {
301
+ self.hovering = false;
302
+ self._timerStart();
303
+ }
304
+ },
305
+
306
+ /**
307
+ * Swipe left event
308
+ *
309
+ * @since 3.0
310
+ * @return null
311
+ */
312
+ _swipeLeft: function () {
313
+ var self = this;
314
+ switch ( this.settings.transition ) {
315
+ case 'slideRight':
316
+ self._showPrevSlide();
317
+ break;
318
+ default:
319
+ self._showNextSlide();
320
+ break;
321
+ }
322
+ },
323
+
324
+ /**
325
+ * Swipe right event
326
+ *
327
+ * @since 3.0
328
+ * @return null
329
+ */
330
+ _swipeRight: function () {
331
+ var self = this;
332
+ switch ( this.settings.transition ) {
333
+ case 'slideRight':
334
+ self._showNextSlide();
335
+ break;
336
+ default:
337
+ self._showPrevSlide();
338
+ break;
339
+ }
340
+ },
341
+
342
+ /**
343
+ * Show a slide
344
+ *
345
+ * @since 3.0
346
+ * @return null
347
+ */
348
+ _showSlide: function( index, direction ) {
349
+
350
+ var $slide = null,
351
+ force = false;
352
+
353
+ if ( null !== this.$currentSlide && this.$currentSlide.hasClass( 'ditty-slide-animating' ) ) {
354
+ return false;
355
+ }
356
+
357
+ if ( undefined === index ) {
358
+ index = this.settings.slide;
359
+ force = true;
360
+ }
361
+ if ( index >= this.total ) {
362
+ index = this.total - 1;
363
+ } else if ( index < 0 ) {
364
+ index = 0;
365
+ }
366
+ if ( ! force && ( index === this.settings.slide ) ) {
367
+ return false;
368
+ }
369
+ if ( undefined === this.settings.slides[index] ) {
370
+ return false;
371
+ }
372
+
373
+ var prevIndex = this.settings.slide,
374
+ prevSlide = this.settings.slides[prevIndex];
375
+
376
+ // Create and add a new slide
377
+ if ( this.settings.slides[index].$elmt ) {
378
+ $slide = this.settings.slides[index].$elmt; // Use an existing element
379
+ } else {
380
+ $slide = $( this.settings.slides[index].html ); // Or, create and cache a new element
381
+ this.settings.slides[index].$elmt = $slide;
382
+ }
383
+
384
+ // Add a the current class
385
+ $slide.addClass( 'ditty-slider__slide' );
386
+ $slide.addClass( 'ditty-slider__slide--current' );
387
+ $slide.addClass( 'ditty-slider__slide--' + index );
388
+
389
+ // Remove any old slides at the same index
390
+ $( this.$slides.children( '.' + 'ditty-slider__slide--' + index ).not( $slide ) ).remove();
391
+
392
+ // Add the custom styles
393
+ this._styleSlide( $slide );
394
+
395
+ // Add the slide to the slider
396
+ $slide.stop( true ).css( {
397
+ position: 'absolute',
398
+ display : 'block',
399
+ opacity : 0
400
+ } );
401
+ this.$slides.append( $slide );
402
+
403
+ // Initialize the height change
404
+ this.animateTransition = true;
405
+ this.animateHeight = true;
406
+ this._setStaticHeight();
407
+
408
+ // After slide update trigger
409
+ var actionParams = [
410
+ index,
411
+ this.settings.slides[index],
412
+ prevIndex,
413
+ prevSlide
414
+ ];
415
+ this.trigger( 'before_slide_update', actionParams );
416
+
417
+ // Hide the previous slide
418
+ if ( null !== this.$currentSlide ) {
419
+ this._animateOut( this.$currentSlide, $slide, direction );
420
+ }
421
+
422
+ // Set this as the current slide
423
+ this.$currentSlide = $slide;
424
+ this.settings.slide = index;
425
+ this.slideObj = this.settings.slides[index];
426
+ this.visibleSlides = [this.settings.slides[index]];
427
+ if ( ! $slide.hasClass( 'ditty-slide-animating' ) ) {
428
+ this._slideResetPosition( $slide, direction );
429
+ }
430
+ this._animateIn( $slide, actionParams );
431
+ this._animateHeight();
432
+ this._activateBullet();
433
+ this.slidesDisplayed = this.slidesDisplayed + 1;
434
+ },
435
+
436
+ /**
437
+ * Animate a slide into view
438
+ *
439
+ * @since 3.0
440
+ * @return null
441
+ */
442
+ _animateIn: function( $slide, actionParams ) {
443
+ var self = this,
444
+ transitionSpeed = ( 0 === parseInt( this.slidesDisplayed ) ) ? this.settings.initTransitionSpeed : this.settings.transitionSpeed,
445
+ transitionEase = ( 0 === parseInt( this.slidesDisplayed ) ) ? this.settings.initTransitionEase : this.settings.transitionEase;
446
+
447
+ this.transitioning = true;
448
+ this._timerStop();
449
+ $slide.show();
450
+ $slide.addClass( 'ditty-slide-animating' );
451
+ $slide.stop( true ).animate( {
452
+ left : 0,
453
+ top : 0,
454
+ opacity : 1
455
+ }, parseFloat( transitionSpeed ) * 1000, transitionEase, function() {
456
+ $slide.removeClass( 'ditty-slide-animating' );
457
+ $slide.css( 'position', 'relative' );
458
+ self.transitioning = false;
459
+ self.animateTransition = false;
460
+ self._removeStaticHeight();
461
+ self._timerStart();
462
+ self.trigger( 'after_slide_update', actionParams );
463
+ });
464
+ },
465
+
466
+ /**
467
+ * Animate a slide out of view
468
+ *
469
+ * @since 3.0
470
+ * @return null
471
+ */
472
+ _animateOut: function( $slide, $nextSlide, direction ) {
473
+ this.$lastSlide = $slide;
474
+
475
+ $slide.removeClass( 'ditty-slider__slide--current' );
476
+ $slide.css( 'position', 'absolute' );
477
+
478
+ var posX = 0,
479
+ posY = 0,
480
+ opacity = 1,
481
+ transition = this.settings.transition;
482
+
483
+ if ( 'reverse' === direction ) {
484
+ transition = this._reverseTransition( transition );
485
+ }
486
+
487
+ switch( transition ) {
488
+ case 'fade':
489
+ opacity = 0;
490
+ break;
491
+ case 'slideRight':
492
+ posX = this.$slides.outerWidth();
493
+ break;
494
+ case 'slideLeft':
495
+ posX = '-' + $slide.outerWidth();
496
+ break;
497
+ case 'slideDown':
498
+ posY = $nextSlide.outerHeight();
499
+ break;
500
+ case 'slideUp':
501
+ posY = '-' + $slide.outerHeight();
502
+ break;
503
+ }
504
+
505
+ $slide.css( {
506
+ zIndex: 1
507
+ } );
508
+
509
+ $slide.addClass( 'ditty-slide-animating' );
510
+ $slide.stop( true ).animate( {
511
+ left : posX + 'px',
512
+ top : posY + 'px',
513
+ opacity : opacity
514
+ }, parseFloat( this.settings.transitionSpeed ) * 1000, this.settings.transitionEase, function() {
515
+ $slide.removeClass( 'ditty-slide-animating' );
516
+ $slide.hide();
517
+ } );
518
+ },
519
+
520
+ /**
521
+ * Figure out and set a slide's reset position
522
+ *
523
+ * @since 3.0
524
+ * @return null
525
+ */
526
+ _slideResetPosition: function( $slide, direction ) {
527
+ var posX = 0,
528
+ posY = 0,
529
+ opacity = 1,
530
+ transition = ( 0 === parseInt( this.slidesDisplayed ) ) ? this.settings.initTransition : this.settings.transition;
531
+
532
+ if ( 'reverse' === direction ) {
533
+ transition = this._reverseTransition( transition );
534
+ }
535
+
536
+ switch( transition ) {
537
+ case 'fade':
538
+ opacity = 0;
539
+ break;
540
+ case 'slideLeft':
541
+ posX = this.$slides.outerWidth();
542
+ break;
543
+ case 'slideRight':
544
+ posX = '-' + $slide.outerWidth();
545
+ break;
546
+ case 'slideUp':
547
+ if ( null !== this.$lastSlide ) {
548
+ posY = this.$lastSlide.outerHeight();
549
+ } else {
550
+ posY = this.$slides.outerHeight();
551
+ if ( $slide.outerHeight() > posY ) {
552
+ posY = $slide.outerHeight();
553
+ }
554
+ }
555
+ break;
556
+ case 'slideDown':
557
+ posY = '-' + $slide.outerHeight();
558
+ break;
559
+ }
560
+
561
+ $slide.stop( true ).css( {
562
+ display : 'block',
563
+ opacity : opacity,
564
+ left : posX + 'px',
565
+ top : posY + 'px',
566
+ zIndex : 9
567
+ } );
568
+ },
569
+
570
+ /**
571
+ * Set a static height before starting an animation
572
+ *
573
+ * @since 3.0
574
+ * @return null
575
+ */
576
+ _setStaticHeight: function () {
577
+ var height = this.$slides.outerHeight();
578
+ this.$slides.stop( true ).css( 'height', height + 'px' );
579
+ },
580
+
581
+ /**
582
+ * Remove the static height after all animations are complete
583
+ *
584
+ * @since 3.0
585
+ * @return null
586
+ */
587
+ _removeStaticHeight: function () {
588
+ if ( ! ( this.animateTransition || this.animateHeight ) ) {
589
+ this.$slides.stop( true ).css( 'height', 'auto' );
590
+ }
591
+ },
592
+
593
+ /**
594
+ * Animate the height of the slider
595
+ *
596
+ * @since 3.0
597
+ * @return null
598
+ */
599
+ _animateHeight: function () {
600
+ var self = this,
601
+ height = this.$currentSlide.outerHeight(),
602
+ heightSpeed = ( 0 === parseInt( this.slidesDisplayed ) ) ? this.settings.initHeightSpeed : this.settings.heightSpeed,
603
+ heightEase = ( 0 === parseInt( this.slidesDisplayed ) ) ? this.settings.initHeightEase : this.settings.heightEase;
604
+
605
+ this.currentHeight = height;
606
+
607
+ this.$slides.stop( true ).animate( {
608
+ height: height + 'px'
609
+ }, parseFloat( heightSpeed ) * 1000, heightEase, function() {
610
+ self.animateHeight = false;
611
+ self._removeStaticHeight();
612
+ self.trigger( 'height_updated' );
613
+ });
614
+ },
615
+
616
+ /**
617
+ * Return the opposite of the current transition
618
+ *
619
+ * @since 3.0
620
+ * @return string reverseTransition
621
+ */
622
+ _reverseTransition: function( transition ) {
623
+ var reverseTransition = transition;
624
+
625
+ switch( transition ) {
626
+ case 'slideLeft':
627
+ reverseTransition = 'slideRight';
628
+ break;
629
+ case 'slideRight':
630
+ reverseTransition = 'slideLeft';
631
+ break;
632
+ case 'slideUp':
633
+ reverseTransition = 'slideDown';
634
+ break;
635
+ case 'slideDown':
636
+ reverseTransition = 'slideUp';
637
+ break;
638
+ }
639
+ return reverseTransition;
640
+ },
641
+
642
+ /**
643
+ * Get the next slide index
644
+ *
645
+ * @since 3.0
646
+ * @return int nextSlide
647
+ */
648
+ _getNextSlide: function() {
649
+ var nextSlide = this.settings.slide + 1;
650
+ if ( nextSlide >= this.total ) {
651
+ nextSlide = 0;
652
+ }
653
+ return nextSlide;
654
+ },
655
+
656
+ /**
657
+ * Show the next slide
658
+ *
659
+ * @since 3.0
660
+ * @return null
661
+ */
662
+ _showNextSlide: function() {
663
+ this._showSlide( this._getNextSlide() );
664
+ },
665
+
666
+ /**
667
+ * Get the previous slide index
668
+ *
669
+ * @since 3.0
670
+ * @return int prevSlide
671
+ */
672
+ _getPrevSlide: function() {
673
+ var prevSlide = this.settings.slide - 1;
674
+ if ( prevSlide < 0 ) {
675
+ prevSlide = this.total - 1;
676
+ }
677
+ return prevSlide;
678
+ },
679
+
680
+ /**
681
+ * Show the previous slide
682
+ *
683
+ * @since 3.0
684
+ * @return null
685
+ */
686
+ _showPrevSlide: function() {
687
+ this._showSlide( this._getPrevSlide(), 'reverse' );
688
+ },
689
+
690
+ /**
691
+ * Bullet click action
692
+ *
693
+ * @since 3.0
694
+ * @return null
695
+ */
696
+ _clickBullet: function( e ) {
697
+ e.preventDefault();
698
+ var self = e.data.self,
699
+ index = $( e.target ).data( 'index' ),
700
+ direction;
701
+
702
+ if ( index < self.settings.slide ) {
703
+ direction = 'reverse';
704
+ }
705
+
706
+ self._showSlide( index, direction );
707
+ },
708
+
709
+ /**
710
+ * Activate the correct bullet for the current slide
711
+ *
712
+ * @since 3.0
713
+ * @return null
714
+ */
715
+ _activateBullet: function () {
716
+ if ( 'none' === this.settings.bullets || 2 > parseInt( this.total ) ) {
717
+ return false;
718
+ }
719
+
720
+ var prev = this._getPrevSlide(),
721
+ next = this._getNextSlide();
722
+
723
+ this.$bullets.find( '.' + 'ditty-slider__bullet' ).removeClass( 'ditty-slider__bullet--active ' + 'ditty-slider__bullet--next ' + 'ditty-slider__bullet--prev' );
724
+ this.$bullets.find( '.' + 'ditty-slider__bullet[data-index="' + this.settings.slide + '"]' ).addClass( 'ditty-slider__bullet--active' );
725
+ this.$bullets.find( '.' + 'ditty-slider__bullet[data-index="' + prev + '"]' ).addClass( 'ditty-slider__bullet--prev' );
726
+ this.$bullets.find( '.' + 'ditty-slider__bullet[data-index="' + next + '"]' ).addClass( 'ditty-slider__bullet--next' );
727
+ this._styleBullets();
728
+ },
729
+
730
+ /**
731
+ * Setup the bullets
732
+ *
733
+ * @since 3.0
734
+ * @return null
735
+ */
736
+ _setupBullets: function () {
737
+ var self = this;
738
+
739
+ if ( null === this.$bullets ) {
740
+ var $bullets = $( '<div class="' + 'ditty-slider__bullets"></div>' );
741
+ this.$bullets = $bullets;
742
+ this.$elmt.append( $bullets );
743
+ }
744
+ if ( 'none' === this.settings.bullets || 2 > parseInt( this.total ) ) {
745
+ this.$bullets.hide();
746
+ } else {
747
+ this.$bullets.empty();
748
+ for ( var i = 0; i < this.total; i++ ) {
749
+ var $bullet = $( '<a href="#" class="' + 'ditty-slider__bullet" data-index="' + i + '">' + this.settings.bullet + '</a>' );
750
+ $bullet.on( 'click', { self: this }, self._clickBullet );
751
+ this.$bullets.append( $bullet );
752
+ }
753
+
754
+ this.$bullets.show();
755
+ this._activateBullet();
756
+ }
757
+ },
758
+
759
+ /**
760
+ * Setup the bullets
761
+ *
762
+ * @since 3.0
763
+ * @return null
764
+ */
765
+ _styleBullets: function () {
766
+ // Reset styles
767
+ this.$bullets.removeAttr( 'style' );
768
+
769
+ this.$bullets.find( 'a' ).css( {
770
+ backgroundColor: this.settings.bulletsColor,
771
+ marginLeft: this.settings.bulletsSpacing + 'px',
772
+ marginRight: this.settings.bulletsSpacing + 'px'
773
+ } );
774
+ this.$bullets.find( 'a.ditty-slider__bullet--active' ).css( { backgroundColor: this.settings.bulletsColorActive } );
775
+
776
+ // Add the custom padding & add to the list
777
+ this.$bullets.css( this.settings.bulletsPadding );
778
+ switch( this.settings.bulletsPosition ) {
779
+ case 'topLeft':
780
+ this.$bullets.css( {
781
+ order: 0,
782
+ justifyContent: 'flex-start'
783
+ } );
784
+ break;
785
+ case 'topCenter':
786
+ this.$bullets.css( {
787
+ order: 0,
788
+ justifyContent: 'center'
789
+ } );
790
+ break;
791
+ case 'topRight':
792
+ this.$bullets.css( {
793
+ order: 0,
794
+ justifyContent: 'flex-end'
795
+ } );
796
+ break;
797
+ case 'bottomLeft':
798
+ this.$bullets.css( {
799
+ order: 2,
800
+ justifyContent: 'flex-start'
801
+ } );
802
+ break;
803
+ case 'bottomCenter':
804
+ this.$bullets.css( {
805
+ order: 2,
806
+ justifyContent: 'center'
807
+ } );
808
+ break;
809
+ case 'bottomRight':
810
+ this.$bullets.css( {
811
+ order: 2,
812
+ justifyContent: 'flex-end'
813
+ } );
814
+ break;
815
+ }
816
+ },
817
+
818
+ /**
819
+ * Previous arrow click action
820
+ *
821
+ * @since 3.0
822
+ * @return null
823
+ */
824
+ _clickPrev: function( e ) {
825
+ e.preventDefault();
826
+ var self = e.data.self;
827
+ self._showPrevSlide();
828
+ },
829
+
830
+ /**
831
+ * Next arrow click action
832
+ *
833
+ * @since 3.0
834
+ * @return null
835
+ */
836
+ _clickNext: function( e ) {
837
+ e.preventDefault();
838
+ var self = e.data.self;
839
+ self._showNextSlide();
840
+ },
841
+
842
+ /**
843
+ * Setup the arrows for the slider
844
+ *
845
+ * @since 3.0
846
+ * @return null
847
+ */
848
+ _setupArrows: function () {
849
+ if ( null === this.$arrows ) {
850
+ var $arrows = $( '<div class="' + 'ditty-slider__arrows"></div>' ),
851
+ $prev = $( '<a href="#" class="' + 'ditty-slider__prev">' + this.settings.navPrev + '</a>' ),
852
+ $next = $( '<a href="#" class="' + 'ditty-slider__next">' + this.settings.navNext + '</a>' );
853
+
854
+ $prev.on( 'click', { self: this }, this._clickPrev );
855
+ $next.on( 'click', { self: this }, this._clickNext );
856
+ $arrows.append( $prev, $next );
857
+
858
+ this.$arrows = $arrows;
859
+ this.$contents.append( $arrows );
860
+ }
861
+
862
+ // Reset styles
863
+ this.$arrows.removeAttr( 'style' );
864
+
865
+ if ( 'none' === this.settings.arrows || 2 > this.total ) {
866
+ this.$arrows.hide();
867
+ } else {
868
+ this.$arrows.css( 'display', 'flex' );
869
+ }
870
+
871
+ // Add the custom styles & add to the list
872
+ this.$arrows.css( this.settings.arrowsPadding );
873
+ this.$arrows.css( { alignItems: this.settings.arrowsPosition } );
874
+ this.$arrows.find( 'i' ).css( { color: this.settings.arrowsIconColor } );
875
+ this.$arrows.find( 'a' ).css( { backgroundColor: this.settings.arrowsBgColor } );
876
+
877
+ if ( 1 === parseInt( this.settings.arrowsStatic ) ) {
878
+ this.$arrows.addClass( 'ditty-slider__arrows--static' );
879
+ } else {
880
+ this.$arrows.removeClass( 'ditty-slider__arrows--static' );
881
+ }
882
+ },
883
+
884
+ /**
885
+ * Style slider and content elements
886
+ *
887
+ * @since 3.0
888
+ * @return null
889
+ */
890
+ _styleDisplay: function () {
891
+ this.$elmt.css( {
892
+ maxWidth: this.settings.maxWidth,
893
+ backgroundColor: this.settings.bgColor,
894
+ borderColor: this.settings.borderColor,
895
+ borderStyle: this.settings.borderStyle
896
+ } );
897
+ this.$elmt.css( this.settings.padding );
898
+ this.$elmt.css( this.settings.margin );
899
+ this.$elmt.css( this.settings.borderRadius );
900
+ this.$elmt.css( this.settings.borderWidth );
901
+
902
+ this.$contents.css( {
903
+ backgroundColor: this.settings.contentsBgColor,
904
+ borderColor: this.settings.contentsBorderColor,
905
+ borderStyle: this.settings.contentsBorderStyle
906
+ } );
907
+ this.$contents.css( this.settings.contentsPadding );
908
+ this.$contents.css( this.settings.contentsBorderRadius );
909
+ this.$contents.css( this.settings.contentsBorderWidth );
910
+ },
911
+
912
+ /**
913
+ * Style the slide
914
+ *
915
+ * @since 3.0
916
+ * @return null
917
+ */
918
+ _styleSlide: function ( $slide ) {
919
+ $slide.css( {
920
+ backgroundColor: this.settings.slideBgColor,
921
+ borderColor: this.settings.slideBorderColor,
922
+ borderStyle: this.settings.slideBorderStyle
923
+ } );
924
+ $slide.css( this.settings.slidePadding );
925
+ $slide.css( this.settings.slideBorderRadius );
926
+ $slide.css( this.settings.slideBorderWidth );
927
+ },
928
+
929
+ /**
930
+ * Maybe adjust slider
931
+ *
932
+ * @since 3.0
933
+ * @return null
934
+ */
935
+ updateSlides: function ( newSlides ) {
936
+ var currentCount = this.settings.slides.length,
937
+ newCount = newSlides.length,
938
+ currentIndex = this.settings.slide,
939
+ newIndex = this.settings.slide;
940
+
941
+ for ( var i = 0; i < newSlides.length; i++ ) {
942
+ this._preloadSlide( newSlides[i] );
943
+ }
944
+
945
+ this.settings.slides = newSlides;
946
+ if ( currentCount !== newCount ) {
947
+ this.total = newSlides.length;
948
+ this._setupBullets();
949
+ this._setupArrows();
950
+ }
951
+
952
+ if ( currentIndex >= this.total ) {
953
+ newIndex = this.total - 1;
954
+ }
955
+
956
+ if ( currentIndex !== newIndex ) {
957
+ this._showSlide( newIndex );
958
+ }
959
+ },
960
+
961
+ /**
962
+ * Return option data for the object
963
+ *
964
+ * @since 3.0
965
+ * @return value
966
+ */
967
+ _getOption: function( key ) {
968
+ switch( key ) {
969
+ case 'elmnt':
970
+ return this;
971
+ case 'height':
972
+ return this.$slides.outerHeight();
973
+ case 'currentSlide':
974
+ return this.$currentSlide;
975
+ default:
976
+ return this.settings[key];
977
+ }
978
+ },
979
+
980
+ /**
981
+ * Set options data for the object
982
+ *
983
+ * @since 3.0
984
+ * @return null
985
+ */
986
+ _setOption: function( key, value ) {
987
+ if ( undefined === value ) {
988
+ return false;
989
+ }
990
+ if ( 'slides' !== key ) {
991
+ this.settings[key] = value;
992
+ }
993
+ switch( key ) {
994
+ case 'slides':
995
+ this.updateSlides( value );
996
+ break;
997
+ case 'slide':
998
+ this.slide = value;
999
+ break;
1000
+ case 'autoplay':
1001
+ if ( 1 === parseInt( value ) ) {
1002
+ if ( ! this.timer ) {
1003
+ this._timerStart();
1004
+ }
1005
+ } else {
1006
+ this._timerStop();
1007
+ }
1008
+ break;
1009
+ case 'bgColor':
1010
+ case 'padding':
1011
+ case 'borderColor':
1012
+ case 'borderStyle':
1013
+ case 'borderWidth':
1014
+ case 'borderRadius':
1015
+ case 'contentsBgColor':
1016
+ case 'contentsPadding':
1017
+ case 'contentsBorderColor':
1018
+ case 'contentsBorderStyle':
1019
+ case 'contentsBorderWidth':
1020
+ case 'contentsBorderRadius':
1021
+ this.animateHeight = true;
1022
+ this._setStaticHeight();
1023
+ this._styleDisplay();
1024
+ this._animateHeight();
1025
+ break;
1026
+ case 'slideBgColor':
1027
+ case 'slidePadding':
1028
+ case 'slideBorderColor':
1029
+ case 'slideBorderStyle':
1030
+ case 'slideBorderWidth':
1031
+ case 'slideBorderRadius':
1032
+ this.animateHeight = true;
1033
+ this._setStaticHeight();
1034
+ this._styleSlide( this.$currentSlide );
1035
+ this._animateHeight();
1036
+ break;
1037
+ case 'arrows':
1038
+ case 'arrowsIconColor':
1039
+ case 'arrowsBgColor':
1040
+ case 'arrowsPadding':
1041
+ case 'arrowsPosition':
1042
+ case 'arrowsStatic':
1043
+ this._setupArrows();
1044
+ break;
1045
+ case 'bullets':
1046
+ this._setupBullets();
1047
+ break;
1048
+ case 'bulletsColor':
1049
+ case 'bulletsColorActive':
1050
+ case 'bulletsPosition':
1051
+ case 'bulletsSpacing':
1052
+ case 'bulletsPadding':
1053
+ this._styleBullets();
1054
+ break;
1055
+ default:
1056
+ this.settings[key] = value;
1057
+ break;
1058
+ }
1059
+ this.trigger( 'update' );
1060
+ },
1061
+
1062
+ /**
1063
+ * Shuffle the slides
1064
+ *
1065
+ * @since 3.0
1066
+ * @return null
1067
+ */
1068
+ shuffle: function () {
1069
+ var temp,
1070
+ rand;
1071
+
1072
+ for ( var i = this.total - 1; i > 0; i-- ) {
1073
+ rand = Math.floor( Math.random() * ( i + 1 ) );
1074
+ temp = this.settings.slides[i];
1075
+
1076
+ this.settings.slides[i] = this.settings.slides[rand];
1077
+ this.settings.slides[rand] = temp;
1078
+ }
1079
+ },
1080
+
1081
+ /**
1082
+ * Hook to start the timer
1083
+ *
1084
+ * @since 3.0
1085
+ * @return null
1086
+ */
1087
+ start: function () {
1088
+ this._timerStart();
1089
+ },
1090
+
1091
+ /**
1092
+ * Hook to stop the timer
1093
+ *
1094
+ * @since 3.0
1095
+ * @return null
1096
+ */
1097
+ stop: function () {
1098
+ this._timerStop();
1099
+ },
1100
+
1101
+ /**
1102
+ * Hook to pause the slider
1103
+ *
1104
+ * @since 3.0
1105
+ * @return null
1106
+ */
1107
+ pause: function () {
1108
+ this.paused = true;
1109
+ },
1110
+
1111
+ /**
1112
+ * Hook to resume the slider
1113
+ *
1114
+ * @since 3.0
1115
+ * @return null
1116
+ */
1117
+ resume: function () {
1118
+ this.paused = false;
1119
+ this._timerStart();
1120
+ },
1121
+
1122
+ /**
1123
+ * Hook to return the current slide
1124
+ *
1125
+ * @since 3.0
1126
+ * @return object $currentSlide
1127
+ */
1128
+ current: function () {
1129
+ return this.$currentSlide;
1130
+ },
1131
+
1132
+ /**
1133
+ * Hook to show a specific slide by index
1134
+ *
1135
+ * @since 3.0
1136
+ * @return null
1137
+ */
1138
+ showSlide: function ( index ) {
1139
+ this._showSlide( index );
1140
+ },
1141
+
1142
+ /**
1143
+ * Hook to show a specific slide by id
1144
+ *
1145
+ * @since 3.0
1146
+ * @return null
1147
+ */
1148
+ showSlideById: function ( id, force ) {
1149
+ var self = this;
1150
+ $.each( this.settings.slides, function( index, slide ) {
1151
+ if ( slide.id === id ) {
1152
+ if ( 'force' === force ) {
1153
+ self.settings.slide = index;
1154
+ self._showSlide();
1155
+ } else {
1156
+ self._showSlide( index );
1157
+ }
1158
+ return false;
1159
+ }
1160
+ } );
1161
+ },
1162
+
1163
+ /**
1164
+ * Hook to add a slide
1165
+ *
1166
+ * @since 3.0
1167
+ * @return null
1168
+ */
1169
+ addSlide: function ( slide, index, type ) {
1170
+
1171
+ var indexExists = true;
1172
+ if ( index >= this.total || index < 0 ) {
1173
+ indexExists = false;
1174
+ }
1175
+
1176
+ // Replace a slide
1177
+ if ( 'replace' === type && indexExists ) {
1178
+
1179
+ // Let other scripts know this slide is being removed
1180
+ var toBeRemoved = this.settings.slides[index];
1181
+ this.trigger( 'slide_removed', [toBeRemoved] );
1182
+
1183
+ this.settings.slides.splice( index, 1, slide );
1184
+
1185
+ // Add a slide
1186
+ } else {
1187
+ if ( null === index || '' === index || ! indexExists ) {
1188
+ this.settings.slides.splice( parseInt( this.settings.slide ) + 1, 0, slide );
1189
+ } else {
1190
+ this.settings.slides.splice( index, 0, slide);
1191
+ }
1192
+ }
1193
+
1194
+ this.total = this.settings.slides.length;
1195
+
1196
+ // Preload slide assets
1197
+ this._preloadSlide( slide );
1198
+
1199
+ this.trigger( 'update' );
1200
+ },
1201
+
1202
+ /**
1203
+ * Hook to add or replace a slide by id
1204
+ *
1205
+ * @since 3.0
1206
+ * @return null
1207
+ */
1208
+ addSlideById: function ( id, html ) {
1209
+ var newSlide = {
1210
+ id : id,
1211
+ html : html
1212
+ },
1213
+ slideIndex = false;
1214
+
1215
+ $.each( this.settings.slides, function( index, slide ) {
1216
+ if ( String( slide.id ) === String( id ) ) {
1217
+ slideIndex = index;
1218
+ return;
1219
+ }
1220
+ } );
1221
+
1222
+ if ( slideIndex ) {
1223
+
1224
+ // Let other scripts know this slide is being removed
1225
+ var toBeRemoved = this.settings.slides[slideIndex];
1226
+ this.trigger( 'slide_removed', [toBeRemoved] );
1227
+
1228
+ // Remove cached elements
1229
+ if ( this.settings.slides[slideIndex].$elmt ) {
1230
+ this.settings.slides[slideIndex].$elmt.remove();
1231
+ }
1232
+ this.settings.slides.splice( slideIndex, 1, newSlide );
1233
+ } else {
1234
+ this.settings.slides.push( newSlide );
1235
+ }
1236
+
1237
+ this.total = this.settings.slides.length;
1238
+ this._preloadSlide( newSlide );
1239
+ this.trigger( 'update' );
1240
+ },
1241
+
1242
+ /**
1243
+ * Hook to delete a slide by id
1244
+ *
1245
+ * @since 3.0
1246
+ * @return null
1247
+ */
1248
+ deleteSlideById: function ( id ) {
1249
+ var updatedSlides = [];
1250
+
1251
+ $.each( this.settings.slides, function( index, slide ) {
1252
+ if ( String( slide.id ) !== String( id ) ) {
1253
+ updatedSlides.push( slide );
1254
+ }
1255
+ } );
1256
+
1257
+ this.settings.slides = updatedSlides;
1258
+ this.total = this.settings.slides.length;
1259
+
1260
+ this.trigger( 'update' );
1261
+ },
1262
+
1263
+ /**
1264
+ * Hook to delete a slide by index
1265
+ *
1266
+ * @since 3.0
1267
+ * @return null
1268
+ */
1269
+ deleteSlide: function ( index ) {
1270
+ if ( index >= this.total || index < 0 ) {
1271
+ return false;
1272
+ }
1273
+
1274
+ // Let other scripts know this slide is being removed
1275
+ var toBeRemoved = this.settings.slides[index];
1276
+ this.trigger( 'slide_removed', [toBeRemoved] );
1277
+
1278
+ // Remove cached elements
1279
+ //if ( this.settings.slides[index].cache && this.settings.slides[index].$elmt ) {
1280
+ if ( this.settings.slides[index].$elmt ) {
1281
+ this.settings.slides[index].$elmt.remove();
1282
+ }
1283
+ this.settings.slides.splice( index, 1 );
1284
+ this.total = this.settings.slides.length;
1285
+
1286
+ this.trigger( 'update' );
1287
+ },
1288
+
1289
+ /**
1290
+ * Hook to set a static height
1291
+ *
1292
+ * @since 3.0
1293
+ * @return null
1294
+ */
1295
+ setStaticHeight: function () {
1296
+ this.animateHeight = true;
1297
+ this._setStaticHeight();
1298
+ },
1299
+
1300
+ /**
1301
+ * Hook to animate the slider height
1302
+ *
1303
+ * @since 3.0
1304
+ * @return null
1305
+ */
1306
+ animateHeight: function () {
1307
+ this._animateHeight();
1308
+ },
1309
+
1310
+ /**
1311
+ * Hook to trigger events
1312
+ *
1313
+ * @since 3.0
1314
+ * @return null
1315
+ */
1316
+ trigger: function ( fn, customParams ) {
1317
+ var params = [];
1318
+
1319
+ switch( fn ) {
1320
+ case 'height_updated':
1321
+ params = [
1322
+ this.currentHeight
1323
+ ];
1324
+ break;
1325
+ default:
1326
+ params = [
1327
+ this.settings,
1328
+ this.$elmt
1329
+ ];
1330
+ break;
1331
+ }
1332
+
1333
+ if ( customParams ) {
1334
+ params = customParams;
1335
+ }
1336
+
1337
+ this.$elmt.trigger( 'ditty_slider_' + fn, params );
1338
+
1339
+ if ( typeof this.settings[fn] === 'function' ) {
1340
+ this.settings[fn].apply( this.$elmt, params );
1341
+ }
1342
+ },
1343
+
1344
+ /**
1345
+ * Hook to get or set slider options
1346
+ *
1347
+ * @since 3.0
1348
+ * @return null
1349
+ */
1350
+ options: function ( key, value ) {
1351
+ var self = this;
1352
+ if ( typeof key === 'object' ) {
1353
+ $.each( key, function( k, v ) {
1354
+ self._setOption( k, v );
1355
+ } );
1356
+ } else if ( typeof key === 'string' ) {
1357
+ if ( value === undefined ) {
1358
+ return self._getOption( key );
1359
+ }
1360
+ self._setOption( key, value );
1361
+ } else {
1362
+ return self.settings;
1363
+ }
1364
+ },
1365
+
1366
+ /**
1367
+ * Hook to destroy this object
1368
+ *
1369
+ * @since 3.0
1370
+ * @return null
1371
+ */
1372
+ destroy: function () {
1373
+ clearInterval( this.timer );
1374
+ this.$elmt.removeClass( 'ditty-slider' );
1375
+ this.$elmt.removeAttr( 'style' );
1376
+ this.$elmt.empty();
1377
+ this.trigger( 'destroy' );
1378
+ this.elmt._ditty_slider = null;
1379
+ }
1380
+ };
1381
+
1382
+ /**
1383
+ * Setup the class or listen for hooks
1384
+ *
1385
+ * @since 3.0
1386
+ * @return null
1387
+ */
1388
+ $.fn.ditty_slider = function( options ) {
1389
+ var args = arguments,
1390
+ error = false,
1391
+ returns;
1392
+
1393
+ if ( options === undefined || typeof options === 'object' ) {
1394
+ return this.each( function () {
1395
+ if ( ! this._ditty_slider ) {
1396
+ this._ditty_slider = new Ditty_Slider( this, options );
1397
+ }
1398
+ });
1399
+ } else if ( typeof options === 'string' ) {
1400
+ this.each( function () {
1401
+ var instance = this._ditty_slider;
1402
+
1403
+ if ( ! instance ) {
1404
+ throw new Error( 'No Ditty_Slider applied to this element.' );
1405
+ }
1406
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
1407
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
1408
+ } else {
1409
+ error = true;
1410
+ }
1411
+ } );
1412
+
1413
+ if ( error ) {
1414
+ throw new Error( 'No method "' + options + '" in Ditty_Slider.' );
1415
+ }
1416
+
1417
+ return returns !== undefined ? returns : this;
1418
+ }
1419
+ };
1420
+
1421
+ $.ditty_slider = {};
1422
+ $.ditty_slider.defaults = defaults;
1423
+
1424
+ } )( jQuery );
includes/js/class-ditty-slider.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function($){"use strict";var t={transition:"fade",transitionEase:"easeInOutQuint",transitionSpeed:1.5,autoplay:0,autoplayPause:0,autoplaySpeed:7,height:0,heightEase:"easeInOutQuint",heightSpeed:1.5,initTransition:"fade",initTransitionEase:"easeInOutQuint",initTransitionSpeed:1.5,initHeightEase:"easeInOutQuint",initHeightSpeed:.5,arrows:"none",arrowsIconColor:"",arrowsBgColor:"",arrowsPosition:"center",arrowsPadding:{},arrowsStatic:0,navPrev:'<i class="fas fa-angle-left"></i>',navNext:'<i class="fas fa-angle-right"></i>',bullets:"none",bulletsColor:"",bulletsColorActive:"",bulletsPosition:"bottomCenter",bulletsSpacing:2,bulletsPadding:{},bullet:"",maxWidth:"",bgColor:"",padding:{},margin:{},borderColor:{},borderStyle:{},borderWidth:{},borderRadius:{},contentsBgColor:"",contentsPadding:{},contentsBorderColor:{},contentsBorderStyle:{},contentsBorderWidth:{},contentsBorderRadius:{},slideBgColor:"",slidePadding:{},slideBorderColor:{},slideBorderStyle:{},slideBorderWidth:{},slideBorderRadius:{},slide:0,slideId:!1,touchSwipe:!0,slidesEl:!1,slides:[]},s=function(s,i){this.elmt=s,this.settings=$.extend({},t,$.ditty_slider.defaults,i),this.slide=this.settings.slide,this.slideObj={},this.total=this.settings.slides.length,this.$elmt=$(s),this.$contents=null,this.$slides=null,this.$bullets=null,this.$arrows=null,this.$currentSlide=null,this.$lastSlide=null,this.transitioning=!1,this.hovering=!1,this.timer=null,this.currentHeight=this.settings.height,this.animateTransition=!1,this.animateHeight=!1,this.slidesDisplayed=0,this.paused=!1,this.transitions=["fade","slideLeft","slideRight","slideDown","slideUp"],this._init()};s.prototype={_init:function(){var t,s,i=this;(this.$elmt.addClass("ditty-slider"),t=$('<div class="ditty-slider__contents"></div>'),this.$contents=t,s=$('<div class="ditty-slider__slides"></div>'),this.$slides=s,this.$slides.height(this.currentHeight),t.append(s),this.$elmt.append(t),this._styleDisplay(),this._setupBullets(),this._setupArrows(),t.on("mouseenter",{self:this},this._mouseenter),t.on("mouseleave",{self:this},this._mouseleave),this.settings.touchSwipe)&&(delete Hammer.defaults.cssProps.userSelect,new Hammer(t[0]).on("swipe",(function(t){switch(t.direction){case 2:i._swipeLeft();break;case 4:i._swipeRight()}})));this._convertSlideElements(),!0===this.settings.shuffle&&this.shuffle();for(var e=0;e<this.total;e++)this._preloadSlide(this.settings.slides[e].html);setTimeout((function(){i.settings.slideId?i.showSlideById(i.settings.slideId,"force"):i._showSlide(),i.trigger("init")}),1)},_convertSlideElements:function(){if(this.settings.slidesEl){var t=this,s=this.$elmt.find(this.settings.slidesEl);t.settings.slides=[],s.each((function(i){var e=$(s[i]),l=!!e.data("slide_id")&&e.data("slide_id");t.settings.slides.push({id:l,html:e.prop("outerHTML"),$elmt:e}),t.$slides.append(e),e.hide()})),t.total=t.settings.slides.length}},_preloadSlide:function(t){var s;$(t).find("img").each((function(){var t=$(this).attr("src");s=new Image,$(s).on("load",(function(){})).attr("src",t)}))},_timerStart:function(){var t=this;if(0===parseInt(this.settings.autoplay)||this.total<2||this.timer||this.hovering||this.paused)return!1;cancelAnimationFrame(this.timer);var s=Date.now();t.timer=requestAnimationFrame((function i(){var e=Date.now();Math.floor((e-s)/1e3)>=t.settings.autoplaySpeed&&(s=e,t._showSlide(t._getNextSlide())),t.timer=requestAnimationFrame(i)}))},_timerStop:function(){this.timer&&(cancelAnimationFrame(this.timer),this.timer=null)},_mouseenter:function(t){var s=t.data.self;s.settings.autoplay&&s.settings.autoplayPause&&(s.hovering=!0,s._timerStop())},_mouseleave:function(t){var s=t.data.self;s.settings.autoplay&&s.settings.autoplayPause&&(s.hovering=!1,s._timerStart())},_swipeLeft:function(){if("slideRight"===this.settings.transition)this._showPrevSlide();else this._showNextSlide()},_swipeRight:function(){if("slideRight"===this.settings.transition)this._showNextSlide();else this._showPrevSlide()},_showSlide:function(t,s){var i=null,e=!1;if(null!==this.$currentSlide&&this.$currentSlide.hasClass("ditty-slide-animating"))return!1;if(void 0===t&&(t=this.settings.slide,e=!0),t>=this.total?t=this.total-1:t<0&&(t=0),!e&&t===this.settings.slide)return!1;if(void 0===this.settings.slides[t])return!1;var l=this.settings.slide,n=this.settings.slides[l];this.settings.slides[t].$elmt?i=this.settings.slides[t].$elmt:(i=$(this.settings.slides[t].html),this.settings.slides[t].$elmt=i),i.addClass("ditty-slider__slide"),i.addClass("ditty-slider__slide--current"),i.addClass("ditty-slider__slide--"+t),$(this.$slides.children(".ditty-slider__slide--"+t).not(i)).remove(),this._styleSlide(i),i.stop(!0).css({position:"absolute",display:"block",opacity:0}),this.$slides.append(i),this.animateTransition=!0,this.animateHeight=!0,this._setStaticHeight();var r=[t,this.settings.slides[t],l,n];this.trigger("before_slide_update",r),null!==this.$currentSlide&&this._animateOut(this.$currentSlide,i,s),this.$currentSlide=i,this.settings.slide=t,this.slideObj=this.settings.slides[t],this.visibleSlides=[this.settings.slides[t]],i.hasClass("ditty-slide-animating")||this._slideResetPosition(i,s),this._animateIn(i,r),this._animateHeight(),this._activateBullet(),this.slidesDisplayed=this.slidesDisplayed+1},_animateIn:function(t,s){var i=this,e=0===parseInt(this.slidesDisplayed)?this.settings.initTransitionSpeed:this.settings.transitionSpeed,l=0===parseInt(this.slidesDisplayed)?this.settings.initTransitionEase:this.settings.transitionEase;this.transitioning=!0,this._timerStop(),t.show(),t.addClass("ditty-slide-animating"),t.stop(!0).animate({left:0,top:0,opacity:1},1e3*parseFloat(e),l,(function(){t.removeClass("ditty-slide-animating"),t.css("position","relative"),i.transitioning=!1,i.animateTransition=!1,i._removeStaticHeight(),i._timerStart(),i.trigger("after_slide_update",s)}))},_animateOut:function(t,s,i){this.$lastSlide=t,t.removeClass("ditty-slider__slide--current"),t.css("position","absolute");var e=0,l=0,n=1,r=this.settings.transition;switch("reverse"===i&&(r=this._reverseTransition(r)),r){case"fade":n=0;break;case"slideRight":e=this.$slides.outerWidth();break;case"slideLeft":e="-"+t.outerWidth();break;case"slideDown":l=s.outerHeight();break;case"slideUp":l="-"+t.outerHeight()}t.css({zIndex:1}),t.addClass("ditty-slide-animating"),t.stop(!0).animate({left:e+"px",top:l+"px",opacity:n},1e3*parseFloat(this.settings.transitionSpeed),this.settings.transitionEase,(function(){t.removeClass("ditty-slide-animating"),t.hide()}))},_slideResetPosition:function(t,s){var i=0,e=0,l=1,n=0===parseInt(this.slidesDisplayed)?this.settings.initTransition:this.settings.transition;switch("reverse"===s&&(n=this._reverseTransition(n)),n){case"fade":l=0;break;case"slideLeft":i=this.$slides.outerWidth();break;case"slideRight":i="-"+t.outerWidth();break;case"slideUp":null!==this.$lastSlide?e=this.$lastSlide.outerHeight():(e=this.$slides.outerHeight(),t.outerHeight()>e&&(e=t.outerHeight()));break;case"slideDown":e="-"+t.outerHeight()}t.stop(!0).css({display:"block",opacity:l,left:i+"px",top:e+"px",zIndex:9})},_setStaticHeight:function(){var t=this.$slides.outerHeight();this.$slides.stop(!0).css("height",t+"px")},_removeStaticHeight:function(){this.animateTransition||this.animateHeight||this.$slides.stop(!0).css("height","auto")},_animateHeight:function(){var t=this,s=this.$currentSlide.outerHeight(),i=0===parseInt(this.slidesDisplayed)?this.settings.initHeightSpeed:this.settings.heightSpeed,e=0===parseInt(this.slidesDisplayed)?this.settings.initHeightEase:this.settings.heightEase;this.currentHeight=s,this.$slides.stop(!0).animate({height:s+"px"},1e3*parseFloat(i),e,(function(){t.animateHeight=!1,t._removeStaticHeight(),t.trigger("height_updated")}))},_reverseTransition:function(t){var s=t;switch(t){case"slideLeft":s="slideRight";break;case"slideRight":s="slideLeft";break;case"slideUp":s="slideDown";break;case"slideDown":s="slideUp"}return s},_getNextSlide:function(){var t=this.settings.slide+1;return t>=this.total&&(t=0),t},_showNextSlide:function(){this._showSlide(this._getNextSlide())},_getPrevSlide:function(){var t=this.settings.slide-1;return t<0&&(t=this.total-1),t},_showPrevSlide:function(){this._showSlide(this._getPrevSlide(),"reverse")},_clickBullet:function(t){t.preventDefault();var s,i=t.data.self,e=$(t.target).data("index");e<i.settings.slide&&(s="reverse"),i._showSlide(e,s)},_activateBullet:function(){if("none"===this.settings.bullets||2>parseInt(this.total))return!1;var t=this._getPrevSlide(),s=this._getNextSlide();this.$bullets.find(".ditty-slider__bullet").removeClass("ditty-slider__bullet--active ditty-slider__bullet--next ditty-slider__bullet--prev"),this.$bullets.find('.ditty-slider__bullet[data-index="'+this.settings.slide+'"]').addClass("ditty-slider__bullet--active"),this.$bullets.find('.ditty-slider__bullet[data-index="'+t+'"]').addClass("ditty-slider__bullet--prev"),this.$bullets.find('.ditty-slider__bullet[data-index="'+s+'"]').addClass("ditty-slider__bullet--next"),this._styleBullets()},_setupBullets:function(){if(null===this.$bullets){var t=$('<div class="ditty-slider__bullets"></div>');this.$bullets=t,this.$elmt.append(t)}if("none"===this.settings.bullets||2>parseInt(this.total))this.$bullets.hide();else{this.$bullets.empty();for(var s=0;s<this.total;s++){var i=$('<a href="#" class="ditty-slider__bullet" data-index="'+s+'">'+this.settings.bullet+"</a>");i.on("click",{self:this},this._clickBullet),this.$bullets.append(i)}this.$bullets.show(),this._activateBullet()}},_styleBullets:function(){switch(this.$bullets.removeAttr("style"),this.$bullets.find("a").css({backgroundColor:this.settings.bulletsColor,marginLeft:this.settings.bulletsSpacing+"px",marginRight:this.settings.bulletsSpacing+"px"}),this.$bullets.find("a.ditty-slider__bullet--active").css({backgroundColor:this.settings.bulletsColorActive}),this.$bullets.css(this.settings.bulletsPadding),this.settings.bulletsPosition){case"topLeft":this.$bullets.css({order:0,justifyContent:"flex-start"});break;case"topCenter":this.$bullets.css({order:0,justifyContent:"center"});break;case"topRight":this.$bullets.css({order:0,justifyContent:"flex-end"});break;case"bottomLeft":this.$bullets.css({order:2,justifyContent:"flex-start"});break;case"bottomCenter":this.$bullets.css({order:2,justifyContent:"center"});break;case"bottomRight":this.$bullets.css({order:2,justifyContent:"flex-end"})}},_clickPrev:function(t){t.preventDefault(),t.data.self._showPrevSlide()},_clickNext:function(t){t.preventDefault(),t.data.self._showNextSlide()},_setupArrows:function(){if(null===this.$arrows){var t=$('<div class="ditty-slider__arrows"></div>'),s=$('<a href="#" class="ditty-slider__prev">'+this.settings.navPrev+"</a>"),i=$('<a href="#" class="ditty-slider__next">'+this.settings.navNext+"</a>");s.on("click",{self:this},this._clickPrev),i.on("click",{self:this},this._clickNext),t.append(s,i),this.$arrows=t,this.$contents.append(t)}this.$arrows.removeAttr("style"),"none"===this.settings.arrows||2>this.total?this.$arrows.hide():this.$arrows.css("display","flex"),this.$arrows.css(this.settings.arrowsPadding),this.$arrows.css({alignItems:this.settings.arrowsPosition}),this.$arrows.find("i").css({color:this.settings.arrowsIconColor}),this.$arrows.find("a").css({backgroundColor:this.settings.arrowsBgColor}),1===parseInt(this.settings.arrowsStatic)?this.$arrows.addClass("ditty-slider__arrows--static"):this.$arrows.removeClass("ditty-slider__arrows--static")},_styleDisplay:function(){this.$elmt.css({maxWidth:this.settings.maxWidth,backgroundColor:this.settings.bgColor,borderColor:this.settings.borderColor,borderStyle:this.settings.borderStyle}),this.$elmt.css(this.settings.padding),this.$elmt.css(this.settings.margin),this.$elmt.css(this.settings.borderRadius),this.$elmt.css(this.settings.borderWidth),this.$contents.css({backgroundColor:this.settings.contentsBgColor,borderColor:this.settings.contentsBorderColor,borderStyle:this.settings.contentsBorderStyle}),this.$contents.css(this.settings.contentsPadding),this.$contents.css(this.settings.contentsBorderRadius),this.$contents.css(this.settings.contentsBorderWidth)},_styleSlide:function(t){t.css({backgroundColor:this.settings.slideBgColor,borderColor:this.settings.slideBorderColor,borderStyle:this.settings.slideBorderStyle}),t.css(this.settings.slidePadding),t.css(this.settings.slideBorderRadius),t.css(this.settings.slideBorderWidth)},updateSlides:function(t){for(var s=this.settings.slides.length,i=t.length,e=this.settings.slide,l=this.settings.slide,n=0;n<t.length;n++)this._preloadSlide(t[n]);this.settings.slides=t,s!==i&&(this.total=t.length,this._setupBullets(),this._setupArrows()),e>=this.total&&(l=this.total-1),e!==l&&this._showSlide(l)},_getOption:function(t){switch(t){case"elmnt":return this;case"height":return this.$slides.outerHeight();case"currentSlide":return this.$currentSlide;default:return this.settings[t]}},_setOption:function(t,s){if(void 0===s)return!1;switch("slides"!==t&&(this.settings[t]=s),t){case"slides":this.updateSlides(s);break;case"slide":this.slide=s;break;case"autoplay":1===parseInt(s)?this.timer||this._timerStart():this._timerStop();break;case"bgColor":case"padding":case"borderColor":case"borderStyle":case"borderWidth":case"borderRadius":case"contentsBgColor":case"contentsPadding":case"contentsBorderColor":case"contentsBorderStyle":case"contentsBorderWidth":case"contentsBorderRadius":this.animateHeight=!0,this._setStaticHeight(),this._styleDisplay(),this._animateHeight();break;case"slideBgColor":case"slidePadding":case"slideBorderColor":case"slideBorderStyle":case"slideBorderWidth":case"slideBorderRadius":this.animateHeight=!0,this._setStaticHeight(),this._styleSlide(this.$currentSlide),this._animateHeight();break;case"arrows":case"arrowsIconColor":case"arrowsBgColor":case"arrowsPadding":case"arrowsPosition":case"arrowsStatic":this._setupArrows();break;case"bullets":this._setupBullets();break;case"bulletsColor":case"bulletsColorActive":case"bulletsPosition":case"bulletsSpacing":case"bulletsPadding":this._styleBullets();break;default:this.settings[t]=s}this.trigger("update")},shuffle:function(){for(var t,s,i=this.total-1;i>0;i--)s=Math.floor(Math.random()*(i+1)),t=this.settings.slides[i],this.settings.slides[i]=this.settings.slides[s],this.settings.slides[s]=t},start:function(){this._timerStart()},stop:function(){this._timerStop()},pause:function(){this.paused=!0},resume:function(){this.paused=!1,this._timerStart()},current:function(){return this.$currentSlide},showSlide:function(t){this._showSlide(t)},showSlideById:function(t,s){var i=this;$.each(this.settings.slides,(function(e,l){if(l.id===t)return"force"===s?(i.settings.slide=e,i._showSlide()):i._showSlide(e),!1}))},addSlide:function(t,s,i){var e=!0;if((s>=this.total||s<0)&&(e=!1),"replace"===i&&e){var l=this.settings.slides[s];this.trigger("slide_removed",[l]),this.settings.slides.splice(s,1,t)}else null!==s&&""!==s&&e?this.settings.slides.splice(s,0,t):this.settings.slides.splice(parseInt(this.settings.slide)+1,0,t);this.total=this.settings.slides.length,this._preloadSlide(t),this.trigger("update")},addSlideById:function(t,s){var i={id:t,html:s},e=!1;if($.each(this.settings.slides,(function(s,i){String(i.id)!==String(t)||(e=s)})),e){var l=this.settings.slides[e];this.trigger("slide_removed",[l]),this.settings.slides[e].$elmt&&this.settings.slides[e].$elmt.remove(),this.settings.slides.splice(e,1,i)}else this.settings.slides.push(i);this.total=this.settings.slides.length,this._preloadSlide(i),this.trigger("update")},deleteSlideById:function(t){var s=[];$.each(this.settings.slides,(function(i,e){String(e.id)!==String(t)&&s.push(e)})),this.settings.slides=s,this.total=this.settings.slides.length,this.trigger("update")},deleteSlide:function(t){if(t>=this.total||t<0)return!1;var s=this.settings.slides[t];this.trigger("slide_removed",[s]),this.settings.slides[t].$elmt&&this.settings.slides[t].$elmt.remove(),this.settings.slides.splice(t,1),this.total=this.settings.slides.length,this.trigger("update")},setStaticHeight:function(){this.animateHeight=!0,this._setStaticHeight()},animateHeight:function(){this._animateHeight()},trigger:function(t,s){var i=[];if("height_updated"===t)i=[this.currentHeight];else i=[this.settings,this.$elmt];s&&(i=s),this.$elmt.trigger("ditty_slider_"+t,i),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,i)},options:function(t,s){var i=this;if("object"==typeof t)$.each(t,(function(t,s){i._setOption(t,s)}));else{if("string"!=typeof t)return i.settings;if(void 0===s)return i._getOption(t);i._setOption(t,s)}},destroy:function(){clearInterval(this.timer),this.$elmt.removeClass("ditty-slider"),this.$elmt.removeAttr("style"),this.$elmt.empty(),this.trigger("destroy"),this.elmt._ditty_slider=null}},$.fn.ditty_slider=function(t){var i,e=arguments,l=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_slider||(this._ditty_slider=new s(this,t))}));if("string"==typeof t){if(this.each((function(){var s=this._ditty_slider;if(!s)throw new Error("No Ditty_Slider applied to this element.");"function"==typeof s[t]&&"_"!==t[0]?i=s[t].apply(s,[].slice.call(e,1)):l=!0})),l)throw new Error('No method "'+t+'" in Ditty_Slider.');return void 0!==i?i:this}},$.ditty_slider={},$.ditty_slider.defaults=t}(jQuery);
includes/js/ditty-admin.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* global dittyAdminVars:true */
3
+ /* global console:true */
4
+
5
+ // @codekit-append 'admin/class-ditty-settings.js';
6
+ // @codekit-append 'admin/class-ditty-extension.js';
7
+ // @codekit-append 'admin/ditty-extensions.js';
8
+ // @codekit-append 'admin/ditty-displays.js';
9
+
10
+ jQuery( document ).ready( function( $ ) {
11
+
12
+ // Setup strict mode
13
+ (function() {
14
+
15
+ "use strict";
16
+
17
+ $( '#poststuff' ).trigger( 'ditty_init_fields' );
18
+ $( '#ditty-settings' ).ditty_settings();
19
+
20
+ }() );
21
+
22
+ } );
includes/js/ditty-admin.min.js ADDED
@@ -0,0 +1,888 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery:true */
2
+ /* global dittyAdminVars:true */
3
+ /* global console:true */
4
+
5
+ // @codekit-append 'admin/class-ditty-settings.js';
6
+ // @codekit-append 'admin/class-ditty-extension.js';
7
+ // @codekit-append 'admin/ditty-extensions.js';
8
+ // @codekit-append 'admin/ditty-displays.js';
9
+
10
+ jQuery( document ).ready( function( $ ) {
11
+
12
+ // Setup strict mode
13
+ (function() {
14
+
15
+ "use strict";
16
+
17
+ $( '#poststuff' ).trigger( 'ditty_init_fields' );
18
+ $( '#ditty-settings' ).ditty_settings();
19
+
20
+ }() );
21
+
22
+ } );
23
+
24
+ /**
25
+ * Ditty Settings
26
+ *
27
+ * @since 3.0
28
+ * @return null
29
+ */
30
+
31
+ (function ($) {
32
+ 'use strict';
33
+
34
+ var defaults = {
35
+ };
36
+
37
+ var Ditty_Settings = function ( elmt, options ) {
38
+
39
+ this.elmt = elmt;
40
+ this.settings = $.extend( {}, defaults, $.ditty_settings.defaults, options );
41
+ this.$elmt = $( elmt );
42
+ this.$form = this.$elmt.find( '.ditty-settings__form' );
43
+ this.$panels = this.$elmt.find( '.ditty-settings__panels' );
44
+ this.saveBtns = this.$elmt.find( '.ditty-settings__save' );
45
+ this.tabs = this.$elmt.find( '.ditty-settings__tab' );
46
+ this.$notice_update = this.$elmt.find( '.ditty-notification--updated' );
47
+ this.$notice_error = this.$elmt.find( '.ditty-notification--error' );
48
+ this.$notice_warning = this.$elmt.find( '.ditty-notification--warning' );
49
+ this.initData = null;
50
+ this._init();
51
+ };
52
+
53
+
54
+ Ditty_Settings.prototype = {
55
+
56
+ /**
57
+ * Initialize the data list
58
+ *
59
+ * @since 3.0
60
+ * @return null
61
+ */
62
+ _init: function () {
63
+
64
+ // Initialize the slider
65
+ this._initSlider();
66
+
67
+ // Add listeners
68
+ $( 'body' ).on( 'ditty_field_clone_update', { self: this }, this._enableSettingsUpdates );
69
+ this.saveBtns.on( 'click', { self: this }, this._submitForm );
70
+ this.tabs.on( 'click', { self: this }, this._tabClick );
71
+ this.$panels.on( 'ditty_slider_init', { self: this }, this._sliderInit );
72
+ this.$panels.on( 'ditty_slider_before_slide_update', { self: this }, this._beforeSlideUpdate );
73
+ this.$form.on( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
74
+ this.$form.on( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
75
+ this.$form.on( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
76
+ this.$form.on( 'click', '.ditty-default-layout-install', { self: this }, this._installLayout );
77
+ this.$form.on( 'click', '.ditty-default-display-install', { self: this }, this._installDisplay );
78
+ },
79
+
80
+ /**
81
+ * Initialize the extensions
82
+ *
83
+ * @since 3.0
84
+ * @return null
85
+ */
86
+ _initSlider: function () {
87
+ var initPanel = this.$panels.data( 'init_panel' );
88
+ this.$panels.ditty_slider( {
89
+ transition : 'fade',
90
+ transitionSpeed : 0.75,
91
+ heightSpeed : 0.75,
92
+ touchSwipe : false,
93
+ slidesEl : '.ditty-settings__panel',
94
+ slideId : ( '' !== initPanel ) ? initPanel : false
95
+ } );
96
+ },
97
+
98
+ /**
99
+ * Slider init
100
+ *
101
+ * @since 3.0
102
+ * @return null
103
+ */
104
+ _sliderInit: function( e ) {
105
+ var self = e.data.self;
106
+ self.initData = self.$form.serialize();
107
+ },
108
+
109
+ /**
110
+ * Before slide update
111
+ *
112
+ * @since 3.0
113
+ * @return null
114
+ */
115
+ _beforeSlideUpdate: function( e, index, slide ) {
116
+ var self = e.data.self;
117
+ self._initFields( slide.$elmt );
118
+ self.$elmt.find( '.ditty-settings__tab' ).removeClass( 'active' );
119
+ self.$elmt.find( '.ditty-settings__tab[data-panel="' + slide.id + '"]' ).addClass( 'active' );
120
+ },
121
+
122
+ /**
123
+ * Preview button add updates class
124
+ *
125
+ * @since 3.0
126
+ * @return null
127
+ */
128
+ _enableSettingsUpdates: function( e ) {
129
+ var self = ( e ) ? e.data.self : this;
130
+ self.saveBtns.addClass( 'has-updates' );
131
+ //self.notice_warning.slideDown();
132
+ },
133
+
134
+ /**
135
+ * Preview button remove updates class
136
+ *
137
+ * @since 3.0
138
+ * @return null
139
+ */
140
+ _disableSettingsUpdates: function() {
141
+ this.saveBtns.removeClass( 'has-updates' );
142
+ },
143
+
144
+ /**
145
+ * Check for updates
146
+ *
147
+ * @since 3.0
148
+ * @return null
149
+ */
150
+ _checkUpdates: function( e ) {
151
+ var self = e ? e.data.self : this;
152
+ var currentData = self.$form.serialize();
153
+ if ( currentData !== self.initData ) {
154
+ self._enableSettingsUpdates();
155
+ } else {
156
+ self._disableSettingsUpdates();
157
+ }
158
+ },
159
+
160
+ /**
161
+ * Initialize dynamic fields
162
+ *
163
+ * @since 3.0
164
+ * @return null
165
+ */
166
+ _initFields: function ( $fields ) {
167
+ $fields.find( '.ditty-data-list' ).ditty_ui_data_list();
168
+ $fields.trigger( 'ditty_init_fields' );
169
+ $.protip( {
170
+ defaults: {
171
+ position: 'top',
172
+ size: 'small',
173
+ scheme: 'black',
174
+ classes: 'ditty-protip'
175
+ }
176
+ } );
177
+ },
178
+
179
+ /**
180
+ * Show or hide post types
181
+ *
182
+ * @since 3.0
183
+ * @return null
184
+ */
185
+ _togglePostTypes: function () {
186
+ if ( $( 'input[name="ditty_layout_ui"]' ).length ) {
187
+ var layoutUiVal = $( 'input[name="ditty_layout_ui"]:checked' ).val(),
188
+ $layoutMenu = $( '#adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_layout"]' );
189
+ if ( 'disabled' === layoutUiVal ) {
190
+ $layoutMenu.hide();
191
+ } else {
192
+ $layoutMenu.css( 'display', 'block' );
193
+ }
194
+ }
195
+ if ( $( 'input[name="ditty_display_ui"]' ).length ) {
196
+ var displayUiVal = $( 'input[name="ditty_display_ui"]:checked' ).val(),
197
+ $displayMenu = $( '#adminmenu .wp-submenu > li > a[href="edit.php?post_type=ditty_display"]' );
198
+ if ( 'disabled' === displayUiVal ) {
199
+ $displayMenu.hide();
200
+ } else {
201
+ $displayMenu.css( 'display', 'block' );
202
+ }
203
+ }
204
+ },
205
+
206
+ /**
207
+ * Listen for a tab click
208
+ *
209
+ * @since 3.0
210
+ * @return null
211
+ */
212
+ _tabClick: function( e ) {
213
+ e.preventDefault();
214
+ var self = e.data.self,
215
+ $tab = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
216
+ slideId = $tab.data( 'panel' ),
217
+ $currentTab = self.$elmt.find( '.ditty-settings__tab.active' );
218
+
219
+ if ( $currentTab === $tab ) {
220
+ return false;
221
+ }
222
+
223
+ self.$elmt.find( '.ditty-extension__tab' ).removeClass( 'active' );
224
+ $tab.addClass( 'active' );
225
+
226
+ self.$panels.ditty_slider( 'showSlideById', slideId );
227
+ },
228
+
229
+ /**
230
+ * Update inputs after save and sanitize
231
+ *
232
+ * @since 3.0
233
+ * @return null
234
+ */
235
+ _upateInputs: function( updates ) {
236
+ $.each( updates, function( inputName, updatedValue ) {
237
+ if ( $( 'input[name="' + inputName + '"]' ).length ) {
238
+ $( 'input[name="' + inputName + '"]' ).val( updatedValue );
239
+ }
240
+ } );
241
+ },
242
+
243
+ /**
244
+ * Submit updates
245
+ *
246
+ * @since 3.0
247
+ * @return null
248
+ */
249
+ _submitForm: function( e ) {
250
+ e.preventDefault();
251
+ var self = e.data.self;
252
+
253
+ if ( self.$elmt.hasClass( 'updating' ) ) {
254
+ return false;
255
+ }
256
+
257
+ self.$elmt.trigger( 'ditty_pre_save_fields' );
258
+ self.$elmt.addClass( 'updating' );
259
+ self.saveBtns.text( dittyAdminVars.adminStrings.settingsSaving );
260
+
261
+ self.$form.ajaxSubmit( {
262
+ url : dittyAdminVars.ajaxurl,
263
+ type : 'post',
264
+ dataType : 'json',
265
+ data : {
266
+ action : 'ditty_settings_save',
267
+ security : dittyAdminVars.security
268
+ },
269
+ success: function( data ) {
270
+ if ( data.input_updates ) {
271
+ self._upateInputs( data.input_updates );
272
+ }
273
+ self.initData = self.$form.serialize();
274
+ self.saveBtns.text( dittyAdminVars.adminStrings.settings_updated );
275
+ setTimeout( function() {
276
+ self.saveBtns.text( dittyAdminVars.adminStrings.settings_save );
277
+ }, 2000 );
278
+ self.$elmt.removeClass( 'updating' );
279
+ self._disableSettingsUpdates();
280
+
281
+ //self.$notice_update.slideDown();
282
+
283
+ // Check the post types display
284
+ self._togglePostTypes();
285
+ }
286
+ } );
287
+ },
288
+
289
+ /**
290
+ * Install a layout
291
+ *
292
+ * @since 3.0
293
+ * @return null
294
+ */
295
+ _installLayout: function( e ) {
296
+ e.preventDefault();
297
+ var self = e.data.self,
298
+ $button = $( e.target ).is( 'button' ) ? $( e.target ) : $( e.target ).parents( 'button' ),
299
+ $icon = $button.find( 'i' ),
300
+ iconClass = $icon.attr( 'class' );
301
+
302
+ if ( $button.hasClass( 'updating' ) ) {
303
+ return false;
304
+ }
305
+ $button.addClass( 'updating' );
306
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
307
+
308
+ var data = {
309
+ action : 'ditty_install_layout',
310
+ layout_template : $button.data( 'layout_template' ),
311
+ layout_version : $button.data( 'layout_version' ),
312
+ security : dittyAdminVars.security
313
+ };
314
+ $.post( dittyAdminVars.ajaxurl, data, function( response ) {
315
+ $icon.attr( 'class', iconClass );
316
+ self.$elmt.removeClass( 'updating' );
317
+ if ( response ) {
318
+ $button.replaceWith( response.button );
319
+ }
320
+ } );
321
+ },
322
+
323
+ /**
324
+ * Install a display
325
+ *
326
+ * @since 3.0
327
+ * @return null
328
+ */
329
+ _installDisplay: function( e ) {
330
+ e.preventDefault();
331
+ var self = e.data.self,
332
+ $button = $( e.target ).is( 'button' ) ? $( e.target ) : $( e.target ).parents( 'button' ),
333
+ $icon = $button.find( 'i' ),
334
+ iconClass = $icon.attr( 'class' );
335
+
336
+ if ( $button.hasClass( 'updating' ) ) {
337
+ return false;
338
+ }
339
+ $button.addClass( 'updating' );
340
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
341
+
342
+ var data = {
343
+ action : 'ditty_install_display',
344
+ display_type : $button.data( 'display_type' ),
345
+ display_template : $button.data( 'display_template' ),
346
+ display_version : $button.data( 'display_version' ),
347
+ security : dittyAdminVars.security
348
+ };
349
+ $.post( dittyAdminVars.ajaxurl, data, function( response ) {
350
+ $icon.attr( 'class', iconClass );
351
+ self.$elmt.removeClass( 'updating' );
352
+ if ( response ) {
353
+ $button.replaceWith( response.button );
354
+ }
355
+ } );
356
+ },
357
+
358
+ /**
359
+ * Return a specific setting
360
+ *
361
+ * @since 3.0
362
+ * @return null
363
+ */
364
+ _options: function ( key ) {
365
+ return this.settings[key];
366
+ },
367
+
368
+ /**
369
+ * Setup triggers
370
+ *
371
+ * @since 3.0
372
+ * @return null
373
+ */
374
+ trigger: function ( fn, customParams ) {
375
+ var params = [this.settings];
376
+ if ( customParams ) {
377
+ params = customParams;
378
+ }
379
+
380
+ this.$elmt.trigger( 'ditty_settings_' + fn, params );
381
+
382
+ if ( typeof this.settings[fn] === 'function' ) {
383
+ this.settings[fn].apply( this.$elmt, params );
384
+ }
385
+ },
386
+
387
+ /**
388
+ * Allow settings to be modified
389
+ *
390
+ * @since 3.0
391
+ * @return null
392
+ */
393
+ options: function ( key, value ) {
394
+
395
+ if ( typeof key === 'object' ) {
396
+ this.settings = $.extend( {}, defaults, $.ditty_settings.defaults, key );
397
+ } else if ( typeof key === 'string' ) {
398
+ if ( value === undefined ) {
399
+ return this.settings[key];
400
+ }
401
+ this.settings[key] = value;
402
+ } else {
403
+ return this.settings;
404
+ }
405
+
406
+ this.trigger( 'options_update' );
407
+ },
408
+
409
+ /**
410
+ * Destroy the editor
411
+ *
412
+ * @since 3.0
413
+ * @return null
414
+ */
415
+ destroy: function () {
416
+
417
+ // Remove listeners
418
+ $( 'body' ).off( 'ditty_field_clone_update', { self: this }, this._enableSettingsUpdates );
419
+ this.saveBtns.off( 'click', { self: this }, this._submitForm );
420
+ this.tabs.off( 'click', { self: this }, this._tabClick );
421
+ this.$panels.off( 'ditty_slider_init', { self: this }, this._sliderInit );
422
+ this.$panels.off( 'ditty_slider_before_slide_update', { self: this }, this._beforeSlideUpdate );
423
+ this.$form.off( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
424
+ this.$form.off( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
425
+ this.$form.off( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
426
+ this.$form.off( 'click', '.ditty-default-layout-install', { self: this }, this._installLayout );
427
+ this.$form.off( 'click', '.ditty-default-display-install', { self: this }, this._installDisplay );
428
+
429
+ this.$panels.ditty_slider( 'destroy' );
430
+ this.elmt._ditty_settings = null;
431
+ }
432
+ };
433
+
434
+ /**
435
+ * Create the data list
436
+ *
437
+ * @since 3.0
438
+ * @return null
439
+ */
440
+ $.fn.ditty_settings = function( options ) {
441
+ var args = arguments,
442
+ error = false,
443
+ returns;
444
+
445
+ if ( options === undefined || typeof options === 'object' ) {
446
+ return this.each( function () {
447
+ if ( ! this._ditty_settings ) {
448
+ this._ditty_settings = new Ditty_Settings( this, options );
449
+ }
450
+ });
451
+ } else if ( typeof options === 'string' ) {
452
+ this.each( function () {
453
+ var instance = this._ditty_settings;
454
+
455
+ if ( ! instance ) {
456
+ throw new Error( 'No Ditty_Settings applied to this element.' );
457
+ }
458
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
459
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
460
+ } else {
461
+ error = true;
462
+ }
463
+ } );
464
+
465
+ if ( error ) {
466
+ throw new Error( 'No method "' + options + '" in Ditty_Settings.' );
467
+ }
468
+
469
+ return returns !== undefined ? returns : this;
470
+ }
471
+ };
472
+
473
+ $.ditty_settings = {};
474
+ $.ditty_settings.defaults = defaults;
475
+
476
+ } )( jQuery );
477
+
478
+
479
+ /**
480
+ * Ditty Extension class
481
+ *
482
+ * @since 3.0
483
+ * @return null
484
+ */
485
+
486
+ (function ($) {
487
+ 'use strict';
488
+
489
+ var defaults = {
490
+ };
491
+
492
+ var Ditty_Extension = function ( elmt, options ) {
493
+
494
+ this.elmt = elmt;
495
+ this.settings = $.extend( {}, defaults, $.ditty_extension.defaults, options );
496
+ this.$elmt = $( elmt );
497
+ this.$panels = $( elmt ).find( '.ditty-extension__panels' );
498
+ this.initPanel = this.$panels.data( 'init_panel' );
499
+
500
+ this._init();
501
+ };
502
+
503
+ Ditty_Extension.prototype = {
504
+
505
+ _init: function () {
506
+
507
+ // Add listeners
508
+ this.$elmt.on( 'click', '.ditty-extension__tab', { self: this }, this._tabClick );
509
+ this.$elmt.on( 'click', 'button[name="submit"]', { self: this }, this._updatePanel );
510
+ this.$elmt.on( 'click', '.ditty-extension__license__submit', { self: this, action: 'ditty_extension_license_activate' }, this._licenseUpdate );
511
+ this.$elmt.on( 'click', '.ditty-extension__license__refresh', { self: this, action: 'ditty_extension_license_refresh' }, this._licenseUpdate );
512
+ this.$elmt.on( 'click', '.ditty-extension__license__deactivate', { self: this, action: 'ditty_extension_license_deactivate' }, this._licenseUpdate );
513
+ this.$panels.on( 'ditty_slider_before_slide_update', { self: this }, this._beforePanelUpdate );
514
+ this._initSlider();
515
+ },
516
+
517
+ /**
518
+ * Initialize the slider
519
+ *
520
+ * @since 3.0
521
+ * @return null
522
+ */
523
+ _initSlider: function () {
524
+ var args = {
525
+ transition : 'fade',
526
+ transitionSpeed : 0.75,
527
+ heightSpeed : 0.75,
528
+ touchSwipe : false,
529
+ slidesEl : '.ditty-extension__panel',
530
+ slideId : ( '' !== this.initPanel ) ? this.initPanel : false
531
+ };
532
+ this.$panels.ditty_slider( args );
533
+ },
534
+
535
+ /**
536
+ * Initialize the slider
537
+ *
538
+ * @since 3.0
539
+ * @return null
540
+ */
541
+ _beforePanelUpdate: function ( e, index, slide ) {
542
+ var self = e.data.self;
543
+ self.$elmt.find( '.ditty-extension__tab' ).removeClass( 'active' );
544
+ self.$elmt.find( '.ditty-extension__tab[data-slide_id="' + slide.id + '"]' ).addClass( 'active' );
545
+ },
546
+
547
+ /**
548
+ * Tab click
549
+ *
550
+ * @since 3.0
551
+ * @return null
552
+ */
553
+ _tabClick: function ( e ) {
554
+ e.preventDefault();
555
+ var self = e.data.self;
556
+ var $tab = $( this ),
557
+ slideId = $tab.data( 'slide_id' ),
558
+ transition = 'slideLeft',
559
+ $currentTab = self.$elmt.find( '.ditty-extension__tab.active' );
560
+
561
+ if ( $currentTab === $tab ) {
562
+ return false;
563
+ }
564
+
565
+ if ( $tab.index() < $currentTab.index() ) {
566
+ transition = 'slideRight';
567
+ }
568
+
569
+ //self.$elmt.find( '.ditty-extension__tab' ).removeClass( 'active' );
570
+ //$tab.addClass( 'active' );
571
+
572
+ self.$panels.ditty_slider( 'options', 'transition', transition );
573
+ self.$panels.ditty_slider( 'showSlideById', slideId );
574
+ },
575
+
576
+ /**
577
+ * Panel update listener
578
+ *
579
+ * @since 3.0
580
+ * @return null
581
+ */
582
+ _updatePanel: function ( e ) {
583
+ e.preventDefault();
584
+ var self = e.data.self;
585
+
586
+ var $button = $( this ),
587
+ $panel = $button.parents( '.ditty-extension__panel' ),
588
+ $form = $button.parents( '.ditty-extension__form' ),
589
+ $icon = $button.find( 'i' ),
590
+ iconClass = $icon.attr( 'class' ),
591
+ extension = self.$elmt.data( 'extension' ),
592
+ panel = $panel.data( 'slide_id' );
593
+
594
+ if ( self.$elmt.hasClass( 'updating' ) ) {
595
+ return false;
596
+ }
597
+
598
+ self.$elmt.addClass( 'updating' );
599
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
600
+
601
+ $form.ajaxSubmit( {
602
+ url : dittyAdminVars.ajaxurl,
603
+ type : 'post',
604
+ dataType : 'json',
605
+ data : {
606
+ action : 'ditty_extension_panel_update',
607
+ extension : extension,
608
+ panel : panel,
609
+ security : dittyAdminVars.security
610
+ },
611
+ success: function( response ) {
612
+ $icon.attr( 'class', iconClass );
613
+ self.$elmt.removeClass( 'updating' );
614
+ $( '#ditty-extensions' ).trigger( 'ditty_extension_panel_updated', [ response, self.$elmt, $panel ] );
615
+ }
616
+ } );
617
+ },
618
+
619
+ /**
620
+ * Update a license
621
+ *
622
+ * @since 3.0
623
+ * @return null
624
+ */
625
+ _licenseUpdate: function ( e ) {
626
+ e.preventDefault();
627
+ var self = e.data.self,
628
+ action = e.data.action;
629
+
630
+ var $button = $( this ),
631
+ $message = self.$elmt.find( '.ditty-extension__license__message' ),
632
+ $input = $button.siblings( '.ditty-extension__license__input' ),
633
+ license = $input.val(),
634
+ extension = $button.data( 'extension' ),
635
+ extensionId = $button.data( 'extension_id' ),
636
+ extensionName = $button.data( 'extension_name' ),
637
+ $icon = $button.children( 'i' );
638
+
639
+ if ( self.$elmt.hasClass( 'updating' ) ) {
640
+ return false;
641
+ }
642
+
643
+ self.$elmt.addClass( 'updating' );
644
+ $icon.attr( 'class', dittyAdminVars.updateIcon );
645
+
646
+ // Load the new display data
647
+ var data = {
648
+ action : action,
649
+ license : license,
650
+ extension : extension,
651
+ extension_id : extensionId,
652
+ extension_name : extensionName,
653
+ security : dittyAdminVars.security
654
+ };
655
+ $.post( dittyAdminVars.ajaxurl, data, function( response ) {
656
+ if ( response ) {
657
+ self.$elmt.attr( 'data-license_status', response.status );
658
+ $message.text( response.message );
659
+ }
660
+ if ( response.license_key ) {
661
+ if ( 'DELETE' === response.license_key ) {
662
+ $input.val( '' );
663
+ } else {
664
+ $input.val( response.license_key );
665
+ }
666
+ }
667
+ $icon.attr( 'class', $icon.data( 'class' ) );
668
+ self.$elmt.removeClass( 'updating' );
669
+ }, 'json' );
670
+ },
671
+
672
+ /**
673
+ * Return data for the object
674
+ *
675
+ * @since 3.0
676
+ * @return null
677
+ */
678
+ _getOption: function( key ) {
679
+ switch( key ) {
680
+ default:
681
+ return this.settings[key];
682
+ }
683
+ },
684
+
685
+ /**
686
+ * Set data for the object
687
+ *
688
+ * @since 3.0
689
+ * @return null
690
+ */
691
+ _setOption: function( key, value ) {
692
+ if ( undefined === value ) {
693
+ return false;
694
+ }
695
+
696
+ this.settings[key] = value;
697
+ },
698
+
699
+ /**
700
+ * Get or set ditty options
701
+ *
702
+ * @since 3.0
703
+ * @return null
704
+ */
705
+ options: function ( key, value ) {
706
+ var self = this;
707
+ if ( typeof key === 'object' ) {
708
+ $.each( key, function( k, v ) {
709
+ self._setOption( k, v );
710
+ });
711
+ } else if ( typeof key === 'string' ) {
712
+ if ( value === undefined ) {
713
+ return self._getOption( key );
714
+ }
715
+ self._setOption( key, value );
716
+ } else {
717
+ return self.settings;
718
+ }
719
+ },
720
+
721
+ /**
722
+ * Destroy this object
723
+ *
724
+ * @since 3.0
725
+ * @return null
726
+ */
727
+ destroy: function () {
728
+ // Remove listeners
729
+ this.$elmt.off( 'click', '.ditty-extension__tab', { self: this }, this._tabClick );
730
+ this.$elmt.off( 'click', 'button[name="submit"]', { self: this }, this._updatePanel );
731
+ this.$elmt.off( 'click', '.ditty-extension__license__submit, .ditty-extension__license__refresh', { self: this, action: 'ditty_extension_license_activate' }, this._licenseUpdate );
732
+ this.$elmt.off( 'click', '.ditty-extension__license__deactivate', { self: this, action: 'ditty_extension_license_deactivate' }, this._licenseUpdate );
733
+ this.$panels.off( 'ditty_slider_after_slide_update', { self: this }, this._afterPanelUpdate );
734
+
735
+ this.$panels.ditty_slider( 'destroy' );
736
+ this.elmt._ditty_extension = null;
737
+ }
738
+ };
739
+
740
+ $.fn.ditty_extension = function( options ) {
741
+ var args = arguments,
742
+ error = false,
743
+ returns;
744
+
745
+ if ( options === undefined || typeof options === 'object' ) {
746
+ return this.each( function () {
747
+ if ( ! this._ditty_extension ) {
748
+ this._ditty_extension = new Ditty_Extension( this, options );
749
+ }
750
+ });
751
+ } else if ( typeof options === 'string' ) {
752
+ this.each( function () {
753
+ var instance = this._ditty_extension;
754
+
755
+ if ( ! instance ) {
756
+ throw new Error( 'No Ditty_Extension applied to this element.' );
757
+ }
758
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
759
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
760
+ } else {
761
+ error = true;
762
+ }
763
+ } );
764
+
765
+ if ( error ) {
766
+ throw new Error( 'No method "' + options + '" in Ditty_Extension.' );
767
+ }
768
+
769
+ return returns !== undefined ? returns : this;
770
+ }
771
+ };
772
+
773
+ $.ditty_extension = {};
774
+ $.ditty_extension.defaults = defaults;
775
+
776
+ } )( jQuery );
777
+
778
+
779
+
780
+ jQuery( document ).ready( function( $ ) {
781
+ // Setup strict mode
782
+ (function() {
783
+
784
+ "use strict";
785
+
786
+ // Setup protip
787
+ $.protip( {
788
+ defaults: {
789
+ position: 'top',
790
+ size: 'small',
791
+ scheme: 'black',
792
+ classes: 'ditty-protip'
793
+ }
794
+ } );
795
+
796
+ /**
797
+ * Listen for an accordion toggle click
798
+ *
799
+ * @since 3.0
800
+ * @return null
801
+ */
802
+ // $( '#ditty-extensions' ).on( 'click', '.ditty-accordion__toggle', function( e ) {
803
+ // e.preventDefault();
804
+ // var $accordion = $( this ).parent(),
805
+ // $content = $( this ).next();
806
+ //
807
+ // if ( $accordion.hasClass( 'active' ) ) {
808
+ // $accordion.removeClass( 'active' );
809
+ // $content.stop().slideUp( { duration: 750, easing: "easeInOutQuint" } );
810
+ // } else {
811
+ // $accordion.addClass( 'active' );
812
+ // $content.stop().slideDown( { duration: 750, easing: "easeInOutQuint" }, function() {
813
+ // $content.css( 'height', 'auto' );
814
+ // } );
815
+ // }
816
+ // } );
817
+ //
818
+ /**
819
+ * Initialize the extensions
820
+ *
821
+ * @since 3.0
822
+ * @return null
823
+ */
824
+ function ditty_extensions_init() {
825
+ $( '#ditty-extensions' ).find( '.ditty-extension' ).each( function( index ) {
826
+
827
+ var $extension = $( this ),
828
+ $panels = $extension.find( '.ditty-extension__panels' );
829
+
830
+ if ( $panels.length ) {
831
+ $extension.ditty_extension();
832
+ }
833
+
834
+ $( '#ditty-extensions' ).trigger( 'ditty_init_fields' );
835
+
836
+ setTimeout( function() {
837
+ $extension.addClass( 'ditty-extension--init' );
838
+ }, index * 250 );
839
+
840
+ } );
841
+ }
842
+ ditty_extensions_init();
843
+
844
+ }() );
845
+
846
+ } );
847
+
848
+
849
+ jQuery( document ).ready( function( $ ) {
850
+ // Setup strict mode
851
+ (function() {
852
+
853
+ "use strict";
854
+
855
+ var isDisplayPost = ( $( 'input[name="post_type"]' ).length && 'ditty_display' == $( 'input[name="post_type"]' ).val() ),
856
+ ajaxSubmitComplete = false;
857
+
858
+ $( 'form#post' ).on( 'submit', function( e ) {
859
+ if ( isDisplayPost && ! ajaxSubmitComplete ) {
860
+ e.preventDefault();
861
+
862
+ var $button = $( '#publishing-action' ).children( 'input[type="submit"]' ),
863
+ $spinner = $( '#publishing-action' ).children( '.spinner' );
864
+
865
+ $button.attr( 'disabled', 'disabled' );
866
+ $spinner.css( 'visibility', 'visible' );
867
+
868
+ var data = {
869
+ action : 'ditty_admin_display_update',
870
+ display_id : $( 'input[name="post_ID"]' ).val(),
871
+ security : dittyAdminVars.security
872
+ };
873
+ $( '#ditty-display-settings' ).ajaxSubmit( {
874
+ url : dittyAdminVars.ajaxurl,
875
+ type : 'post',
876
+ dataType : 'json',
877
+ data : data,
878
+ success: function( response ) {
879
+ ajaxSubmitComplete = true;
880
+ $( 'form#post' ).submit();
881
+ }
882
+ } );
883
+ }
884
+ } );
885
+
886
+ }() );
887
+
888
+ } );
includes/js/ditty-editor.js ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global dittyVars:true */
2
+ /* global jQuery:true */
3
+ // @codekit-append 'partials/class-ditty-ui-data-list.js';
4
+ // @codekit-append 'editor/helpers.js';
5
+ // @codekit-append 'editor/class-ditty-editor.js';
6
+ // @codekit-append 'editor/class-ditty-settings-panel.js';
7
+ // @codekit-append 'editor/class-ditty-items-panel.js';
8
+ // @codekit-append 'editor/class-ditty-item-types-panel.js';
9
+ // @codekit-append 'editor/class-ditty-item-editor-panel.js';
10
+ // @codekit-append 'editor/class-ditty-displays-panel.js';
11
+ // @codekit-append 'editor/class-ditty-display-editor-panel.js';
12
+ // @codekit-append 'editor/class-ditty-layout-variations-panel.js';
13
+ // @codekit-append 'editor/class-ditty-layouts-panel.js';
14
+ // @codekit-append 'editor/class-ditty-layout-html-editor-panel.js';
15
+ // @codekit-append 'editor/class-ditty-layout-css-editor-panel.js';
16
+ // @codekit-append 'editor/ditty-list-display-editor.js';
17
+
18
+ jQuery( document ).ready( function( $ ) {
19
+
20
+ // Setup strict mode
21
+ (function() {
22
+
23
+ "use strict";
24
+
25
+ /**
26
+ * Close down editor display panels appropriately
27
+ *
28
+ * @since 3.0
29
+ * @return null
30
+ */
31
+ $( 'body' ).on( 'ditty_editor_before_panel_update', function( event, slideId, $slide, prevSlideId, $prevSlide, editor ) {
32
+
33
+ // Disable any delayed Ditty updates
34
+ editor.delayedSubmitDisable();
35
+
36
+ // Setup protip
37
+ $.protip({
38
+ defaults: {
39
+ position: 'top',
40
+ size: 'small',
41
+ scheme: 'black',
42
+ classes: 'ditty-protip'
43
+ }
44
+ } );
45
+
46
+ switch( slideId ) {
47
+ case 'settings':
48
+ if ( ! $slide.hasClass( 'init' ) ) {
49
+ $slide.ditty_settings_panel( { editor: editor } );
50
+ }
51
+ break;
52
+ case 'items':
53
+ if ( $slide.hasClass( 'init' ) ) {
54
+ $slide.ditty_items_panel( 'panelVisible' );
55
+ } else {
56
+ $slide.ditty_items_panel( { editor: editor } );
57
+ }
58
+ break;
59
+ case 'displays':
60
+ $slide.find( '.ditty-data-list__item' ).removeClass( 'editing' );
61
+ if ( $slide.hasClass( 'init' ) ) {
62
+ $slide.ditty_displays_panel( 'panelVisible' );
63
+ } else {
64
+ $slide.ditty_displays_panel( {
65
+ editor: editor
66
+ } );
67
+ }
68
+ break;
69
+ case 'item_types':
70
+ $slide.find( '.ditty-data-list__item' ).removeClass( 'editing' );
71
+ if ( $slide.hasClass( 'init' ) ) {
72
+ $slide.ditty_item_types_panel( 'panelVisible' );
73
+ } else {
74
+ $slide.ditty_item_types_panel( {
75
+ editor: editor
76
+ } );
77
+ }
78
+ break;
79
+ case 'item_editor':
80
+ $slide.ditty_item_editor_panel( { editor : editor } );
81
+ break;
82
+ case 'display_editor':
83
+ $slide.ditty_display_editor_panel( { editor: editor } );
84
+ break;
85
+ case 'layouts':
86
+ if ( ! ( 'layoutHtmlEditor' === prevSlideId || 'layoutCssEditor' === prevSlideId ) ) {
87
+ $slide.ditty_layouts_panel( { editor : editor } );
88
+ }
89
+ break;
90
+ case 'layout_variations':
91
+ if ( $slide.hasClass( 'init' ) ) {
92
+ $slide.ditty_layout_variations_panel( 'panelVisible' );
93
+ } else {
94
+ $slide.ditty_layout_variations_panel( { editor : editor } );
95
+ }
96
+ break;
97
+ case 'layout_html_editor':
98
+ $slide.ditty_layout_html_editor_panel( {
99
+ editor : editor,
100
+ prevPanel : prevSlideId
101
+ } );
102
+ break;
103
+ case 'layout_css_editor':
104
+ $slide.ditty_layout_css_editor_panel( {
105
+ editor : editor,
106
+ prevPanel : prevSlideId
107
+ } );
108
+ break;
109
+ default:
110
+ break;
111
+ }
112
+ } );
113
+
114
+ /**
115
+ * Setup the editor display panel when ready
116
+ *
117
+ * @since 3.0
118
+ * @return null
119
+ */
120
+ $( 'body' ).on( 'ditty_editor_panel_removed', function( event, slideId, $slide ) {
121
+ switch( slideId ) {
122
+ case 'item_editor':
123
+ if ( $slide.ditty_item_editor_panel ) {
124
+ $slide.ditty_item_editor_panel( 'destroy' );
125
+ }
126
+ break;
127
+ case 'display_editor':
128
+ if ( $slide.ditty_display_editor_panel ) {
129
+ $slide.ditty_display_editor_panel( 'destroy' );
130
+ }
131
+ break;
132
+ case 'layouts':
133
+ if ( $slide.ditty_layouts_panel ) {
134
+ $slide.ditty_layouts_panel( 'destroy' );
135
+ }
136
+ break;
137
+ case 'layout_variations':
138
+ if ( $slide.ditty_layout_variations_panel ) {
139
+ $slide.ditty_layout_variations_panel( 'destroy' );
140
+ }
141
+ break;
142
+ case 'layouts':
143
+ if ( $slide.ditty_layouts_panel ) {
144
+ $slide.ditty_layouts_panel( 'destroy' );
145
+ }
146
+ break;
147
+ case 'layout_html_editor':
148
+ if ( $slide.ditty_layout_html_editor_panel ) {
149
+ $slide.ditty_layout_html_editor_panel( 'destroy' );
150
+ }
151
+ break;
152
+ case 'layout_css_editor':
153
+ if ( $slide.ditty_layout_css_editor_panel ) {
154
+ $slide.ditty_layout_css_editor_panel( 'destroy' );
155
+ }
156
+ break;
157
+ default:
158
+ break;
159
+ }
160
+ } );
161
+
162
+ }() );
163
+
164
+ } );
165
+
166
+
167
+ /**
168
+ * Initialize an editor
169
+ *
170
+ * @since 3.0
171
+ * @return null
172
+ */
173
+ function dittyEditorInit( ditty ) {
174
+ if ( ! ditty ) {
175
+ return false;
176
+ }
177
+ var status = ditty.options( 'status' ),
178
+ panel = 'auto-draft' === status ? 'settings' : false;
179
+
180
+ jQuery( '#ditty-editor__settings' ).ditty_editor( {
181
+ ditty: ditty,
182
+ panel: panel
183
+ } );
184
+ }
185
+ dittyEditorInit();
includes/js/ditty-editor.min.js ADDED
@@ -0,0 +1,5784 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global dittyVars:true */
2
+ /* global jQuery:true */
3
+ // @codekit-append 'partials/class-ditty-ui-data-list.js';
4
+ // @codekit-append 'editor/helpers.js';
5
+ // @codekit-append 'editor/class-ditty-editor.js';
6
+ // @codekit-append 'editor/class-ditty-settings-panel.js';
7
+ // @codekit-append 'editor/class-ditty-items-panel.js';
8
+ // @codekit-append 'editor/class-ditty-item-types-panel.js';
9
+ // @codekit-append 'editor/class-ditty-item-editor-panel.js';
10
+ // @codekit-append 'editor/class-ditty-displays-panel.js';
11
+ // @codekit-append 'editor/class-ditty-display-editor-panel.js';
12
+ // @codekit-append 'editor/class-ditty-layout-variations-panel.js';
13
+ // @codekit-append 'editor/class-ditty-layouts-panel.js';
14
+ // @codekit-append 'editor/class-ditty-layout-html-editor-panel.js';
15
+ // @codekit-append 'editor/class-ditty-layout-css-editor-panel.js';
16
+ // @codekit-append 'editor/ditty-list-display-editor.js';
17
+
18
+ jQuery( document ).ready( function( $ ) {
19
+
20
+ // Setup strict mode
21
+ (function() {
22
+
23
+ "use strict";
24
+
25
+ /**
26
+ * Close down editor display panels appropriately
27
+ *
28
+ * @since 3.0
29
+ * @return null
30
+ */
31
+ $( 'body' ).on( 'ditty_editor_before_panel_update', function( event, slideId, $slide, prevSlideId, $prevSlide, editor ) {
32
+
33
+ // Disable any delayed Ditty updates
34
+ editor.delayedSubmitDisable();
35
+
36
+ // Setup protip
37
+ $.protip({
38
+ defaults: {
39
+ position: 'top',
40
+ size: 'small',
41
+ scheme: 'black',
42
+ classes: 'ditty-protip'
43
+ }
44
+ } );
45
+
46
+ switch( slideId ) {
47
+ case 'settings':
48
+ if ( ! $slide.hasClass( 'init' ) ) {
49
+ $slide.ditty_settings_panel( { editor: editor } );
50
+ }
51
+ break;
52
+ case 'items':
53
+ if ( $slide.hasClass( 'init' ) ) {
54
+ $slide.ditty_items_panel( 'panelVisible' );
55
+ } else {
56
+ $slide.ditty_items_panel( { editor: editor } );
57
+ }
58
+ break;
59
+ case 'displays':
60
+ $slide.find( '.ditty-data-list__item' ).removeClass( 'editing' );
61
+ if ( $slide.hasClass( 'init' ) ) {
62
+ $slide.ditty_displays_panel( 'panelVisible' );
63
+ } else {
64
+ $slide.ditty_displays_panel( {
65
+ editor: editor
66
+ } );
67
+ }
68
+ break;
69
+ case 'item_types':
70
+ $slide.find( '.ditty-data-list__item' ).removeClass( 'editing' );
71
+ if ( $slide.hasClass( 'init' ) ) {
72
+ $slide.ditty_item_types_panel( 'panelVisible' );
73
+ } else {
74
+ $slide.ditty_item_types_panel( {
75
+ editor: editor
76
+ } );
77
+ }
78
+ break;
79
+ case 'item_editor':
80
+ $slide.ditty_item_editor_panel( { editor : editor } );
81
+ break;
82
+ case 'display_editor':
83
+ $slide.ditty_display_editor_panel( { editor: editor } );
84
+ break;
85
+ case 'layouts':
86
+ if ( ! ( 'layoutHtmlEditor' === prevSlideId || 'layoutCssEditor' === prevSlideId ) ) {
87
+ $slide.ditty_layouts_panel( { editor : editor } );
88
+ }
89
+ break;
90
+ case 'layout_variations':
91
+ if ( $slide.hasClass( 'init' ) ) {
92
+ $slide.ditty_layout_variations_panel( 'panelVisible' );
93
+ } else {
94
+ $slide.ditty_layout_variations_panel( { editor : editor } );
95
+ }
96
+ break;
97
+ case 'layout_html_editor':
98
+ $slide.ditty_layout_html_editor_panel( {
99
+ editor : editor,
100
+ prevPanel : prevSlideId
101
+ } );
102
+ break;
103
+ case 'layout_css_editor':
104
+ $slide.ditty_layout_css_editor_panel( {
105
+ editor : editor,
106
+ prevPanel : prevSlideId
107
+ } );
108
+ break;
109
+ default:
110
+ break;
111
+ }
112
+ } );
113
+
114
+ /**
115
+ * Setup the editor display panel when ready
116
+ *
117
+ * @since 3.0
118
+ * @return null
119
+ */
120
+ $( 'body' ).on( 'ditty_editor_panel_removed', function( event, slideId, $slide ) {
121
+ switch( slideId ) {
122
+ case 'item_editor':
123
+ if ( $slide.ditty_item_editor_panel ) {
124
+ $slide.ditty_item_editor_panel( 'destroy' );
125
+ }
126
+ break;
127
+ case 'display_editor':
128
+ if ( $slide.ditty_display_editor_panel ) {
129
+ $slide.ditty_display_editor_panel( 'destroy' );
130
+ }
131
+ break;
132
+ case 'layouts':
133
+ if ( $slide.ditty_layouts_panel ) {
134
+ $slide.ditty_layouts_panel( 'destroy' );
135
+ }
136
+ break;
137
+ case 'layout_variations':
138
+ if ( $slide.ditty_layout_variations_panel ) {
139
+ $slide.ditty_layout_variations_panel( 'destroy' );
140
+ }
141
+ break;
142
+ case 'layouts':
143
+ if ( $slide.ditty_layouts_panel ) {
144
+ $slide.ditty_layouts_panel( 'destroy' );
145
+ }
146
+ break;
147
+ case 'layout_html_editor':
148
+ if ( $slide.ditty_layout_html_editor_panel ) {
149
+ $slide.ditty_layout_html_editor_panel( 'destroy' );
150
+ }
151
+ break;
152
+ case 'layout_css_editor':
153
+ if ( $slide.ditty_layout_css_editor_panel ) {
154
+ $slide.ditty_layout_css_editor_panel( 'destroy' );
155
+ }
156
+ break;
157
+ default:
158
+ break;
159
+ }
160
+ } );
161
+
162
+ }() );
163
+
164
+ } );
165
+
166
+
167
+ /**
168
+ * Initialize an editor
169
+ *
170
+ * @since 3.0
171
+ * @return null
172
+ */
173
+ function dittyEditorInit( ditty ) {
174
+ if ( ! ditty ) {
175
+ return false;
176
+ }
177
+ var status = ditty.options( 'status' ),
178
+ panel = 'auto-draft' === status ? 'settings' : false;
179
+
180
+ jQuery( '#ditty-editor__settings' ).ditty_editor( {
181
+ ditty: ditty,
182
+ panel: panel
183
+ } );
184
+ }
185
+ dittyEditorInit();
186
+
187
+ /**
188
+ * UI - Data List
189
+ *
190
+ * @since 3.0
191
+ * @return null
192
+ */
193
+
194
+ (function ($) {
195
+ 'use strict';
196
+
197
+ var defaults = {
198
+ listType : 'toggle',
199
+ showAll : true,
200
+ activeFilter : '*',
201
+ filter : '.ditty-data-list__filter',
202
+ filterSelector : 'filter',
203
+ item : '.ditty-data-list__item',
204
+ itemSelector : 'filter'
205
+ };
206
+
207
+ var Ditty_UI_Data_List = function ( elmt, options ) {
208
+
209
+ this.elmt = elmt;
210
+ this.settings = $.extend( {}, defaults, $.ditty_ui_data_list.defaults, options );
211
+ this.$elmt = $( elmt );
212
+ this.filters = [];
213
+
214
+ this._init();
215
+ };
216
+
217
+
218
+ Ditty_UI_Data_List.prototype = {
219
+
220
+ /**
221
+ * Initialize the data list
222
+ *
223
+ * @since 3.0
224
+ * @return null
225
+ */
226
+ _init: function () {
227
+
228
+ var self = this;
229
+
230
+ this.$elmt.on( 'click', this.settings.filter, { self: this }, this._filterClick );
231
+ this.$elmt.find( this.settings.filter + '.active' ).each( function() {
232
+ self._filterList( $( this ).data( self.settings.filterSelector ) );
233
+ });
234
+
235
+ if ( '*' !== this.settings.activeFilter ) {
236
+ this._filterList( this.settings.activeFilter );
237
+ }
238
+
239
+ // Trigger the init
240
+ setTimeout( function () {
241
+ self.trigger( 'init' );
242
+ }, 1 );
243
+ },
244
+
245
+
246
+ /**
247
+ * Select the filter and update the list
248
+ *
249
+ * @since 3.0
250
+ * @return null
251
+ */
252
+ _filterList: function( filter ) {
253
+
254
+ var self = this,
255
+ filters = this.filters;
256
+
257
+ if ( 'toggle' === this.settings.listType ) {
258
+
259
+ if ( this.filters.includes( filter ) ) {
260
+ if ( this.settings.showAll ) {
261
+ this.filters = [];
262
+ this.$elmt.find( this.settings.filter ).removeClass( 'active' );
263
+ this.$elmt.find( this.settings.item ).show();
264
+ }
265
+ } else {
266
+ this.filters = [ filter ];
267
+ this.$elmt.find( this.settings.filter ).removeClass( 'active' );
268
+ this.$elmt.find( this.settings.filter + '[data-' + this.settings.filterSelector + '="' + filter + '"]' ).addClass( 'active' );
269
+ this.$elmt.find( this.settings.item ).hide();
270
+ this.$elmt.find( this.settings.item + '[data-' + this.settings.itemSelector + '="' + filter + '"]' ).show();
271
+ }
272
+ } else if ( 'filter' === this.settings.listType ) {
273
+
274
+ this.$elmt.find( this.settings.item ).hide();
275
+
276
+ if ( this.filters.includes( filter ) ) {
277
+ this.$elmt.find( this.settings.filter + '[data-' + this.settings.filterSelector + '="' + filter + '"]' ).removeClass( 'active' );
278
+ for( var i = 0; i < this.filters.length; i++ ) {
279
+ if ( self.filters[i] === filter ) {
280
+ self.filters.splice( i, 1 );
281
+ }
282
+ }
283
+ } else {
284
+ this.$elmt.find( this.settings.filter + '[data-' + this.settings.filterSelector + '="' + filter + '"]' ).addClass( 'active' );
285
+ this.filters.push( filter );
286
+ }
287
+
288
+ // Show the filtered items
289
+ $.each( this.filters, function( index, value ) {
290
+ self.$elmt.find( this.settings.item + '[data-' + this.settings.itemSelector + '="' + value + '"]' ).show();
291
+ });
292
+
293
+ // Show all if no filters
294
+ if( 0 === this.filters.length ) {
295
+ self.$elmt.find( this.settings.item ).show();
296
+ }
297
+ }
298
+
299
+ if ( filters !== this.filters ) {
300
+ self.trigger( 'update' );
301
+ }
302
+ },
303
+
304
+
305
+ /**
306
+ * Filter click listener
307
+ *
308
+ * @since 3.0
309
+ * @return null
310
+ */
311
+ _filterClick: function( e ) {
312
+ e.preventDefault();
313
+
314
+ var self = e.data.self,
315
+ $link = $( e.target );
316
+
317
+ if ( ! $link.is( 'a' ) ) {
318
+ $link = $link.parents( 'a' );
319
+ }
320
+
321
+ self._filterList( $link.data( self.settings.filterSelector ) );
322
+ },
323
+
324
+
325
+ /**
326
+ * Return a specific setting
327
+ *
328
+ * @since 3.0
329
+ * @return null
330
+ */
331
+ _options: function ( key ) {
332
+ return this.settings[key];
333
+ },
334
+
335
+
336
+ /**
337
+ * Setup triggers
338
+ *
339
+ * @since 3.0
340
+ * @return null
341
+ */
342
+ trigger: function ( fn, customParams ) {
343
+ var params = [ this.settings, this.filters ];
344
+
345
+ if ( customParams ) {
346
+ params = customParams;
347
+ }
348
+
349
+ this.$elmt.trigger( 'ditty_ui_data_list_' + fn, params );
350
+
351
+ if ( typeof this.settings[fn] === 'function' ) {
352
+ this.settings[fn].apply( this.$elmt, params );
353
+ }
354
+ },
355
+
356
+
357
+ /**
358
+ * Allow settings to be modified
359
+ *
360
+ * @since 3.0
361
+ * @return null
362
+ */
363
+ options: function ( key, value ) {
364
+
365
+ if ( typeof key === 'object' ) {
366
+ this.settings = $.extend( {}, defaults, $.ditty_ui_data_list.defaults, key );
367
+ } else if ( typeof key === 'string' ) {
368
+ if ( value === undefined ) {
369
+ return this.settings[key];
370
+ }
371
+ this.settings[key] = value;
372
+ } else {
373
+ return this.settings;
374
+ }
375
+
376
+ this.trigger( 'options_update' );
377
+ },
378
+
379
+
380
+ /**
381
+ * Destroy the editor
382
+ *
383
+ * @since 3.0
384
+ * @return null
385
+ */
386
+ destroy: function () {
387
+
388
+ this.$elmt.off( 'click', this.settings.filter, { self: this }, this._filterClick );
389
+
390
+ // Trigger a reset notice
391
+ this.trigger( 'destroy' );
392
+ this.elmt._ditty_ui_data_list = null;
393
+ }
394
+ };
395
+
396
+
397
+ /**
398
+ * Create the data list
399
+ *
400
+ * @since 3.0
401
+ * @return null
402
+ */
403
+ $.fn.ditty_ui_data_list = function( options ) {
404
+ var args = arguments,
405
+ error = false,
406
+ returns;
407
+
408
+ if ( options === undefined || typeof options === 'object' ) {
409
+ return this.each( function () {
410
+ if ( ! this._ditty_ui_data_list ) {
411
+ this._ditty_ui_data_list = new Ditty_UI_Data_List( this, options );
412
+ }
413
+ });
414
+ } else if ( typeof options === 'string' ) {
415
+ this.each( function () {
416
+ var instance = this._ditty_ui_data_list;
417
+
418
+ if ( ! instance ) {
419
+ throw new Error( 'No Ditty_UI_Data_List applied to this element.' );
420
+ }
421
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
422
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
423
+ } else {
424
+ error = true;
425
+ }
426
+ } );
427
+
428
+ if ( error ) {
429
+ throw new Error( 'No method "' + options + '" in Ditty_UI_Data_List.' );
430
+ }
431
+
432
+ return returns !== undefined ? returns : this;
433
+ }
434
+ };
435
+
436
+ $.ditty_ui_data_list = {};
437
+ $.ditty_ui_data_list.defaults = defaults;
438
+
439
+ } )( jQuery );
440
+
441
+
442
+ /**
443
+ * Reorder a set of items by id
444
+ *
445
+ * @since 3.0
446
+ * @return null
447
+ */
448
+ function dittyGetItemsById( items, id ) {
449
+ var idItems = [];
450
+ jQuery.each( items, function( i, item ) {
451
+ if ( String( item.id ) === String( id ) ) {
452
+ idItems.push( item );
453
+ }
454
+ } );
455
+ return idItems;
456
+ }
457
+
458
+ /**
459
+ * Reorder a set of items
460
+ *
461
+ * @since 3.0
462
+ * @return null
463
+ */
464
+ function dittyItemsReorder( items, ids ) {
465
+ var orderedItems = [];
466
+ jQuery.each( ids, function( index, id ) {
467
+ orderedItems = jQuery.merge( orderedItems, dittyGetItemsById( items, id ) );
468
+ } );
469
+ return orderedItems;
470
+ }
471
+
472
+ /**
473
+ * Ditty editor ajax request
474
+ * @since 3.0
475
+ * @return null
476
+ */
477
+ // function ditty_editor_ajax( data, elmt ) {
478
+ // var defaults = {
479
+ // action : 'ditty_editor_ajax',
480
+ // draft_values : elmt.settings.editor.getDraftValues(),
481
+ // security : dittyVars.security
482
+ // };
483
+ // var ajax_data = jQuery.extend( {}, defaults, data );
484
+ // jQuery.post( dittyVars.ajaxurl, ajax_data, function( response ) {
485
+ // if ( response.draft_values ) {
486
+ // elmt.settings.editor.updateDraftValues( false, response.draft_values );
487
+ // }
488
+ // if ( response.hook ) {
489
+ // elmt.$elmt.trigger( response.hook, [response] );
490
+ // }
491
+ // }, 'json' );
492
+ // }
493
+
494
+ /**
495
+ * Update draft data
496
+ * @since 3.0
497
+ * @return null
498
+ */
499
+ function dittyDraftUpdate( elmt, type, key, value ) {
500
+ var draftValues = elmt.settings.editor.getDraftValues( type );
501
+ if ( ! draftValues ) {
502
+ draftValues = {};
503
+ }
504
+ if ( key ) {
505
+ draftValues[key] = value;
506
+ } else {
507
+ draftValues = value;
508
+ }
509
+ return elmt.settings.editor.updateDraftValues( type, draftValues );
510
+ }
511
+
512
+ /**
513
+ * Get draft data
514
+ * @since 3.0
515
+ * @return null
516
+ */
517
+ function dittyDraftGet( elmt, type, key ) {
518
+ var draftValues = elmt.settings.editor.getDraftValues( type );
519
+ if ( ! draftValues ) {
520
+ return false;
521
+ }
522
+ if ( key && draftValues[key] ) {
523
+ return draftValues[key];
524
+ } else {
525
+ return draftValues;
526
+ }
527
+ }
528
+
529
+ /**
530
+ * Set a ditty element to delete
531
+ *
532
+ * @since 3.0
533
+ * @return null
534
+ */
535
+ function dittyDraftDelete( type, elmt, el_id ) {
536
+ var draftValues = elmt.settings.editor.getDraftValues( type ),
537
+ updatedDraftValues = {};
538
+
539
+ jQuery.each( draftValues, function( id, values ) {
540
+ if ( String( el_id ) !== String( id ) ) {
541
+ updatedDraftValues[id] = values;
542
+ }
543
+ } );
544
+ if ( 'new-' !== String( el_id ).substring( 0, 4 ) ) {
545
+ updatedDraftValues[el_id] = 'DELETE';
546
+ }
547
+ return elmt.settings.editor.updateDraftValues( type, updatedDraftValues );
548
+ }
549
+ function dittyDraftItemDelete( elmt, itemId ) {
550
+ return dittyDraftDelete( 'items', elmt, itemId );
551
+ }
552
+ function dittyDraftLayoutDelete( elmt, layoutId ) {
553
+ return dittyDraftDelete( 'layouts', elmt, layoutId );
554
+ }
555
+ function dittyDraftDisplayDelete( elmt, displayId ) {
556
+ return dittyDraftDelete( 'displays', elmt, displayId );
557
+ }
558
+
559
+ /**
560
+ * Update item draft data
561
+ *
562
+ * @since 3.0
563
+ * @return null
564
+ */
565
+ function dittyDraftItemUpdateData( elmt, itemId, key, value ) {
566
+ var itemDraftValues = elmt.settings.editor.getDraftValues( 'items' );
567
+ if ( ! itemDraftValues ) {
568
+ itemDraftValues = {};
569
+ }
570
+ if ( ! itemDraftValues[itemId] ) {
571
+ itemDraftValues[itemId] = {};
572
+ }
573
+ if ( ! itemDraftValues[itemId].data ) {
574
+ itemDraftValues[itemId].data = {};
575
+ }
576
+ if ( key ) {
577
+ itemDraftValues[itemId].data[key] = value;
578
+ } else {
579
+ itemDraftValues[itemId].data = value;
580
+ }
581
+ return elmt.settings.editor.updateDraftValues( 'items', itemDraftValues );
582
+ }
583
+
584
+ /**
585
+ * Get item draft data
586
+ *
587
+ * @since 3.0
588
+ * @return null
589
+ */
590
+ function dittyDraftItemGetData( elmt, itemId, key ) {
591
+ var itemDraftValues = elmt.settings.editor.getDraftValues( 'items' );
592
+ if ( ! itemDraftValues[itemId] ) {
593
+ return false;
594
+ }
595
+ if ( ! itemDraftValues[itemId].data ) {
596
+ return false;
597
+ }
598
+ if ( key ) {
599
+ if ( itemDraftValues[itemId].data[key] ) {
600
+ return itemDraftValues[itemId].data[key];
601
+ }
602
+ } else {
603
+ return itemDraftValues[itemId].data;
604
+ }
605
+ }
606
+
607
+ /**
608
+ * Update item draft meta
609
+ *
610
+ * @since 3.0
611
+ * @return null
612
+ */
613
+ function dittyDraftItemUpdateMeta( elmt, itemId, key, value ) {
614
+ var itemDraftValues = elmt.settings.editor.getDraftValues( 'items' );
615
+ if ( ! itemDraftValues ) {
616
+ itemDraftValues = {};
617
+ }
618
+ if ( ! itemDraftValues[itemId] ) {
619
+ itemDraftValues[itemId] = {};
620
+ }
621
+ if ( ! itemDraftValues[itemId].meta ) {
622
+ itemDraftValues[itemId].meta = {};
623
+ }
624
+ if ( key ) {
625
+ itemDraftValues[itemId].meta[key] = value;
626
+ } else {
627
+ itemDraftValues[itemId].meta = value;
628
+ }
629
+ return elmt.settings.editor.updateDraftValues( 'items', itemDraftValues );
630
+ }
631
+
632
+ /**
633
+ * Get item draft meta
634
+ *
635
+ * @since 3.0
636
+ * @return null
637
+ */
638
+ function dittyDraftItemGetMeta( elmt, itemId, key ) {
639
+ var itemDraftValues = elmt.settings.editor.getDraftValues( 'items' );
640
+ if ( ! itemDraftValues[itemId] ) {
641
+ return false;
642
+ }
643
+ if ( ! itemDraftValues[itemId].meta ) {
644
+ return false;
645
+ }
646
+ if ( key ) {
647
+ if ( itemDraftValues[itemId].meta[key] ) {
648
+ return itemDraftValues[itemId].meta[key];
649
+ }
650
+ } else {
651
+ return itemDraftValues[itemId].meta;
652
+ }
653
+ }
654
+
655
+ /**
656
+ * Update layout draft meta
657
+ *
658
+ * @since 3.0
659
+ * @return null
660
+ */
661
+ function dittyDraftLayoutUpdate( elmt, layoutId, key, value ) {
662
+ var layoutDraftValues = elmt.settings.editor.getDraftValues( 'layouts' );
663
+ if ( ! layoutDraftValues ) {
664
+ layoutDraftValues = {};
665
+ }
666
+ if ( ! layoutDraftValues[layoutId] ) {
667
+ layoutDraftValues[layoutId] = {};
668
+ }
669
+ if ( key ) {
670
+ layoutDraftValues[layoutId][key] = value;
671
+ } else {
672
+ layoutDraftValues[layoutId] = value;
673
+ }
674
+ return elmt.settings.editor.updateDraftValues( 'layouts', layoutDraftValues );
675
+ }
676
+
677
+ /**
678
+ * Get layout draft meta
679
+ *
680
+ * @since 3.0
681
+ * @return null
682
+ */
683
+ function dittyDraftLayoutGet( elmt, layoutId, key ) {
684
+ var layoutDraftValues = elmt.settings.editor.getDraftValues( 'layouts' );
685
+ if ( ! layoutDraftValues[layoutId] ) {
686
+ return false;
687
+ }
688
+ if ( key ) {
689
+ if ( layoutDraftValues[layoutId][key] ) {
690
+ return layoutDraftValues[layoutId][key];
691
+ }
692
+ } else {
693
+ return layoutDraftValues[layoutId];
694
+ }
695
+ }
696
+
697
+ /**
698
+ * Update display draft meta
699
+ *
700
+ * @since 3.0
701
+ * @return null
702
+ */
703
+ function dittyDraftDisplayUpdate( elmt, displayId, key, value ) {
704
+ var displayDraftValues = elmt.settings.editor.getDraftValues( 'displays' );
705
+ if ( ! displayDraftValues ) {
706
+ displayDraftValues = {};
707
+ }
708
+ if ( ! displayDraftValues[displayId] ) {
709
+ displayDraftValues[displayId] = {};
710
+ }
711
+ if ( key ) {
712
+ displayDraftValues[displayId][key] = value;
713
+ } else {
714
+ displayDraftValues[displayId] = value;
715
+ }
716
+ return elmt.settings.editor.updateDraftValues( 'displays', displayDraftValues );
717
+ }
718
+
719
+ /**
720
+ * Get layout draft meta
721
+ *
722
+ * @since 3.0
723
+ * @return null
724
+ */
725
+ function dittyDraftDisplayGet( elmt, displayId, key ) {
726
+ var displayDraftValues = elmt.settings.editor.getDraftValues( 'layouts' );
727
+ if ( ! displayDraftValues[displayId] ) {
728
+ return false;
729
+ }
730
+ if ( key ) {
731
+ if ( displayDraftValues[displayId][key] ) {
732
+ return displayDraftValues[displayId][key];
733
+ }
734
+ } else {
735
+ return displayDraftValues[displayId];
736
+ }
737
+ }
738
+
739
+ /* global tinymce:true */
740
+
741
+ /**
742
+ * Ditty Editor
743
+ *
744
+ * @since 3.0
745
+ * @return null
746
+ */
747
+
748
+ (function ($) {
749
+ 'use strict';
750
+
751
+ var defaults = {
752
+ screen : 'admin',
753
+ ditty : null,
754
+ panel : ''
755
+ };
756
+
757
+ var Ditty_Editor = function( elmt, options ) {
758
+
759
+ this.elmt = elmt;
760
+ this.settings = $.extend( {}, defaults, $.ditty_editor.defaults, options );
761
+ this.$elmt = $( elmt );
762
+ this.ditty = this.settings.ditty;
763
+ this.dittyId = this.settings.ditty.options( 'id' );
764
+ this.dittyType = this.settings.ditty.options( 'type' );
765
+ this.displayId = 0;
766
+ this.panelsLoaded = 0;
767
+ this.unsavedUpdates = {};
768
+ this.draftValues = {};
769
+
770
+ this.$overlay = null;
771
+ this.$contents = null;
772
+ this.$header = null;
773
+ this.$update = null;
774
+ this.$updateCount = null;
775
+ this.$updateLabel = null;
776
+ this.$tabs = null;
777
+ this.$panels = null;
778
+ this.currentTab = 0;
779
+ this.currentPanel = this.settings.panel;
780
+ this.delayedSubmit = false;
781
+ this.tabs = [];
782
+ this.panels = [];
783
+ this.activeItems = [];
784
+
785
+ this._init();
786
+ };
787
+
788
+
789
+ Ditty_Editor.prototype = {
790
+
791
+ /**
792
+ * Initialize the editor
793
+ *
794
+ * @since 3.0
795
+ * @return null
796
+ */
797
+ _init: function () {
798
+ var self = this,
799
+ $contents,
800
+ $header,
801
+ $updateCount,
802
+ $updateLabel,
803
+ $update,
804
+ $tabs,
805
+ $panels;
806
+
807
+ // Create the editor contents
808
+ $contents = $( '<div class="ditty-editor__contents"></div>' );
809
+ this.$contents = $contents;
810
+
811
+ // Create the editor header
812
+ $header = $( '<div class="ditty-editor__header"></div>' );
813
+ this.$header = $header;
814
+
815
+ // Create the editor update button count
816
+ $updateCount = $( '<span class="ditty-editor__update__count"></span>' );
817
+ this.$updateCount = $updateCount;
818
+
819
+ // Create the editor update button label
820
+ $updateLabel = $( '<span class="ditty-editor__update__label">Save Ditty</span>' );
821
+ this.$updateLabel = $updateLabel;
822
+
823
+ // Create the editor update button
824
+ $update = $( '<button type="submit" class="ditty-editor__update ditty-button ditty-button--primary"></button>' );
825
+ this.$update = $update;
826
+
827
+ // Create the editor tabs
828
+ $tabs = $( '<div class="ditty-editor__tabs"></div>' );
829
+ this.$tabs = $tabs;
830
+
831
+ // Create the editor panels
832
+ $panels = $( '<div class="ditty-editor__panels"></div>' );
833
+ this.$panels = $panels;
834
+
835
+ // Add the new elements
836
+ $update.prepend( $updateCount, $updateLabel );
837
+ $header.append( $update );
838
+ $contents.append( $header, $tabs, $panels );
839
+ this.$elmt.append( $contents );
840
+
841
+ this.$overlay = $( '<div class="ditty-updating-overlay ditty-admin-item__overlay"><div class="ditty-updating-overlay__inner"><i class="fas fa-sync-alt fa-spin"></i></div></div>' );
842
+ this.$elmt.append( this.$overlay );
843
+
844
+ // Setup action listeners
845
+ $( document ).on( 'postbox-moved', { self: this }, this._postboxMoved );
846
+ $( document ).on( 'postboxes-columnchange', { self: this }, this._postboxMoved );
847
+ $( window ).on( 'beforeunload', { self: this }, this._beforeunload );
848
+ this.ditty.$elmt.on( 'ditty_active_items_update', { self: this }, this._dittyItemsUpdated );
849
+ this.ditty.$elmt.on( 'ditty_disabled_items_update', { self: this }, this._disabledItemsUpdate );
850
+ this.$tabs.on( 'click', '.ditty-editor__tab', { self: this }, this._showPanel );
851
+ this.$update.on( 'click', { self: this }, this._saveClick );
852
+ this.$panels.on( 'ditty_slider_init', { self: this }, this._editorLoaded );
853
+ this.$panels.on( 'ditty_slider_before_slide_update', { self: this }, this._beforeSlideUpdate );
854
+ this.$panels.on( 'ditty_slider_after_slide_update', { self: this }, this._afterSlideUpdate );
855
+ this.$panels.on( 'ditty_slider_slide_removed', { self: this }, this._slideRemoved );
856
+
857
+ // Load the editor contents
858
+ this._loadContents();
859
+
860
+ // Stop live updates
861
+ this.trigger( 'stop_live_updates' );
862
+
863
+ // Trigger the init
864
+ setTimeout( function() {
865
+ self.trigger( 'init' );
866
+ }, 1 );
867
+ },
868
+
869
+
870
+ /**
871
+ * Select the filter and update the list
872
+ *
873
+ * @since 3.0
874
+ * @return null
875
+ */
876
+ _loadContents: function() {
877
+
878
+ var self = this;
879
+
880
+ var data = {
881
+ action : 'ditty_editor_load_contents',
882
+ ditty_id : this.dittyId,
883
+ security : dittyVars.security
884
+ };
885
+
886
+ $.post( dittyVars.ajaxurl, data, function( response ) {
887
+ self._initTabs( response.tabs );
888
+ self._initPanels( response.panels );
889
+ self._initSlider();
890
+ }, 'json' );
891
+
892
+ },
893
+
894
+ /**
895
+ * Initialize the editor
896
+ *
897
+ * @since 3.0
898
+ * @return null
899
+ */
900
+ _editorLoaded: function ( e ) {
901
+ var self = e.data.self;
902
+ $( 'body' ).trigger( 'ditty_editor_loaded', [ self ] );
903
+ },
904
+
905
+ /**
906
+ * Get the editor update count
907
+ *
908
+ * @since 3.0
909
+ * @return null
910
+ */
911
+ _setUpdateCount: function() {
912
+ // var total = 0;
913
+ // $.each( this.unsavedUpdates, function( type, data ) {
914
+ // total += data.length;
915
+ // } );
916
+ //
917
+ // if ( total > 0 ) {
918
+ // this.$updateCount.text( total );
919
+ // } else {
920
+ // this.$updateCount.text( '' );
921
+ // }
922
+ },
923
+
924
+ /**
925
+ * Initialize the slider
926
+ *
927
+ * @since 3.0
928
+ * @return null
929
+ */
930
+ _initSlider: function () {
931
+ var slideId = this.tabs[0].id;
932
+ if ( this.currentPanel && '' !== this.currentPanel ) {
933
+ slideId = this.currentPanel;
934
+ }
935
+
936
+ // Create a new slider and bind actions
937
+ this.$panels.ditty_slider( {
938
+ transition : 'fade',
939
+ transitionSpeed : 0.75,
940
+ heightSpeed : 0.75,
941
+ touchSwipe : false,
942
+ slides : this.panels,
943
+ slideId : slideId
944
+ } );
945
+ },
946
+
947
+ /**
948
+ * Before slide update
949
+ *
950
+ * @since 3.0
951
+ * @return null
952
+ */
953
+ _beforeSlideUpdate: function ( e, index, slide, prevIndex, prevSlide ) {
954
+ var self = e.data.self;
955
+ self.updateStart();
956
+ self._updateTab( slide.id );
957
+ $( 'body' ).trigger( 'ditty_editor_before_panel_update', [ slide.id, slide.$elmt, prevSlide.id, prevSlide.$elmt, self ] );
958
+ },
959
+
960
+ /**
961
+ * After slide update
962
+ *
963
+ * @since 3.0
964
+ * @return null
965
+ */
966
+ _afterSlideUpdate: function ( e, index, slide, prevIndex, prevSlide ) {
967
+ var self = e.data.self;
968
+ self.updateStop();
969
+ $( 'body' ).trigger( 'ditty_editor_after_panel_update', [ slide.id, slide.$elmt, prevSlide.id, prevSlide.$elmt, self ] );
970
+ },
971
+
972
+ /**
973
+ * Slide removed notice
974
+ *
975
+ * @since 3.0
976
+ * @return null
977
+ */
978
+ _slideRemoved: function ( e, slide ) {
979
+ var self = e.data.self;
980
+ $( 'body' ).trigger( 'ditty_editor_panel_removed', [ slide.id, slide.$elmt, self ] );
981
+ },
982
+
983
+ /**
984
+ * Show a specific panel
985
+ *
986
+ * @since 3.0
987
+ * @return null
988
+ */
989
+ _showPanel: function ( e ) {
990
+ e.preventDefault();
991
+ var self = e.data.self,
992
+ $tab = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
993
+ panelId = $tab.data( 'panel' ),
994
+ index = parseInt( $tab.data( 'index' ) );
995
+
996
+ if ( panelId === self.currentTab ) {
997
+ return false;
998
+ }
999
+
1000
+ var transition = index > self.currentTab ? 'slideLeft' : 'slideRight';
1001
+ self.$panels.ditty_slider( 'options', 'transition', transition );
1002
+ self.$panels.ditty_slider( 'showSlideById', panelId );
1003
+ self.currentTab = index;
1004
+ self.$elmt.trigger( 'ditty_editor_add_drafts' );
1005
+ },
1006
+
1007
+ /**
1008
+ * Update the active tab
1009
+ *
1010
+ * @since 3.0
1011
+ * @return null
1012
+ */
1013
+ _updateTab: function ( id ) {
1014
+ var $tab = $( '.ditty-editor__tab[data-panel="' + id + '"]' );
1015
+ if ( undefined !== $tab[0] ) {
1016
+ $( '.ditty-editor__tab' ).removeClass( 'active' );
1017
+ $tab.addClass( 'active' );
1018
+ this.currentTab = parseInt( $tab.data( 'index' ) );
1019
+ }
1020
+ },
1021
+
1022
+ /**
1023
+ * Initialize the editor tabs
1024
+ *
1025
+ * @since 3.0
1026
+ * @return null
1027
+ */
1028
+ _initTabs: function ( tabs ) {
1029
+ var self = this,
1030
+ index = 0;
1031
+ $.each( tabs, function( key, value ) {
1032
+ var $tab = $( '<a href="#" class="ditty-editor__tab ditty-editor__tab--' + key + '" data-panel="' + key + '" data-index="' + index + '"><i class="' + value.icon + '"></i><span>' + value.label + '</span></a>' );
1033
+ self.$tabs.append( $tab );
1034
+ self.tabs.push( {
1035
+ id: key,
1036
+ tab: $tab
1037
+ } );
1038
+ index++;
1039
+ } );
1040
+ },
1041
+
1042
+ /**
1043
+ * Initialize the editor panels
1044
+ *
1045
+ * @since 3.0
1046
+ * @return null
1047
+ */
1048
+ _initPanels: function ( panels ) {
1049
+ var self = this;
1050
+ $.each( panels, function( key, value ) {
1051
+ var html = '<div class="ditty-editor__panel ditty-editor__panel--' + key + '">' + value + '</div>';
1052
+ self.panels.push( {
1053
+ id : key,
1054
+ html : html,
1055
+ cache : true
1056
+ } );
1057
+ } );
1058
+ },
1059
+
1060
+ /**
1061
+ * Initialize dynamic fields
1062
+ *
1063
+ * @since 3.0
1064
+ * @return null
1065
+ */
1066
+ _initFields: function ( $fields ) {
1067
+ $fields.find( '.ditty-data-list' ).ditty_ui_data_list();
1068
+ $fields.trigger( 'ditty_init_fields' );
1069
+ $.protip({
1070
+ defaults: {
1071
+ position: 'top',
1072
+ size: 'small',
1073
+ scheme: 'black',
1074
+ classes: 'ditty-protip'
1075
+ }
1076
+ });
1077
+ },
1078
+
1079
+ /**
1080
+ * Save the Ditty via ajax
1081
+ *
1082
+ * @since 3.0
1083
+ * @return null
1084
+ */
1085
+ saveDitty: function( args ) {
1086
+ var self = this,
1087
+ dittyId = self.dittyId;
1088
+
1089
+ self.$updateLabel.text( 'Updating...' );
1090
+ self.updateStart(); // Stop the update overlay
1091
+
1092
+ var data = {
1093
+ action : 'ditty_editor_save',
1094
+ ditty_id : dittyId,
1095
+ draft_values : self.draftValues,
1096
+ return_items : 1,
1097
+ security : dittyVars.security
1098
+ };
1099
+ data = $.extend( {}, data, args );
1100
+
1101
+ $.post( dittyVars.ajaxurl, data, function( response ) {
1102
+ $( 'body' ).trigger( 'ditty_editor_save_ditty_response', [response] );
1103
+
1104
+ // Update the items
1105
+ if ( response.display_items ) {
1106
+ self.ditty.options( 'items', response.display_items );
1107
+ }
1108
+ self.draftValues = {};
1109
+ self.unsavedUpdates = {};
1110
+ self._setUpdateCount();
1111
+ self.$elmt.removeClass( 'ditty-editor--updates-exist' );
1112
+
1113
+ self.$updateLabel.text( 'Ditty Saved!' );
1114
+ setTimeout(function() {
1115
+ self.$updateLabel.text( 'Save Ditty' );
1116
+ }, 2000 );
1117
+ self.updateStop(); // Stop the update overlay
1118
+
1119
+ if ( response.new_ditty_url ) {
1120
+ window.history.pushState( null, '', '/wp-admin/post.php?post=' + dittyId + '&action=edit' );
1121
+ }
1122
+ } );
1123
+ },
1124
+ _saveClick: function( e ) {
1125
+ e.preventDefault();
1126
+ var self = e.data.self;
1127
+ self.$elmt.trigger( 'ditty_editor_save_drafts' );
1128
+ if ( ! self.delayedSubmit ) {
1129
+ self.saveDitty();
1130
+ }
1131
+ },
1132
+
1133
+ /**
1134
+ * Close
1135
+ *
1136
+ * @since 3.0
1137
+ * @return null
1138
+ */
1139
+ /*
1140
+ _close: function() {
1141
+ //this.trigger( 'close' );
1142
+ },
1143
+ */
1144
+
1145
+ /**
1146
+ * Cancel click
1147
+ *
1148
+ * @since 3.0
1149
+ * @return null
1150
+ */
1151
+ /*
1152
+ _cancel_click: function( e ) {
1153
+ e.preventDefault();
1154
+ var self = e.data.self;
1155
+ self._close();
1156
+ },
1157
+ */
1158
+
1159
+ /**
1160
+ * Listen for updated items
1161
+ *
1162
+ * @since 3.0
1163
+ * @return null
1164
+ */
1165
+ _dittyItemsUpdated: function( e, ditty, items ) {
1166
+ var self = e.data.self;
1167
+ self.activeItems = items;
1168
+ self.trigger( 'active_items_update' );
1169
+ },
1170
+
1171
+ /**
1172
+ * Listen for updated disabled items
1173
+ *
1174
+ * @since 3.0
1175
+ * @return null
1176
+ */
1177
+ _disabledItemsUpdate: function( e, items ) {
1178
+ var self = e.data.self;
1179
+ $.each( items, function( id, status ) {
1180
+ if ( 'disabled' === status ) {
1181
+ self.$elmt.find( '#ditty-editor-item--' + id ).addClass( 'ditty-editor-item--disabled' );
1182
+ } else {
1183
+ self.$elmt.find( '#ditty-editor-item--' + id ).removeClass( 'ditty-editor-item--disabled' );
1184
+ }
1185
+ } );
1186
+ },
1187
+
1188
+ /**
1189
+ * Postbox moved listener
1190
+ *
1191
+ * @since 3.0
1192
+ * @return null
1193
+ */
1194
+ _postboxMoved: function ( e, item ) {
1195
+ if ( ! window.tinymce ) {
1196
+ return false;
1197
+ }
1198
+
1199
+ $( item ).find( '.wp-editor-area' ).each( function() {
1200
+ var id = $( this ).attr( 'id' );
1201
+ tinymce.execCommand( 'mceRemoveEditor', true, id );
1202
+ tinymce.execCommand( 'mceAddEditor', true, id );
1203
+ } );
1204
+ },
1205
+
1206
+ /**
1207
+ * Warn users before leaving
1208
+ *
1209
+ * @since 3.0
1210
+ * @return null
1211
+ */
1212
+ _beforeunload: function ( e ) {
1213
+ var self = e.data.self;
1214
+ if ( Object.keys( self.unsavedUpdates ).length > 0 ) {
1215
+ return true;
1216
+ } else {
1217
+ return undefined;
1218
+ }
1219
+ },
1220
+
1221
+ /**
1222
+ * Window resize listener
1223
+ *
1224
+ * @since 3.0
1225
+ * @return null
1226
+ */
1227
+ _windowResize: function( e ) {
1228
+ e.preventDefault();
1229
+ //var self = e.data.self;
1230
+ //self._set_editor_padding();
1231
+ },
1232
+
1233
+ /**
1234
+ * Return a specific setting
1235
+ *
1236
+ * @since 3.0
1237
+ * @return null
1238
+ */
1239
+ _options: function ( key ) {
1240
+ return this.settings[key];
1241
+ },
1242
+
1243
+ /**
1244
+ * Check if an update exists
1245
+ *
1246
+ * @since 3.0
1247
+ * @return null
1248
+ */
1249
+ panelExists: function ( id ) {
1250
+ var panels = this.$panels.ditty_slider( 'options', 'slides' ),
1251
+ exists = false;
1252
+
1253
+ $.each( panels, function( index, panel ) {
1254
+ if ( String( panel.id ) === String( id ) ) {
1255
+ exists = true;
1256
+ return;
1257
+ }
1258
+ } );
1259
+ return exists;
1260
+ },
1261
+
1262
+ /**
1263
+ * Check if an update exists
1264
+ *
1265
+ * @since 3.0
1266
+ * @return null
1267
+ */
1268
+ showPanel: function ( id, html ) {
1269
+ if ( html ) {
1270
+ this.$panels.ditty_slider( 'addSlideById', id, html );
1271
+ }
1272
+ this.$panels.ditty_slider( 'showSlideById', id, true );
1273
+ },
1274
+
1275
+ /**
1276
+ * Check if an update exists
1277
+ *
1278
+ * @since 3.0
1279
+ * @return null
1280
+ */
1281
+ updateExists: function ( type, id ) {
1282
+ if ( undefined === this.unsavedUpdates[type] ) {
1283
+ this.unsavedUpdates[type] = [];
1284
+ }
1285
+ if ( -1 !== $.inArray( id, this.unsavedUpdates[type] ) ) {
1286
+ return true;
1287
+ }
1288
+ },
1289
+
1290
+ /**
1291
+ * Let the user know there are unsaved updates
1292
+ *
1293
+ * @since 3.0
1294
+ * @return null
1295
+ */
1296
+ addUpdate: function ( type, id ) {
1297
+ var updated = false;
1298
+ if ( undefined === this.unsavedUpdates[type] ) {
1299
+ this.unsavedUpdates[type] = [];
1300
+ }
1301
+ if ( -1 === $.inArray( id, this.unsavedUpdates[type] ) ) {
1302
+ updated = true;
1303
+ this.unsavedUpdates[type].push( id );
1304
+ }
1305
+ this._setUpdateCount();
1306
+ this.$elmt.addClass( 'ditty-editor--updates-exist' );
1307
+ //this.$updateLabel.text( 'Unsaved Updates' );
1308
+
1309
+ return updated;
1310
+ },
1311
+
1312
+ /**
1313
+ * Remove an update notification
1314
+ *
1315
+ * @since 3.0
1316
+ * @return null
1317
+ */
1318
+ removeUpdate: function ( type, id ) {
1319
+ if ( undefined === this.unsavedUpdates[type] ) {
1320
+ return false;
1321
+ }
1322
+ if ( -1 === $.inArray( id, this.unsavedUpdates[type] ) ) {
1323
+ return false;
1324
+ }
1325
+ var removed = false,
1326
+ updatedType = [];
1327
+
1328
+ $.each( this.unsavedUpdates[type], function( index, type_id ) {
1329
+ if ( String( id ) === String( type_id ) ) {
1330
+ removed = true;
1331
+ } else {
1332
+ updatedType.push( type_id );
1333
+ }
1334
+ } );
1335
+ this.unsavedUpdates[type] = updatedType;
1336
+ this._setUpdateCount();
1337
+ if ( '' === this.$updateCount.text() ) {
1338
+ this.$elmt.removeClass( 'ditty-editor--updates-exist' );
1339
+ }
1340
+ return removed;
1341
+ },
1342
+
1343
+ /**
1344
+ * Show the update overlay
1345
+ *
1346
+ * @since 3.0
1347
+ * @return null
1348
+ */
1349
+ updateStart: function () {
1350
+ this.$overlay.fadeIn();
1351
+ },
1352
+
1353
+ /**
1354
+ * Hide the update overlay
1355
+ *
1356
+ * @since 3.0
1357
+ * @return null
1358
+ */
1359
+ updateStop: function () {
1360
+ this.$overlay.fadeOut();
1361
+ },
1362
+
1363
+ /**
1364
+ * Initialize dynamic fields
1365
+ *
1366
+ * @since 3.0
1367
+ * @return null
1368
+ */
1369
+ initFields: function ( $fields ) {
1370
+ this._initFields( $fields );
1371
+ },
1372
+
1373
+ /**
1374
+ * Add draft values
1375
+ *
1376
+ * @since 3.0
1377
+ * @return null
1378
+ */
1379
+ updateDraftValues: function ( key, value ) {
1380
+ this.$elmt.addClass( 'ditty-editor--updates-exist' );
1381
+ if ( key ) {
1382
+ this.draftValues[key] = value;
1383
+ if ( 'development' === dittyVars.mode && window.console ) {
1384
+ console.log( 'draftValues:', this.draftValues );
1385
+ }
1386
+ return this.draftValues[key];
1387
+ } else {
1388
+ this.draftValues = value;
1389
+ if ( 'development' === dittyVars.mode && window.console ) {
1390
+ console.log( 'draftValues:', this.draftValues );
1391
+ }
1392
+ return this.draftValues;
1393
+ }
1394
+
1395
+ },
1396
+
1397
+ /**
1398
+ * Get draft values
1399
+ *
1400
+ * @since 3.0
1401
+ * @return null
1402
+ */
1403
+ getDraftValues: function ( key ) {
1404
+ if ( key ) {
1405
+ if ( this.draftValues[key] ) {
1406
+ return this.draftValues[key];
1407
+ } else {
1408
+ return false;
1409
+ }
1410
+ } else {
1411
+ return this.draftValues;
1412
+ }
1413
+ },
1414
+
1415
+ /**
1416
+ * Enable/disable delayed submit
1417
+ *
1418
+ * @since 3.0
1419
+ * @return null
1420
+ */
1421
+ delayedSubmitEnable: function () {
1422
+ this.delayedSubmit = true;
1423
+ },
1424
+ delayedSubmitDisable: function () {
1425
+ this.delayedSubmit = false;
1426
+ },
1427
+
1428
+ /**
1429
+ * Setup triggers
1430
+ *
1431
+ * @since 3.0
1432
+ * @return null
1433
+ */
1434
+ trigger: function ( fn, customParams ) {
1435
+ var params = [];
1436
+
1437
+ switch( fn ) {
1438
+ case 'active_items_update':
1439
+ params = [this.ditty, this.activeItems];
1440
+ break;
1441
+ case 'stop_live_updates':
1442
+ params = [this.dittyId];
1443
+ break;
1444
+ default:
1445
+ params = [this.settings];
1446
+ break;
1447
+ }
1448
+
1449
+ if ( customParams ) {
1450
+ params = customParams;
1451
+ }
1452
+
1453
+ this.$elmt.trigger( 'ditty_editor_' + fn, params );
1454
+ if ( typeof this.settings[fn] === 'function' ) {
1455
+ this.settings[fn].apply( this.$elmt, params );
1456
+ }
1457
+ $( 'body' ).trigger( 'ditty_' + fn, params );
1458
+ },
1459
+
1460
+ /**
1461
+ * Allow settings to be modified
1462
+ *
1463
+ * @since 3.0
1464
+ * @return null
1465
+ */
1466
+ /*
1467
+ options: function ( key, value ) {
1468
+
1469
+ if ( typeof key === 'object' ) {
1470
+ this.settings = $.extend( {}, defaults, $.ditty_editor.defaults, key );
1471
+ } else if ( typeof key === 'string' ) {
1472
+ if ( value === undefined ) {
1473
+ return this.settings[key];
1474
+ }
1475
+ this.settings[key] = value;
1476
+ } else {
1477
+ return this.settings;
1478
+ }
1479
+
1480
+ this.trigger( 'options_update' );
1481
+ },
1482
+ */
1483
+
1484
+ /**
1485
+ * Return option data for the object
1486
+ *
1487
+ * @since 3.0
1488
+ * @return value
1489
+ */
1490
+ _getPanelOption: function( key ) {
1491
+ switch( key ) {
1492
+ case 'elmnt':
1493
+ return this.$panels;
1494
+ default:
1495
+ return this.settings[key];
1496
+ }
1497
+ },
1498
+
1499
+ /**
1500
+ * Set options data for the object
1501
+ *
1502
+ * @since 3.0
1503
+ * @return null
1504
+ */
1505
+ _setPanelOption: function( key, value ) {
1506
+ if ( undefined === value ) {
1507
+ return false;
1508
+ }
1509
+ this.$panels.ditty_slider( 'options', key, value );
1510
+ this.trigger( 'update' );
1511
+ },
1512
+
1513
+ /**
1514
+ * Hook to get or set editor options
1515
+ *
1516
+ * @since 3.0
1517
+ * @return null
1518
+ */
1519
+ panelOptions: function ( key, value ) {
1520
+ var self = this;
1521
+ if ( typeof key === 'object' ) {
1522
+ $.each( key, function( k, v ) {
1523
+ self._setPanelOption( k, v );
1524
+ } );
1525
+ } else if ( typeof key === 'string' ) {
1526
+ if ( value === undefined ) {
1527
+ return self._getPanelOption( key );
1528
+ }
1529
+ self._setPanelOption( key, value );
1530
+ } else {
1531
+ return self.$panels.ditty_slider( 'options' );
1532
+ }
1533
+ },
1534
+
1535
+ /**
1536
+ * Return option data for the object
1537
+ *
1538
+ * @since 3.0
1539
+ * @return value
1540
+ */
1541
+ _getOption: function( key ) {
1542
+ switch( key ) {
1543
+ case 'elmnt':
1544
+ return this;
1545
+ default:
1546
+ return this.settings[key];
1547
+ }
1548
+ },
1549
+
1550
+ /**
1551
+ * Set options data for the object
1552
+ *
1553
+ * @since 3.0
1554
+ * @return null
1555
+ */
1556
+ _setOption: function( key, value ) {
1557
+ if ( undefined === value ) {
1558
+ return false;
1559
+ }
1560
+ this.settings[key] = value;
1561
+ this.trigger( 'update' );
1562
+ },
1563
+
1564
+ /**
1565
+ * Hook to get or set editor options
1566
+ *
1567
+ * @since 3.0
1568
+ * @return null
1569
+ */
1570
+ options: function ( key, value ) {
1571
+ var self = this;
1572
+ if ( typeof key === 'object' ) {
1573
+ $.each( key, function( k, v ) {
1574
+ self._setOption( k, v );
1575
+ } );
1576
+ } else if ( typeof key === 'string' ) {
1577
+ if ( value === undefined ) {
1578
+ return self._getOption( key );
1579
+ }
1580
+ self._setOption( key, value );
1581
+ } else {
1582
+ return self.settings;
1583
+ }
1584
+ },
1585
+
1586
+ /**
1587
+ * Destroy the editor
1588
+ *
1589
+ * @since 3.0
1590
+ * @return null
1591
+ */
1592
+ destroy: function () {
1593
+ if ( this.$panels.ditty_slider ) {
1594
+ this.$panels.ditty_slider( 'destroy' );
1595
+ }
1596
+
1597
+ $( document ).off( 'postbox-moved', { self: this }, this._postboxMoved );
1598
+ $( document ).off( 'postboxes-columnchange', { self: this }, this._postboxMoved );
1599
+ $( window ).off( 'beforeunload', { self: this }, this._beforeunload );
1600
+ this.ditty.$elmt.off( 'ditty_active_items_update', { self: this }, this._dittyItemsUpdated );
1601
+ this.ditty.$elmt.off( 'ditty_disabled_items_update', { self: this }, this._disabledItemsUpdate );
1602
+ this.$tabs.off( 'click', 'ditty-editor__tab', { self: this }, this._showPanel );
1603
+ this.$update.off( 'click', { self: this }, this._saveClick );
1604
+ this.$panels.off( 'ditty_slider_init', { self: this }, this._editorLoaded );
1605
+ this.$panels.off( 'ditty_slider_before_slide_update', { self: this }, this._beforeSlideUpdate );
1606
+ this.$panels.off( 'ditty_slider_after_slide_update', { self: this }, this._afterSlideUpdate );
1607
+ this.$panels.off( 'ditty_slider_slide_removed', { self: this }, this._slideRemoved );
1608
+
1609
+ this.trigger( 'destroy' );
1610
+ this.elmt._ditty_editor = null;
1611
+ }
1612
+ };
1613
+
1614
+ /**
1615
+ * Create the data list
1616
+ *
1617
+ * @since 3.0
1618
+ * @return null
1619
+ */
1620
+ $.fn.ditty_editor = function( options ) {
1621
+ var args = arguments,
1622
+ error = false,
1623
+ returns;
1624
+
1625
+ if ( options === undefined || typeof options === 'object' ) {
1626
+ return this.each( function () {
1627
+ if ( ! this._ditty_editor ) {
1628
+ this._ditty_editor = new Ditty_Editor( this, options );
1629
+ }
1630
+ });
1631
+ } else if ( typeof options === 'string' ) {
1632
+ this.each( function () {
1633
+ var instance = this._ditty_editor;
1634
+
1635
+ if ( ! instance ) {
1636
+ throw new Error( 'No Ditty_Editor applied to this element.' );
1637
+ }
1638
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
1639
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
1640
+ } else {
1641
+ error = true;
1642
+ }
1643
+ } );
1644
+
1645
+ if ( error ) {
1646
+ throw new Error( 'No method "' + options + '" in Ditty_Editor.' );
1647
+ }
1648
+
1649
+ return returns !== undefined ? returns : this;
1650
+ }
1651
+ };
1652
+
1653
+ $.ditty_editor = {};
1654
+ $.ditty_editor.defaults = defaults;
1655
+
1656
+ } )( jQuery );
1657
+
1658
+
1659
+ /**
1660
+ * Ditty Editor Settings Panel
1661
+ *
1662
+ * @since 3.0
1663
+ * @return null
1664
+ */
1665
+
1666
+ (function ($) {
1667
+ 'use strict';
1668
+
1669
+ var defaults = {
1670
+ editor: null
1671
+ };
1672
+
1673
+ var Ditty_Settings_Panel = function ( elmt, options ) {
1674
+ this.elmt = elmt;
1675
+ this.settings = $.extend( {}, defaults, $.ditty_settings_panel.defaults, options );
1676
+ this.$elmt = $( elmt );
1677
+ this.$form = this.$elmt.find( '.ditty-editor-options' );
1678
+ this.$title = this.$elmt.find( 'input[name="title]' );
1679
+ this.$previewBg = this.$elmt.find( 'input[name="previewBg"]' );
1680
+ this.$previewPaddingTop = this.$elmt.find( 'input[name="previewPadding[paddingTop]"]' );
1681
+ this.$previewPaddingBottom = this.$elmt.find( 'input[name="previewPadding[paddingBottom]"]' );
1682
+ this.$previewPaddingLeft = this.$elmt.find( 'input[name="previewPadding[paddingLeft]"]' );
1683
+ this.$previewPaddingRight = this.$elmt.find( 'input[name="previewPadding[paddingRight]"]' );
1684
+ this.$postTitle = $( '.ditty-post__title' );
1685
+ this.$editorPreview = $( '#ditty-editor__preview' );
1686
+ this.dittyId = this.$form.data( 'ditty_id' );
1687
+ this.initData = null;
1688
+ this.afterUpdateAction = '';
1689
+
1690
+ this._init();
1691
+ };
1692
+
1693
+
1694
+ Ditty_Settings_Panel.prototype = {
1695
+
1696
+ /**
1697
+ * Initialize the panel
1698
+ *
1699
+ * @since 3.0
1700
+ * @return null
1701
+ */
1702
+ _init: function () {
1703
+
1704
+ // Save the initial data
1705
+ this.initData = this.$form.serialize();
1706
+
1707
+ // Initialize dynamic fields
1708
+ this.settings.editor.initFields( this.$elmt );
1709
+
1710
+ // Add actions
1711
+ this.settings.editor.$elmt.on( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
1712
+ this.settings.editor.$elmt.on( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
1713
+ this.$form.on( 'submit', { self: this }, this._submitForm );
1714
+ this.$form.on( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
1715
+ this.$form.on( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
1716
+ this.$form.on( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
1717
+ this.$form.on( 'keyup change', 'input[name="title"]', { self: this }, this._titleChange );
1718
+ this.$form.on( 'keyup change', '.ditty-field--preview_settings *', { self: this }, this._previewBgChange );
1719
+
1720
+ this.$elmt.addClass( 'init' );
1721
+ },
1722
+
1723
+ /**
1724
+ * Check for updates
1725
+ *
1726
+ * @since 3.0
1727
+ * @return null
1728
+ */
1729
+ _checkUpdates: function( e ) {
1730
+ var self = e ? e.data.self : this;
1731
+ var currentData = self.$form.serialize();
1732
+ if ( currentData !== self.initData ) {
1733
+ self.settings.editor.addUpdate( 'settings', self.itemId );
1734
+ self.settings.editor.delayedSubmitEnable(); // Enable the delayed submit since we have changes
1735
+ } else {
1736
+ self.settings.editor.removeUpdate( 'settings', self.itemId );
1737
+ }
1738
+ },
1739
+
1740
+ /**
1741
+ * Listen for title changes
1742
+ *
1743
+ * @since 3.0
1744
+ * @return null
1745
+ */
1746
+ _titleChange: function( e ) {
1747
+ var self = e ? e.data.self : this;
1748
+ var title = $( e.target ).val();
1749
+ self.$postTitle.text( title );
1750
+ },
1751
+
1752
+ /**
1753
+ * Listen for the preview background change
1754
+ *
1755
+ * @since 3.0
1756
+ * @return null
1757
+ */
1758
+ _previewBgChange: function( e ) {
1759
+ var self = e ? e.data.self : this;
1760
+ var preview_css = {
1761
+ backgroundColor : self.$previewBg.val(),
1762
+ paddingTop : self.$previewPaddingTop.val(),
1763
+ paddingBottom : self.$previewPaddingBottom.val(),
1764
+ paddingLeft : self.$previewPaddingLeft.val(),
1765
+ paddingRight : self.$previewPaddingRight.val()
1766
+ };
1767
+ self.$editorPreview.css( preview_css );
1768
+ },
1769
+
1770
+ /**
1771
+ * Editor updated listener
1772
+ *
1773
+ * @since 3.0
1774
+ * @return null
1775
+ */
1776
+ _addDrafts: function( e ) {
1777
+ var self = e.data.self,
1778
+ currentData = self.$form.serialize();
1779
+
1780
+ if ( currentData !== self.initData ) {
1781
+ self.$form.trigger( 'submit' );
1782
+ }
1783
+ },
1784
+
1785
+ /**
1786
+ * Editor updated listener
1787
+ *
1788
+ * @since 3.0
1789
+ * @return null
1790
+ */
1791
+ _saveDrafts: function( e ) {
1792
+ var self = e.data.self,
1793
+ currentData = self.$form.serialize();
1794
+
1795
+ if ( currentData !== self.initData ) {
1796
+ self.afterUpdateAction = 'save';
1797
+ self.$form.trigger( 'submit' );
1798
+ }
1799
+ },
1800
+
1801
+ /**
1802
+ * Submit updates
1803
+ *
1804
+ * @since 3.0
1805
+ * @return null
1806
+ */
1807
+ _submitForm: function( e ) {
1808
+ e.preventDefault();
1809
+ var self = e.data.self,
1810
+ dittyId = self.dittyId;
1811
+
1812
+ self.settings.editor.updateStart(); // Start the update overlay
1813
+
1814
+ var data = {
1815
+ action : 'ditty_editor_settings_update',
1816
+ ditty_id : dittyId,
1817
+ draft_values : self.settings.editor.getDraftValues(),
1818
+ security : dittyVars.security
1819
+ };
1820
+ self.$form.ajaxSubmit( {
1821
+ url : dittyVars.ajaxurl,
1822
+ type : 'post',
1823
+ dataType : 'json',
1824
+ data : data,
1825
+ success : function( response ) {
1826
+ self.initData = self.$form.serialize();
1827
+ dittyDraftUpdate( self, 'settings', false, response );
1828
+ self.settings.editor.delayedSubmitDisable(); // Remove the delayed submit since we just submitted
1829
+ if ( 'save' === self.afterUpdateAction ) { // Update the ticker
1830
+ self.settings.editor.saveDitty( { return_items: 0 } );
1831
+ }
1832
+ self.afterUpdateAction = '';
1833
+ }
1834
+ } );
1835
+ },
1836
+
1837
+ /**
1838
+ * Return a specific setting
1839
+ *
1840
+ * @since 3.0
1841
+ * @return null
1842
+ */
1843
+ _options: function ( key ) {
1844
+ return this.settings[key];
1845
+ },
1846
+
1847
+ /**
1848
+ * Setup triggers
1849
+ *
1850
+ * @since 3.0
1851
+ * @return null
1852
+ */
1853
+ trigger: function ( fn, customParams ) {
1854
+ var params = [this.settings];
1855
+
1856
+ if ( customParams ) {
1857
+ params = customParams;
1858
+ }
1859
+
1860
+ this.$elmt.trigger( 'ditty_settings_panel_' + fn, params );
1861
+
1862
+ if ( typeof this.settings[fn] === 'function' ) {
1863
+ this.settings[fn].apply( this.$elmt, params );
1864
+ }
1865
+ },
1866
+
1867
+ /**
1868
+ * Allow settings to be modified
1869
+ *
1870
+ * @since 3.0
1871
+ * @return null
1872
+ */
1873
+ options: function ( key, value ) {
1874
+
1875
+ if ( typeof key === 'object' ) {
1876
+ this.settings = $.extend( {}, defaults, $.ditty_settings_panel.defaults, key );
1877
+ } else if ( typeof key === 'string' ) {
1878
+ if ( value === undefined ) {
1879
+ return this.settings[key];
1880
+ }
1881
+ this.settings[key] = value;
1882
+ } else {
1883
+ return this.settings;
1884
+ }
1885
+
1886
+ this.trigger( 'options_update' );
1887
+ },
1888
+
1889
+ /**
1890
+ * Destroy the editor
1891
+ *
1892
+ * @since 3.0
1893
+ * @return null
1894
+ */
1895
+ destroy: function () {
1896
+
1897
+ // Remove the init class
1898
+ this.$elmt.removeClass( 'init' );
1899
+
1900
+ // Remove actions
1901
+ this.settings.editor.$elmt.off( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
1902
+ this.settings.editor.$elmt.off( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
1903
+ this.$form.off( 'submit', { self: this }, this._submitForm );
1904
+ this.$form.off( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
1905
+ this.$form.off( 'keyup change', 'input[name="previewBg"]', { self: this }, this._previewBg_cahnge );
1906
+ this.$form.off( 'keyup change', 'input[name="title"]', { self: this }, this._titleChange );
1907
+ this.$form.off( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
1908
+ this.$form.off( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
1909
+
1910
+ this.trigger( 'destroy' );
1911
+ this.elmt._ditty_settings_panel = null;
1912
+ }
1913
+ };
1914
+
1915
+ /**
1916
+ * Create the data list
1917
+ *
1918
+ * @since 3.0
1919
+ * @return null
1920
+ */
1921
+ $.fn.ditty_settings_panel = function( options ) {
1922
+ var args = arguments,
1923
+ error = false,
1924
+ returns;
1925
+
1926
+ if ( options === undefined || typeof options === 'object' ) {
1927
+ return this.each( function () {
1928
+ if ( ! this._ditty_settings_panel ) {
1929
+ this._ditty_settings_panel = new Ditty_Settings_Panel( this, options );
1930
+ }
1931
+ });
1932
+ } else if ( typeof options === 'string' ) {
1933
+ this.each( function () {
1934
+ var instance = this._ditty_settings_panel;
1935
+
1936
+ if ( ! instance ) {
1937
+ throw new Error( 'No Ditty_Settings_Panel applied to this element.' );
1938
+ }
1939
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
1940
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
1941
+ } else {
1942
+ error = true;
1943
+ }
1944
+ } );
1945
+
1946
+ if ( error ) {
1947
+ throw new Error( 'No method "' + options + '" in Ditty_Settings_Panel.' );
1948
+ }
1949
+
1950
+ return returns !== undefined ? returns : this;
1951
+ }
1952
+ };
1953
+
1954
+ $.ditty_settings_panel = {};
1955
+ $.ditty_settings_panel.defaults = defaults;
1956
+
1957
+ } )( jQuery );
1958
+
1959
+
1960
+ /**
1961
+ * Ditty Editor Items Panel
1962
+ *
1963
+ * @since 3.0
1964
+ * @return null
1965
+ */
1966
+
1967
+ (function ($) {
1968
+ 'use strict';
1969
+
1970
+ var defaults = {
1971
+ editor: null
1972
+ };
1973
+
1974
+ var Ditty_Items_Panel = function ( elmt, options ) {
1975
+ this.elmt = elmt;
1976
+ this.settings = $.extend( {}, defaults, $.ditty_items_panel.defaults, options );
1977
+ this.$elmt = $( elmt );
1978
+ this.$add = $( elmt ).find( '.ditty-editor-options__add' );
1979
+ this.$contents = $( elmt ).find( '.ditty-editor__panel__contents' );
1980
+ this.$list = $( elmt ).find( '.ditty-data-list' );
1981
+ this.$listItems = $( elmt ).find( '.ditty-data-list__items' );
1982
+ this.isEmptyTicker = false;
1983
+
1984
+ this._init();
1985
+ };
1986
+
1987
+
1988
+ Ditty_Items_Panel.prototype = {
1989
+
1990
+ /**
1991
+ * Initialize the panel
1992
+ *
1993
+ * @since 3.0
1994
+ * @return null
1995
+ */
1996
+ _init: function () {
1997
+ this.$elmt.addClass( 'init' );
1998
+
1999
+ // Add actions
2000
+ this.settings.editor.$elmt.on( 'ditty_editor_aactive_items_update', { self: this }, this._dittyActiveItemsUpdated );
2001
+ this.$add.on( 'click', { self: this }, this._add_item );
2002
+ this.$elmt.on( 'click', '.ditty-data-list__item', { self: this }, this._showItem );
2003
+ this.$elmt.on( 'click', '.ditty-data-list__item__icon', { self: this }, this._editType );
2004
+ this.$elmt.on( 'click', '.ditty-data-list__item__edit', { self: this }, this._editItem );
2005
+ this.$elmt.on( 'click', '.ditty-data-list__item__layout', { self: this }, this._editLayoutVariations );
2006
+ this.$elmt.on( 'click', '.ditty-data-list__item__clone', { self: this }, this._cloneItem );
2007
+ this.$elmt.on( 'click', '.ditty-data-list__item__delete', { self: this }, this._deleteItem );
2008
+ this.$list.on( 'click', '.ditty-editor-item > a', { self: this }, this._actionClick );
2009
+ $( 'body' ).on( 'ditty_editor_save_ditty_response', { self: this }, this._dittyEditorSaveResponse );
2010
+
2011
+ // Make sure there is at least one item
2012
+ if ( 1 > this.$elmt.find( '.ditty-data-list__item' ).length ) {
2013
+ this.isEmptyTicker = true;
2014
+ this.$add.trigger( 'click' );
2015
+ }
2016
+
2017
+ // Initialize list sorting
2018
+ this._initializeSorting();
2019
+
2020
+ // Highlight the current items
2021
+ this._highlightListItems( this.settings.editor.activeItems );
2022
+ },
2023
+
2024
+ /**
2025
+ * Update new layout ids on save
2026
+ *
2027
+ * @since 3.0
2028
+ * @return null
2029
+ */
2030
+ dittyUpdateSavedDraftLayouts: function( draftId, newID ) {
2031
+ $.each( $( '.ditty-editor-item' ), function() {
2032
+ var layoutValue = $( this ).data( 'layout_value' );
2033
+ $.each( layoutValue, function( type, id ) {
2034
+ if ( String( id ) === String( draftId ) ) {
2035
+ layoutValue[type] = String( newID );
2036
+ }
2037
+ } );
2038
+ $( this ).attr( 'data-layout_value', layoutValue ).data( 'layout_value', layoutValue );
2039
+ } );
2040
+ },
2041
+
2042
+ /**
2043
+ * Update new item ids on save
2044
+ *
2045
+ * @since 3.0
2046
+ * @return null
2047
+ */
2048
+ _dittyEditorSaveResponse: function( e, response ) {
2049
+ var self = e.data.self;
2050
+ if ( response.ditty_new_item_ids ) {
2051
+ $.each( response.ditty_new_item_ids, function( draftId, newId ) {
2052
+ var $editorItem = $( '#ditty-editor-item--' + draftId );
2053
+ if ( $editorItem.length ) {
2054
+ $editorItem.attr( 'id', 'ditty-editor-item--' + newId );
2055
+ $editorItem.attr( 'data-item_id', newId ).data( 'item_id', newId );
2056
+ }
2057
+ } );
2058
+ }
2059
+ if ( response.ditty_new_layout_ids ) {
2060
+ $.each( response.ditty_new_layout_ids, function( draftId, newID ) {
2061
+ self.dittyUpdateSavedDraftLayouts( draftId, newID );
2062
+ } );
2063
+ }
2064
+ },
2065
+
2066
+ /**
2067
+ * Highlight a list item
2068
+ *
2069
+ * @since 3.0
2070
+ * @return null
2071
+ */
2072
+ _highlightListItem: function( item ) {
2073
+ var itemId = item.id + '';
2074
+ itemId = itemId.split( '_' );
2075
+ this.$elmt.find( '#ditty-editor-item--' + itemId[0] ).addClass( 'active' );
2076
+ },
2077
+
2078
+ /**
2079
+ * Loop through the active items and highlight
2080
+ *
2081
+ * @since 3.0
2082
+ * @return null
2083
+ */
2084
+ _highlightListItems: function( items ) {
2085
+ this.$elmt.find( '.ditty-data-list__item' ).removeClass( 'active' );
2086
+ var self = this;
2087
+ if ( Array.isArray( items ) ) {
2088
+ $.each( items, function( i, item ) {
2089
+ self._highlightListItem( item );
2090
+ });
2091
+ } else {
2092
+ self._highlightListItem( items );
2093
+ }
2094
+ },
2095
+
2096
+ /**
2097
+ * Update the highlighted items when active
2098
+ *
2099
+ * @since 3.0
2100
+ * @return null
2101
+ */
2102
+ _dittyActiveItemsUpdated: function( e, ditty, items ) {
2103
+ var self = e.data.self;
2104
+ self._highlightListItems( items );
2105
+ },
2106
+
2107
+ /**
2108
+ * Initialize item sorting
2109
+ *
2110
+ * @since 3.0
2111
+ * @return null
2112
+ */
2113
+ _initializeSorting: function() {
2114
+ var self = this;
2115
+ this.$listItems.sortable( {
2116
+ handle: '.ditty-data-list__item__move',
2117
+ items: '.ditty-data-list__item',
2118
+ axis: 'y',
2119
+ start: function( event, ui ) {
2120
+ var $item = $( ui.item );
2121
+ $item.addClass( 'ditty-data-list__item--moving' );
2122
+ },
2123
+ stop: function( event, ui ) {
2124
+ var $item = $( ui.item );
2125
+ $item.removeClass( 'ditty-data-list__item--moving' );
2126
+ self.settings.editor.addUpdate( 'item_order', self.settings.editor.dittyId ); // Add to the update queue
2127
+ },
2128
+ update: function() {
2129
+ self._updateItemIndexes( 'updateDitty' );
2130
+ }
2131
+ } );
2132
+ },
2133
+
2134
+ /**
2135
+ * Show a specific item
2136
+ *
2137
+ * @since 3.0
2138
+ * @return null
2139
+ */
2140
+ _showItem: function( e ) {
2141
+ e.preventDefault();
2142
+ var self = e.data.self;
2143
+ if ( ! $( e.target ).is( 'a' ) && ! $( e.target ).parent().is( 'a' ) ) {
2144
+ var $item = $( e.target ).is( '.ditty-data-list__item' ) ? $( e.target ) : $( e.target ).parents( '.ditty-data-list__item' ),
2145
+ itemId = $item.data( 'item_id' );
2146
+
2147
+ // Update the display element
2148
+ self.settings.editor.ditty.showItem( itemId );
2149
+ }
2150
+ },
2151
+
2152
+ /**
2153
+ * Trigger an actions when a button is clicked
2154
+ *
2155
+ * @since 3.0
2156
+ * @return null
2157
+ */
2158
+ _actionClick: function( e ) {
2159
+ e.preventDefault();
2160
+ var self = e.data.self,
2161
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
2162
+ $item = $button.parents( '.ditty-data-list__item' ),
2163
+ dittyId = $item.data( 'ditty_id' ),
2164
+ itemId = $item.data( 'item_id' );
2165
+
2166
+ dittyVars.editor.currentItem = $item; // Set the current item
2167
+
2168
+ $( 'body' ).trigger( 'ditty_editor_item_action_click', [$button, $item, itemId, dittyId, self.settings.editor] );
2169
+ },
2170
+
2171
+ /**
2172
+ * Edit a item type
2173
+ *
2174
+ * @since 3.0
2175
+ * @return null
2176
+ */
2177
+ _editType: function( e ) {
2178
+ e.preventDefault();
2179
+ var self = e.data.self;
2180
+
2181
+ var $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
2182
+ $item = $button.parents( '.ditty-data-list__item' );
2183
+
2184
+ $item.trigger( 'click' );
2185
+ $item.addClass( 'editing' );
2186
+ self.settings.editor.updateStart(); // Start the update overlay
2187
+ self.settings.editor.panelOptions( 'transition', 'slideRight' );
2188
+ self.settings.editor.showPanel( 'item_types' );
2189
+ },
2190
+
2191
+ /**
2192
+ * Edit a item
2193
+ *
2194
+ * @since 3.0
2195
+ * @return null
2196
+ */
2197
+ _editItem: function( e ) {
2198
+ e.preventDefault();
2199
+ var self = e.data.self;
2200
+
2201
+ var $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
2202
+ $item = $button.parents( '.ditty-data-list__item' ),
2203
+ itemId = $item.data( 'item_id' );
2204
+
2205
+ $item.trigger( 'click' );
2206
+ $item.addClass( 'editing' );
2207
+ self.settings.editor.updateStart(); // Start the update overlay
2208
+
2209
+ // var data = {
2210
+ // hook : 'ditty_editorItem_fields',
2211
+ // itemId : itemId,
2212
+ // };
2213
+ // ditty_editor_ajax( data, self );
2214
+
2215
+ // Load the item fields
2216
+ var data = {
2217
+ action : 'ditty_editor_item_fields',
2218
+ item_id : itemId,
2219
+ draft_values : self.settings.editor.getDraftValues(),
2220
+ security : dittyVars.security
2221
+ };
2222
+ $.post( dittyVars.ajaxurl, data, function( response ) {
2223
+ if ( response ) {
2224
+ var html = '<div class="ditty-editor__panel ditty-editor__panel--item_editor">' + response + '</div>';
2225
+ self.settings.editor.panelOptions( 'transition', 'slideLeft' );
2226
+ self.settings.editor.showPanel( 'item_editor', html );
2227
+ }
2228
+ } );
2229
+ },
2230
+
2231
+ // _ditty_editorItem_fields: function( e, data ) {
2232
+ // var self = e.data.self;
2233
+ // if ( data.html ) {
2234
+ // var html = '<div class="ditty-editor__panel ditty-editor__panel--item_editor">' + data.html + '</div>';
2235
+ // self.settings.editor.panelOptions( 'transition', 'slideLeft' );
2236
+ // self.settings.editor.showPanel( 'item_editor', html );
2237
+ // }
2238
+ // },
2239
+
2240
+ /**
2241
+ * Edit a item layout variation
2242
+ *
2243
+ * @since 3.0
2244
+ * @return null
2245
+ */
2246
+ _editLayoutVariations: function( e ) {
2247
+ e.preventDefault();
2248
+ var self = e.data.self;
2249
+
2250
+ var $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
2251
+ $item = $button.parents( '.ditty-data-list__item' ),
2252
+ itemType = $item.data( 'item_type' ),
2253
+ layoutValue = $item.data( 'layout_value' ),
2254
+ itemLabel = $item.find( '.ditty-data-list__item__label' ).html();
2255
+
2256
+ $item.trigger( 'click' );
2257
+ $item.addClass( 'editing' );
2258
+ self.settings.editor.updateStart(); // Start the update overlay
2259
+
2260
+ // Load the item fields
2261
+ var data = {
2262
+ action : 'ditty_editor_layout_variations',
2263
+ ditty_id : self.settings.editor.dittyId,
2264
+ item_type : itemType,
2265
+ item_label : itemLabel,
2266
+ layout_value : layoutValue,
2267
+ draft_values : self.settings.editor.getDraftValues(),
2268
+ security : dittyVars.security
2269
+ };
2270
+ $.post( dittyVars.ajaxurl, data, function( response ) {
2271
+ if ( response ) {
2272
+ var html = '<div class="ditty-editor__panel ditty-editor__panel--layout-variations">' + response + '</div>';
2273
+ self.settings.editor.panelOptions( 'transition', 'slideLeft' );
2274
+ self.settings.editor.showPanel( 'layout_variations', html );
2275
+ }
2276
+ } );
2277
+ },
2278
+
2279
+ /**
2280
+ * Add a new item
2281
+ *
2282
+ * @since 3.0
2283
+ * @return null
2284
+ */
2285
+ _add_item: function( e ) {
2286
+ e.preventDefault();
2287
+ var self = e.data.self,
2288
+ dittyId = self.settings.editor.dittyId;
2289
+
2290
+ //self.settings.editor.updateStart(); // Start the update overlay
2291
+
2292
+ // Load the new display fields
2293
+ var data = {
2294
+ action : 'ditty_editor_item_add',
2295
+ ditty_id : dittyId,
2296
+ draft_values : self.settings.editor.getDraftValues(),
2297
+ security : dittyVars.security
2298
+ };
2299
+ $.post( dittyVars.ajaxurl, data, function( response ) {
2300
+ if ( response.display_items ) {
2301
+ if ( self.isEmptyTicker ) {
2302
+ var placeholderItems = self.settings.editor.ditty.options( 'items' );
2303
+ $.each( placeholderItems, function( index, data ) {
2304
+ self.settings.editor.ditty.deleteItem( data.id );
2305
+ } );
2306
+ self.isEmptyTicker = false;
2307
+ }
2308
+ $.each( response.display_items, function( key, value ) {
2309
+ self.settings.editor.ditty.addItem( value, 0 );
2310
+ } );
2311
+ }
2312
+ if ( response.editor_item ) {
2313
+ var $new = $( response.editor_item );
2314
+ $new.hide();
2315
+ self.$listItems.prepend( $new );
2316
+ $new.slideDown();
2317
+ self._updateItemIndexes();
2318
+ //self.settings.editor.addUpdate( 'item_add', value.id ); // Add to the update queue
2319
+ }
2320
+ if ( response.draft_id && response.draft_data ) {
2321
+ dittyDraftItemUpdateData( self, response.draft_id, null, response.draft_data );
2322
+ }
2323
+ if ( response.draft_id && response.draft_meta ) {
2324
+ dittyDraftItemUpdateMeta( self, response.draft_id, null, response.draft_meta );
2325
+ }
2326
+ //.settings.editor.updateStop(); // Stop the update overlay
2327
+ }, 'json' );
2328
+ },
2329
+
2330
+ /**
2331
+ * Clone a item
2332
+ *
2333
+ * @since 3.0
2334
+ * @return null
2335
+ */
2336
+ _cloneItem: function( e ) {
2337
+ e.preventDefault();
2338
+ var self = e.data.self,
2339
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
2340
+ $item = $button.parents( '.ditty-data-list__item' ),
2341
+ itemId = $item.data( 'item_id' );
2342
+
2343
+ self.settings.editor.updateStart(); // Start the update overlay
2344
+
2345
+ // Load the new display fields
2346
+ var data = {
2347
+ action : 'ditty_editor_item_clone',
2348
+ item_id : itemId,
2349
+ draft_values : self.settings.editor.getDraftValues(),
2350
+ security : dittyVars.security
2351
+ };
2352
+ $.post( dittyVars.ajaxurl, data, function( response ) {
2353
+ if ( response.display_items && response.display_items.length ) {
2354
+ self.settings.editor.ditty.updateItems( response.display_items, itemId, 'after' );
2355
+ }
2356
+ if ( response.editor_item ) {
2357
+ var $new = $( response.editor_item );
2358
+ $new.hide();
2359
+ $item.after( $new );
2360
+ $new.slideDown();
2361
+ self._updateItemIndexes();
2362
+ }
2363
+ if ( response.draft_id && response.draft_data ) {
2364
+ dittyDraftItemUpdateData( self, response.draft_id, null, response.draft_data );
2365
+ }
2366
+ if ( response.draft_id && response.draft_meta ) {
2367
+ dittyDraftItemUpdateMeta( self, response.draft_id, null, response.draft_meta );
2368
+ }
2369
+ self.settings.editor.updateStop(); // Stop the update overlay
2370
+ }, 'json' );
2371
+ },
2372
+
2373
+ /**
2374
+ * Delete a item
2375
+ *
2376
+ * @since 3.0
2377
+ * @return null
2378
+ */
2379
+ _deleteItem: function( e ) {
2380
+ e.preventDefault();
2381
+ var self = e.data.self,
2382
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
2383
+ $item = $button.parents( '.ditty-data-list__item' ),
2384
+ itemId = $item.data( 'item_id' );
2385
+
2386
+ if ( 1 >= self.$elmt.find( '.ditty-data-list__item' ).length ) {
2387
+ self.$add.trigger( 'click' );
2388
+ }
2389
+
2390
+ // Remove the item from the editor and ditty
2391
+ $item.slideUp( function() {
2392
+ $( this ).remove();
2393
+ } );
2394
+ self.settings.editor.ditty.deleteItem( itemId );
2395
+ dittyDraftItemDelete( self, itemId ); // Remove the draft data
2396
+ },
2397
+
2398
+ /**
2399
+ * Update the item order
2400
+ *
2401
+ * @since 3.0
2402
+ * @return null
2403
+ */
2404
+ _updateItemIndexes: function( action ) {
2405
+ var self = this,
2406
+ itemIds = [];
2407
+
2408
+ this.$elmt.find( '.ditty-data-list__item' ).each( function( index ) {
2409
+ var itemId = $( this ).data( 'item_id' );
2410
+ itemIds.push( itemId );
2411
+ dittyDraftItemUpdateData( self, itemId, 'item_index', index );
2412
+ } );
2413
+
2414
+ if ( 'updateDitty' === action ) {
2415
+ // Update the ditty with the new order
2416
+ var reorderedItems = dittyItemsReorder( self.settings.editor.ditty.options( 'items' ), itemIds );
2417
+ self.settings.editor.ditty.options( 'items', reorderedItems );
2418
+ }
2419
+ },
2420
+
2421
+ /**
2422
+ * Do actions when panel is visible
2423
+ *
2424
+ * @since 3.0
2425
+ * @return null
2426
+ */
2427
+ panelVisible: function () {
2428
+ this.$elmt.find( '.ditty-data-list__item' ).removeClass( 'editing' );
2429
+ },
2430
+
2431
+ /**
2432
+ * Return a specific setting
2433
+ *
2434
+ * @since 3.0
2435
+ * @return null
2436
+ */
2437
+ _options: function ( key ) {
2438
+ return this.settings[key];
2439
+ },
2440
+
2441
+ /**
2442
+ * Setup triggers
2443
+ *
2444
+ * @since 3.0
2445
+ * @return null
2446
+ */
2447
+ trigger: function ( fn, customParams ) {
2448
+ var params = [this.settings];
2449
+
2450
+ if ( customParams ) {
2451
+ params = customParams;
2452
+ }
2453
+
2454
+ this.$elmt.trigger( 'ditty_items_panel_' + fn, params );
2455
+
2456
+ if ( typeof this.settings[fn] === 'function' ) {
2457
+ this.settings[fn].apply( this.$elmt, params );
2458
+ }
2459
+ },
2460
+
2461
+ /**
2462
+ * Allow settings to be modified
2463
+ *
2464
+ * @since 3.0
2465
+ * @return null
2466
+ */
2467
+ options: function ( key, value ) {
2468
+
2469
+ if ( typeof key === 'object' ) {
2470
+ this.settings = $.extend( {}, defaults, $.ditty_items_panel.defaults, key );
2471
+ } else if ( typeof key === 'string' ) {
2472
+ if ( value === undefined ) {
2473
+ return this.settings[key];
2474
+ }
2475
+ this.settings[key] = value;
2476
+ } else {
2477
+ return this.settings;
2478
+ }
2479
+
2480
+ this.trigger( 'options_update' );
2481
+ },
2482
+
2483
+ /**
2484
+ * Destroy the editor
2485
+ *
2486
+ * @since 3.0
2487
+ * @return null
2488
+ */
2489
+ destroy: function () {
2490
+
2491
+ // Remove the init class
2492
+ this.$elmt.removeClass( 'init' );
2493
+
2494
+ // Remove actions
2495
+ this.settings.editor.$elmt.off( 'ditty_editor_active_items_update', { self: this }, this._dittyActiveItemsUpdated );
2496
+ this.$add.off( 'click', { self: this }, this._add_item );
2497
+ this.$elmt.off( 'click', '.ditty-data-list__item', { self: this }, this._showItem );
2498
+ this.$elmt.off( 'click', '.ditty-data-list__item__icon', { self: this }, this._editType );
2499
+ this.$elmt.off( 'click', '.ditty-data-list__item__edit', { self: this }, this._editItem );
2500
+ this.$elmt.off( 'click', '.ditty-data-list__item__layout', { self: this }, this._editLayoutVariations );
2501
+ this.$elmt.off( 'click', '.ditty-data-list__item__clone', { self: this }, this._cloneItem );
2502
+ this.$elmt.off( 'click', '.ditty-data-list__item__delete', { self: this }, this._deleteItem );
2503
+ this.$list.off( 'click', '.ditty-editor-item > a', { self: this }, this._actionClick );
2504
+ $( 'body' ).off( 'ditty_editor_save_ditty_response', { self: this }, this._dittyEditorSaveResponse );
2505
+
2506
+ this.trigger( 'destroy' );
2507
+ this.elmt._ditty_items_panel = null;
2508
+ }
2509
+ };
2510
+
2511
+ /**
2512
+ * Create the data list
2513
+ *
2514
+ * @since 3.0
2515
+ * @return null
2516
+ */
2517
+ $.fn.ditty_items_panel = function( options ) {
2518
+ var args = arguments,
2519
+ error = false,
2520
+ returns;
2521
+
2522
+ if ( options === undefined || typeof options === 'object' ) {
2523
+ return this.each( function () {
2524
+ if ( ! this._ditty_items_panel ) {
2525
+ this._ditty_items_panel = new Ditty_Items_Panel( this, options );
2526
+ }
2527
+ });
2528
+ } else if ( typeof options === 'string' ) {
2529
+ this.each( function () {
2530
+ var instance = this._ditty_items_panel;
2531
+
2532
+ if ( ! instance ) {
2533
+ throw new Error( 'No Ditty_Items_Panel applied to this element.' );
2534
+ }
2535
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
2536
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
2537
+ } else {
2538
+ error = true;
2539
+ }
2540
+ } );
2541
+
2542
+ if ( error ) {
2543
+ throw new Error( 'No method "' + options + '" in Ditty_Items_Panel.' );
2544
+ }
2545
+
2546
+ return returns !== undefined ? returns : this;
2547
+ }
2548
+ };
2549
+
2550
+ $.ditty_items_panel = {};
2551
+ $.ditty_items_panel.defaults = defaults;
2552
+
2553
+ } )( jQuery );
2554
+
2555
+
2556
+ /**
2557
+ * Ditty Editor
2558
+ *
2559
+ * @since 3.0
2560
+ * @return null
2561
+ */
2562
+
2563
+ (function ($) {
2564
+ 'use strict';
2565
+
2566
+ var defaults = {
2567
+ editor: null
2568
+ };
2569
+
2570
+ var Ditty_Item_Types_Panel = function ( elmt, options ) {
2571
+
2572
+ this.elmt = elmt;
2573
+ this.settings = $.extend( {}, defaults, $.ditty_item_types_panel.defaults, options );
2574
+ this.$elmt = $( elmt );
2575
+ this.$back = this.$elmt.find( '.ditty-editor-options__back' );
2576
+ this.$editorItem = this.settings.editor.$panels.find( '.ditty-editor__panel--items' ).find( '.ditty-data-list__item.editing' );
2577
+ this.editorDittyId = this.$editorItem.data( 'ditty_id' );
2578
+ this.editorItemId = this.$editorItem.data( 'item_id' );
2579
+ this.currentType = null;
2580
+
2581
+ this._init();
2582
+ };
2583
+
2584
+
2585
+ Ditty_Item_Types_Panel.prototype = {
2586
+
2587
+ /**
2588
+ * Initialize the data list
2589
+ *
2590
+ * @since 3.0
2591
+ * @return null
2592
+ */
2593
+ _init: function () {
2594
+ this.$elmt.addClass( 'init' );
2595
+
2596
+ // Initialize dynamic fields
2597
+ this.settings.editor.initFields( this.$elmt );
2598
+
2599
+ // Add actions
2600
+ this.$back.on( 'click', { self: this }, this._backClick );
2601
+ this.$elmt.on( 'click', '.ditty-editor-item-type', { self: this }, this._typeClick );
2602
+
2603
+ this.panelVisible();
2604
+ },
2605
+
2606
+ /**
2607
+ * Return to the item list
2608
+ *
2609
+ * @since 3.0
2610
+ * @return null
2611
+ */
2612
+ _showItemsList: function() {
2613
+ this.settings.editor.panelOptions( 'transition', 'slideLeft' );
2614
+ this.settings.editor.showPanel( 'items' );
2615
+ },
2616
+
2617
+ /**
2618
+ * Cancel click
2619
+ *
2620
+ * @since 3.0
2621
+ * @return null
2622
+ */
2623
+ _backClick: function( e ) {
2624
+ e.preventDefault();
2625
+ var self = e.data.self;
2626
+ self._showItemsList();
2627
+ },
2628
+
2629
+ /**
2630
+ * Select a new type
2631
+ *
2632
+ * @since 3.0
2633
+ * @return null
2634
+ */
2635
+ _typeClick: function( e ) {
2636
+ e.preventDefault();
2637
+
2638
+ var self = e.data.self,
2639
+ $item = $( e.target ).is( '.ditty-editor-item-type' ) ? $( e.target ) : $( e.target ).parents( '.ditty-editor-item-type' ),
2640
+ itemType = $item.data( 'item_type' );
2641
+
2642
+ if ( itemType === self.currentType ) {
2643
+ self._showItemsList(); // Show the display list
2644
+ } else {
2645
+
2646
+ self.settings.editor.updateStart(); // Start the update overlay
2647
+ //dittyDraftItemUpdateData( self, self.editorItemId, 'item_type', itemType );
2648
+
2649
+ var data = {
2650
+ action : 'ditty_editor_item_type_update',
2651
+ item_id : self.editorItemId,
2652
+ item_type : itemType,
2653
+ draft_values : self.settings.editor.getDraftValues(),
2654
+ security : dittyVars.security
2655
+ };
2656
+ $.post( dittyVars.ajaxurl, data, function( response ) {
2657
+ if ( response.display_items ) {
2658
+ self.settings.editor.ditty.updateItems( response.display_items, self.editorItemId );
2659
+ }
2660
+ if ( response.editor_item ) {
2661
+ var $editorItem = $( response.editor_item );
2662
+ self.$editorItem.after( $editorItem );
2663
+ self.$editorItem.remove();
2664
+ self.$editorItem = $editorItem;
2665
+ }
2666
+ if ( response.draft_id && response.draft_data ) {
2667
+ dittyDraftItemUpdateData( self, response.draft_id, null, response.draft_data );
2668
+ }
2669
+ self._showItemsList(); // Show the display list
2670
+ self.settings.editor.updateStop(); // Stop the update overlay
2671
+ }, 'json' );
2672
+ }
2673
+ },
2674
+
2675
+ /**
2676
+ * Do actions when panel is visible
2677
+ *
2678
+ * @since 3.0
2679
+ * @return null
2680
+ */
2681
+ panelVisible: function () {
2682
+ this.$editorItem = this.settings.editor.$panels.find( '.ditty-editor__panel--items' ).find( '.ditty-data-list__item.editing' );
2683
+ this.editorDittyId = this.$editorItem.data( 'ditty_id' );
2684
+ this.editorItemId = this.$editorItem.data( 'item_id' );
2685
+ this.currentType = this.$editorItem.data( 'item_type' );
2686
+
2687
+ this.$elmt.find( '.ditty-editor-item-type' ).removeClass( 'active' );
2688
+ this.$elmt.find( '.ditty-editor-item-type[data-itemType="' + this.currentType + '"]' ).addClass( 'active' );
2689
+ },
2690
+
2691
+ /**
2692
+ * Do actions when panel is hidden
2693
+ *
2694
+ * @since 3.0
2695
+ * @return null
2696
+ */
2697
+ panelHidden: function () {
2698
+ var $editorItemIcon = this.$editorItem.find( '.ditty-data-list__item__icon' ).children( 'i' );
2699
+ $editorItemIcon.attr( 'class', $editorItemIcon.data( 'class' ) );
2700
+ },
2701
+
2702
+ /**
2703
+ * Return a specific setting
2704
+ *
2705
+ * @since 3.0
2706
+ * @return null
2707
+ */
2708
+ _options: function ( key ) {
2709
+ return this.settings[key];
2710
+ },
2711
+
2712
+ /**
2713
+ * Setup triggers
2714
+ *
2715
+ * @since 3.0
2716
+ * @return null
2717
+ */
2718
+ trigger: function ( fn, customParams ) {
2719
+ var params = [this.settings];
2720
+ if ( customParams ) {
2721
+ params = customParams;
2722
+ }
2723
+
2724
+ this.$elmt.trigger( 'ditty_item_types_panel_' + fn, params );
2725
+
2726
+ if ( typeof this.settings[fn] === 'function' ) {
2727
+ this.settings[fn].apply( this.$elmt, params );
2728
+ }
2729
+ },
2730
+
2731
+ /**
2732
+ * Allow settings to be modified
2733
+ *
2734
+ * @since 3.0
2735
+ * @return null
2736
+ */
2737
+ options: function ( key, value ) {
2738
+
2739
+ if ( typeof key === 'object' ) {
2740
+ this.settings = $.extend( {}, defaults, $.ditty_item_types_panel.defaults, key );
2741
+ } else if ( typeof key === 'string' ) {
2742
+ if ( value === undefined ) {
2743
+ return this.settings[key];
2744
+ }
2745
+ this.settings[key] = value;
2746
+ } else {
2747
+ return this.settings;
2748
+ }
2749
+
2750
+ this.trigger( 'options_update' );
2751
+ },
2752
+
2753
+ /**
2754
+ * Destroy the editor
2755
+ *
2756
+ * @since 3.0
2757
+ * @return null
2758
+ */
2759
+ destroy: function () {
2760
+
2761
+ // Remove the init class
2762
+ this.$elmt.removeClass( 'init' );
2763
+
2764
+ // Remove actions
2765
+ this.$back.off( 'click', { self: this }, this._backClick );
2766
+ this.$elmt.off( 'click', '.ditty-editor-item-type', { self: this }, this._typeClick );
2767
+
2768
+ this.trigger( 'destroy' );
2769
+ this.elmt._ditty_item_types_panel = null;
2770
+ }
2771
+ };
2772
+
2773
+ /**
2774
+ * Create the data list
2775
+ *
2776
+ * @since 3.0
2777
+ * @return null
2778
+ */
2779
+ $.fn.ditty_item_types_panel = function( options ) {
2780
+ var args = arguments,
2781
+ error = false,
2782
+ returns;
2783
+
2784
+ if ( options === undefined || typeof options === 'object' ) {
2785
+ return this.each( function () {
2786
+ if ( ! this._ditty_item_types_panel ) {
2787
+ this._ditty_item_types_panel = new Ditty_Item_Types_Panel( this, options );
2788
+ }
2789
+ });
2790
+ } else if ( typeof options === 'string' ) {
2791
+ this.each( function () {
2792
+ var instance = this._ditty_item_types_panel;
2793
+
2794
+ if ( ! instance ) {
2795
+ throw new Error( 'No Ditty_Item_Types_Panel applied to this element.' );
2796
+ }
2797
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
2798
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
2799
+ } else {
2800
+ error = true;
2801
+ }
2802
+ } );
2803
+
2804
+ if ( error ) {
2805
+ throw new Error( 'No method "' + options + '" in Ditty_Item_Types_Panel.' );
2806
+ }
2807
+
2808
+ return returns !== undefined ? returns : this;
2809
+ }
2810
+ };
2811
+
2812
+ $.ditty_item_types_panel = {};
2813
+ $.ditty_item_types_panel.defaults = defaults;
2814
+
2815
+ } )( jQuery );
2816
+
2817
+
2818
+ /**
2819
+ * Ditty Editor
2820
+ *
2821
+ * @since 3.0
2822
+ * @return null
2823
+ */
2824
+
2825
+ (function ($) {
2826
+ 'use strict';
2827
+
2828
+ var defaults = {
2829
+ editor: null
2830
+ };
2831
+
2832
+ var Ditty_Item_Editor_Panel = function ( elmt, options ) {
2833
+
2834
+ this.elmt = elmt;
2835
+ this.settings = $.extend( {}, defaults, $.ditty_item_editor_panel.defaults, options );
2836
+ this.$elmt = $( elmt );
2837
+ this.$form = this.$elmt.find( '.ditty-editor-options' );
2838
+ this.$back = this.$elmt.find( '.ditty-editor-options__back' );
2839
+ this.$preview = this.$elmt.find( '.ditty-editor-options__preview' );
2840
+ this.$title = this.$elmt.find( '.ditty-editor-options__title' );
2841
+ this.itemId = this.$form.data( 'item_id' );
2842
+ this.itemType = this.$form.data( 'item_type' );
2843
+ this.dittyId = this.$form.data( 'ditty_id' );
2844
+ this.$editorItem = this.settings.editor.$panels.find( '.ditty-editor__panel--items' ).find( '.ditty-data-list__item.editing' );
2845
+ this.$editorItemTitle = this.$editorItem.find( '.ditty-data-list__item__label' );
2846
+ this.initData = null;
2847
+ this.afterUpdateAction = '';
2848
+
2849
+ this._init();
2850
+ };
2851
+
2852
+
2853
+ Ditty_Item_Editor_Panel.prototype = {
2854
+
2855
+ /**
2856
+ * Initialize the data list
2857
+ *
2858
+ * @since 3.0
2859
+ * @return null
2860
+ */
2861
+ _init: function () {
2862
+
2863
+ // Save the initial data
2864
+ this.initData = this.$form.serialize();
2865
+
2866
+ // Initialize dynamic fields
2867
+ this.settings.editor.initFields( this.$elmt );
2868
+
2869
+ // Add actions
2870
+ this.settings.editor.$elmt.on( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
2871
+ this.settings.editor.$elmt.on( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
2872
+ this.$form.on( 'submit', { self: this }, this._submitForm );
2873
+ this.$back.on( 'click', { self: this }, this._backClick );
2874
+ this.$preview.on( 'click', { self: this }, this._previewClick );
2875
+ this.$form.on( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
2876
+ this.$form.on( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
2877
+ this.$form.on( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
2878
+ this.$form.on( 'ditty_field_update', '.ditty-field__input', { self: this }, this._checkUpdates );
2879
+ },
2880
+
2881
+ /**
2882
+ * Return to the item list
2883
+ *
2884
+ * @since 3.0
2885
+ * @return null
2886
+ */
2887
+ _showItemList: function() {
2888
+ this.settings.editor.$panels.ditty_slider( 'options', 'transition', 'slideRight' );
2889
+ this.settings.editor.$panels.ditty_slider( 'showSlideById', 'items' );
2890
+ },
2891
+
2892
+ /**
2893
+ * Preview button add updates class
2894
+ *
2895
+ * @since 3.0
2896
+ * @return null
2897
+ */
2898
+ _enablePreviewButton: function() {
2899
+ this.$preview.addClass( 'ditty-has-updates' );
2900
+ },
2901
+
2902
+ /**
2903
+ * Preview button remove updates class
2904
+ *
2905
+ * @since 3.0
2906
+ * @return null
2907
+ */
2908
+ _disablePreviewButton: function() {
2909
+ this.$preview.removeClass( 'ditty-has-updates' );
2910
+ this.$preview.children( 'i' ).attr( 'class', this.$preview.children( 'i' ).data( 'class' ) );
2911
+ },
2912
+
2913
+ /**
2914
+ * Check for updates
2915
+ *
2916
+ * @since 3.0
2917
+ * @return null
2918
+ */
2919
+ _checkUpdates: function( e ) {
2920
+ var self = e ? e.data.self : this;
2921
+ var currentData = self.$form.serialize();
2922
+ if ( currentData !== self.initData ) {
2923
+ self._enablePreviewButton();
2924
+ self.settings.editor.addUpdate( 'item_settings', self.itemId );
2925
+ self.settings.editor.delayedSubmitEnable(); // Enable the delayed submit since we have changes
2926
+ } else {
2927
+ self._disablePreviewButton();
2928
+ self.settings.editor.removeUpdate( 'item_settings', self.itemId );
2929
+ }
2930
+ },
2931
+
2932
+ /**
2933
+ * Editor tabs listener
2934
+ *
2935
+ * @since 3.0
2936
+ * @return null
2937
+ */
2938
+ _addDrafts: function( e ) {
2939
+ var self = e.data.self,
2940
+ currentData = self.$form.serialize();
2941
+
2942
+ if ( currentData !== self.initData ) {
2943
+ self.$form.trigger( 'submit' );
2944
+ }
2945
+ },
2946
+
2947
+ /**
2948
+ * Editor updated listener
2949
+ *
2950
+ * @since 3.0
2951
+ * @return null
2952
+ */
2953
+ _saveDrafts: function( e ) {
2954
+ var self = e.data.self,
2955
+ currentData = self.$form.serialize();
2956
+
2957
+ if ( currentData !== self.initData ) {
2958
+ self.afterUpdateAction = 'save';
2959
+ self.$form.trigger( 'submit' );
2960
+ }
2961
+ },
2962
+
2963
+ /**
2964
+ * Back click
2965
+ *
2966
+ * @since 3.0
2967
+ * @return null
2968
+ */
2969
+ _backClick: function( e ) {
2970
+ e.preventDefault();
2971
+ var self = e.data.self,
2972
+ currentData = self.$form.serialize();
2973
+
2974
+ if ( currentData === self.initData ) {
2975
+ self._showItemList();
2976
+ } else {
2977
+ self.afterUpdateAction = 'return';
2978
+ self.$form.trigger( 'submit' );
2979
+ }
2980
+ },
2981
+
2982
+ /**
2983
+ * Preview any changes
2984
+ *
2985
+ * @since 3.0
2986
+ * @return null
2987
+ */
2988
+ _previewClick: function( e ) {
2989
+ e.preventDefault();
2990
+ var self = e.data.self,
2991
+ currentData = self.$form.serialize();
2992
+
2993
+ if ( currentData !== self.initData ) {
2994
+ self.$preview.children( 'i' ).attr( 'class', dittyVars.updateIcon );
2995
+ self.$form.trigger( 'submit' );
2996
+ }
2997
+ },
2998
+
2999
+ /**
3000
+ * Submit updates
3001
+ *
3002
+ * @since 3.0
3003
+ * @return null
3004
+ */
3005
+ _submitForm: function( e ) {
3006
+ e.preventDefault();
3007
+ var self = e.data.self,
3008
+ itemId = self.itemId;
3009
+
3010
+ self.settings.editor.updateStart(); // Start the update overlay
3011
+
3012
+ var data = {
3013
+ action : 'ditty_editor_item_update',
3014
+ item_id : itemId,
3015
+ draft_values : self.settings.editor.getDraftValues(),
3016
+ security : dittyVars.security
3017
+ };
3018
+ self.$form.ajaxSubmit( {
3019
+ url : dittyVars.ajaxurl,
3020
+ type : 'post',
3021
+ dataType : 'json',
3022
+ data : data,
3023
+ error : function() {
3024
+ },
3025
+ success : function( response ) {
3026
+ if ( response.value_updates ) {
3027
+ self._updateValues( response.value_updates );
3028
+ }
3029
+ self.initData = self.$form.serialize();
3030
+ self._disablePreviewButton();
3031
+
3032
+ if ( response.display_items ) {
3033
+ self.settings.editor.ditty.updateItems( response.display_items, itemId );
3034
+ }
3035
+ if ( response.editor_item ) {
3036
+ var $item = $( response.editor_item ),
3037
+ itemTitle = $item.children( '.ditty-data-list__item__label' ).text();
3038
+
3039
+ // Set the new titles
3040
+ self.$title.html( itemTitle );
3041
+ self.$editorItemTitle.html( itemTitle );
3042
+ }
3043
+ if ( response.draft_id && response.draft_data ) {
3044
+ dittyDraftItemUpdateData( self, response.draft_id, null, response.draft_data );
3045
+ }
3046
+ if ( response.draft_id && response.draft_meta ) {
3047
+ dittyDraftItemUpdateMeta( self, response.draft_id, null, response.draft_meta );
3048
+ }
3049
+
3050
+ self.settings.editor.updateStop(); // Stop the update overlay
3051
+ self.settings.editor.delayedSubmitDisable(); // Remove the delayed submit since we just submitted
3052
+
3053
+ // Show the items list
3054
+ if ( 'return' === self.afterUpdateAction ) {
3055
+ self._showItemList();
3056
+ }
3057
+ // Update the Ditty
3058
+ if ( 'save' === self.afterUpdateAction ) {
3059
+ self.settings.editor.saveDitty( { return_items: 0 } );
3060
+ }
3061
+ self.afterUpdateAction = '';
3062
+ }
3063
+ } );
3064
+ },
3065
+
3066
+ /**
3067
+ * Update field values
3068
+ *
3069
+ * @since 3.0
3070
+ * @return null
3071
+ */
3072
+ _updateValues: function ( data ) {
3073
+ var self = this;
3074
+ $.each( data, function( key, value ) {
3075
+ var $element = self.$form.find( '[name="' + key + '"]' );
3076
+ if ( $element.length ) {
3077
+ $element.val( value );
3078
+ }
3079
+ } );
3080
+ },
3081
+
3082
+ /**
3083
+ * Return a specific setting
3084
+ *
3085
+ * @since 3.0
3086
+ * @return null
3087
+ */
3088
+ _options: function ( key ) {
3089
+ return this.settings[key];
3090
+ },
3091
+
3092
+ /**
3093
+ * Setup triggers
3094
+ *
3095
+ * @since 3.0
3096
+ * @return null
3097
+ */
3098
+ trigger: function ( fn, customParams ) {
3099
+ var params = [this.settings];
3100
+
3101
+ if ( customParams ) {
3102
+ params = customParams;
3103
+ }
3104
+
3105
+ this.$elmt.trigger( 'ditty_item_editor_panel_' + fn, params );
3106
+
3107
+ if ( typeof this.settings[fn] === 'function' ) {
3108
+ this.settings[fn].apply( this.$elmt, params );
3109
+ }
3110
+ },
3111
+
3112
+ /**
3113
+ * Allow settings to be modified
3114
+ *
3115
+ * @since 3.0
3116
+ * @return null
3117
+ */
3118
+ options: function ( key, value ) {
3119
+
3120
+ if ( typeof key === 'object' ) {
3121
+ this.settings = $.extend( {}, defaults, $.ditty_item_editor_panel.defaults, key );
3122
+ } else if ( typeof key === 'string' ) {
3123
+ if ( value === undefined ) {
3124
+ return this.settings[key];
3125
+ }
3126
+ this.settings[key] = value;
3127
+ } else {
3128
+ return this.settings;
3129
+ }
3130
+
3131
+ this.trigger( 'options_update' );
3132
+ },
3133
+
3134
+ /**
3135
+ * Destroy the editor
3136
+ *
3137
+ * @since 3.0
3138
+ * @return null
3139
+ */
3140
+ destroy: function () {
3141
+
3142
+ // Remove listeners
3143
+ this.settings.editor.$elmt.off( 'ditty_editor_add_drafts', { self: this }, this._saveDrafts );
3144
+ this.settings.editor.$elmt.off( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
3145
+ this.$form.off( 'submit', { self: this }, this._submitForm );
3146
+ this.$back.off( 'click', { self: this }, this._backClick );
3147
+ this.$preview.off( 'click', { self: this }, this._previewClick );
3148
+ this.$form.off( 'keyup change', 'input[type="text"], input[type="number"], textarea, select', { self: this }, this._checkUpdates );
3149
+ this.$form.off( 'click', 'input[type="radio"], input[type="checkbox"]', { self: this }, this._checkUpdates );
3150
+ this.$form.off( 'ditty_input_wysiwyg_update', '.ditty-input--wysiwyg', { self: this }, this._checkUpdates );
3151
+ this.$form.off( 'ditty_field_update', '.ditty-field__input', { self: this }, this._checkUpdates );
3152
+
3153
+ this.elmt._ditty_item_editor_panel = null;
3154
+ }
3155
+ };
3156
+
3157
+ /**
3158
+ * Create the data list
3159
+ *
3160
+ * @since 3.0
3161
+ * @return null
3162
+ */
3163
+ $.fn.ditty_item_editor_panel = function( options ) {
3164
+ var args = arguments,
3165
+ error = false,
3166
+ returns;
3167
+
3168
+ if ( options === undefined || typeof options === 'object' ) {
3169
+ return this.each( function () {
3170
+ if ( ! this._ditty_item_editor_panel ) {
3171
+ this._ditty_item_editor_panel = new Ditty_Item_Editor_Panel( this, options );
3172
+ }
3173
+ });
3174
+ } else if ( typeof options === 'string' ) {
3175
+ this.each( function () {
3176
+ var instance = this._ditty_item_editor_panel;
3177
+
3178
+ if ( ! instance ) {
3179
+ throw new Error( 'No Ditty_Item_Editor_Panel applied to this element.' );
3180
+ }
3181
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
3182
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
3183
+ } else {
3184
+ error = true;
3185
+ }
3186
+ } );
3187
+
3188
+ if ( error ) {
3189
+ throw new Error( 'No method "' + options + '" in Ditty_Item_Editor_Panel.' );
3190
+ }
3191
+
3192
+ return returns !== undefined ? returns : this;
3193
+ }
3194
+ };
3195
+
3196
+ $.ditty_item_editor_panel = {};
3197
+ $.ditty_item_editor_panel.defaults = defaults;
3198
+
3199
+ } )( jQuery );
3200
+
3201
+
3202
+ /**
3203
+ * Ditty Displays Panel
3204
+ *
3205
+ * @since 3.0
3206
+ * @return null
3207
+ */
3208
+ ( function ( $ ) {
3209
+ 'use strict';
3210
+
3211
+ var defaults = {
3212
+ editor: null
3213
+ };
3214
+
3215
+ var Ditty_Displays_Panel = function ( elmt, options ) {
3216
+ this.elmt = elmt;
3217
+ this.settings = $.extend( {}, defaults, $.ditty_displays_panel.defaults, options );
3218
+ this.$elmt = $( elmt );
3219
+ this.$list = $( elmt ).find( '.ditty-data-list__items' );
3220
+ this.$contents = $( elmt ).find( '.ditty-editor__panel__contents' );
3221
+ this.initDisplay = null;
3222
+
3223
+ this._init();
3224
+ };
3225
+
3226
+
3227
+ Ditty_Displays_Panel.prototype = {
3228
+
3229
+ /**
3230
+ * Initialize the panel
3231
+ *
3232
+ * @since 3.0
3233
+ * @return null
3234
+ */
3235
+ _init: function () {
3236
+ this.$elmt.addClass( 'init' );
3237
+
3238
+ // Setup the display list
3239
+ this.$elmt.ditty_ui_data_list( {
3240
+ filter : '.ditty-display-panel__filter',
3241
+ item : '.ditty-editor-display',
3242
+ itemSelector : 'display_type'
3243
+ } );
3244
+
3245
+ // Activate the current layout
3246
+ this.initDisplay = this.$list.data( 'active' );
3247
+ this._activateDisplay( this.$list.find( '#ditty-editor-display--' + this.initDisplay ) );
3248
+
3249
+ // Add listeners
3250
+ this.$elmt.on( 'click', '.ditty-data-list__item', { self: this }, this._selectDisplay );
3251
+ this.$elmt.on( 'click', '.ditty-data-list__item__edit', { self: this }, this._editDisplay );
3252
+ this.$elmt.on( 'click', '.ditty-data-list__item__clone', { self: this }, this._cloneDisplay );
3253
+ this.$elmt.on( 'click', '.ditty-data-list__item__delete', { self: this }, this._deleteDisplay );
3254
+ this.settings.editor.$elmt.on( 'ditty_editor_saveDrafts', { self: this }, this._saveDrafts );
3255
+ },
3256
+
3257
+ /**
3258
+ * Editor updated listener
3259
+ *
3260
+ * @since 3.0
3261
+ * @return null
3262
+ */
3263
+ _saveDrafts: function( e ) {
3264
+ var self = e.data.self;
3265
+ self.initDisplay = self.$list.find( '.ditty-editor-display.active' ).data( 'display_id' );
3266
+ },
3267
+
3268
+ /**
3269
+ * Activate a display
3270
+ *
3271
+ * @since 3.0
3272
+ * @return null
3273
+ */
3274
+ _activateDisplay: function ( $display ) {
3275
+ this.$list.find( '.ditty-editor-display' ).removeClass( 'active' );
3276
+ $display.addClass( 'active' );
3277
+ },
3278
+
3279
+ /**
3280
+ * Load a new display
3281
+ *
3282
+ * @since 3.0
3283
+ * @return null
3284
+ */
3285
+ _initDitty: function( displayType, displayId, values ) {
3286
+
3287
+ var $elmnt = this.settings.editor.ditty.$elmt;
3288
+
3289
+ values.display = displayId;
3290
+ values.id = this.settings.editor.ditty.options( 'id' );
3291
+ values.items = this.settings.editor.ditty.options( 'items' );
3292
+ values.height = this.settings.editor.ditty.options( 'height' );
3293
+
3294
+ this.settings.editor.ditty.destroy();
3295
+
3296
+ // Setup the new ticker and overwrite ditty
3297
+ $elmnt['ditty_' + displayType]( values );
3298
+ this.settings.editor.ditty = $elmnt['ditty_' + displayType]( 'options', 'ditty' );
3299
+ },
3300
+
3301
+ /**
3302
+ * Load a new display
3303
+ *
3304
+ * @since 3.0
3305
+ * @return null
3306
+ */
3307
+ _selectDisplay: function( e ) {
3308
+ e.preventDefault();
3309
+ var self = e.data.self;
3310
+ if ( $( e.target ).parent().is( 'a' ) ) {
3311
+ return false;
3312
+ }
3313
+
3314
+ var $display = $( e.target ).is( '.ditty-data-list__item' ) ? $( e.target ) : $( e.target ).parents( '.ditty-data-list__item' ),
3315
+ displayId = $display.data( 'display_id' ),
3316
+ displayType = $display.data( 'display_type' );
3317
+
3318
+ if ( $display.hasClass( 'active' ) ) {
3319
+ return false;
3320
+ }
3321
+
3322
+ self.settings.editor.updateStart(); // Start the update overlay
3323
+ dittyDraftUpdate( self, 'post_meta', '_ditty_display', displayId );
3324
+ self._activateDisplay( $display );
3325
+
3326
+ // Load the new display data
3327
+ var data = {
3328
+ action : 'ditty_editor_select_display',
3329
+ display_id : displayId,
3330
+ draft_values : self.settings.editor.getDraftValues(),
3331
+ security : dittyVars.security
3332
+ };
3333
+ $.post( dittyVars.ajaxurl, data, function( response ) {
3334
+ if ( ! response ) {
3335
+ return false;
3336
+ }
3337
+ self._initDitty( displayType, displayId, response ); // Initialize a new ditty
3338
+ self.settings.editor.updateStop(); // Stop the update overlay
3339
+ }, 'json' );
3340
+ },
3341
+
3342
+ /**
3343
+ * Clone a display
3344
+ *
3345
+ * @since 3.0
3346
+ * @return null
3347
+ */
3348
+ _cloneDisplay: function( e ) {
3349
+ e.preventDefault();
3350
+ var self = e.data.self,
3351
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
3352
+ $display = $button.parents( '.ditty-data-list__item' ),
3353
+ displayId = $display.data( 'display_id' );
3354
+
3355
+ self.settings.editor.updateStart(); // Start the update overlay
3356
+
3357
+ // Load the new display fields
3358
+ var data = {
3359
+ action : 'ditty_editor_display_clone',
3360
+ display_id : displayId,
3361
+ draft_values : self.settings.editor.getDraftValues(),
3362
+ security : dittyVars.security
3363
+ };
3364
+
3365
+ $.post( dittyVars.ajaxurl, data, function( response ) {
3366
+ if ( response.editor_display ) {
3367
+ var $clone = $( response.editor_display );
3368
+ $clone.hide();
3369
+ $display.after( $clone );
3370
+ $clone.slideDown();
3371
+ }
3372
+ if ( response.draft_id && response.draft_data ) {
3373
+ dittyDraftDisplayUpdate( self, response.draft_id, null, response.draft_data );
3374
+ }
3375
+ self.settings.editor.updateStop(); // Stop the update overlay
3376
+ }, 'json' );
3377
+ },
3378
+
3379
+ /**
3380
+ * Delete a display
3381
+ *
3382
+ * @since 3.0
3383
+ * @return null
3384
+ */
3385
+ _deleteDisplay: function( e ) {
3386
+ e.preventDefault();
3387
+
3388
+ var self = e.data.self,
3389
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
3390
+ $item = $button.parents( '.ditty-data-list__item' ),
3391
+ $nextItem = null,
3392
+ displayId = $item.data( 'display_id' );
3393
+
3394
+ // Find the display to load if this one is active
3395
+ if ( $item.hasClass( 'active' ) ) {
3396
+ if ( $item.prev().length ) {
3397
+ $nextItem = $item.prev();
3398
+ } else if ( $item.next().length ) {
3399
+ $nextItem = $item.next();
3400
+ }
3401
+ }
3402
+
3403
+ $item.slideUp( function() {
3404
+ $( this ).remove();
3405
+ } );
3406
+ dittyDraftDisplayDelete( self, displayId );
3407
+
3408
+ // Possibly select another display
3409
+ if ( null !== $nextItem ) {
3410
+ $nextItem.trigger( 'click' );
3411
+ }
3412
+ },
3413
+
3414
+ /**
3415
+ * Edit a display
3416
+ *
3417
+ * @since 3.0
3418
+ * @return null
3419
+ */
3420
+ _editDisplay: function( e ) {
3421
+ e.preventDefault();
3422
+ var self = e.data.self;
3423
+ self.$displayEdit = $( this ).parents( '.ditty-data-list__item' );
3424
+
3425
+ var $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
3426
+ $display = $button.parents( '.ditty-data-list__item' ),
3427
+ displayId = $display.data( 'display_id' );
3428
+
3429
+ self.settings.editor.updateStart(); // Start the update overlay
3430
+ $display.addClass( 'editing' );
3431
+
3432
+ // Load the new display fields
3433
+ var data = {
3434
+ action : 'ditty_editor_display_fields',
3435
+ display_id : displayId,
3436
+ draft_values : self.settings.editor.getDraftValues(),
3437
+ security : dittyVars.security
3438
+ };
3439
+ $.post( dittyVars.ajaxurl, data, function( response ) {
3440
+ if ( response ) {
3441
+ var html = '<div class="ditty-editor__panel ditty-editor__panel--displayEditor">' + response + '</div>';
3442
+ self.settings.editor.panelOptions( 'transition', 'slideLeft' );
3443
+ self.settings.editor.showPanel( 'display_editor', html );
3444
+ }
3445
+ } );
3446
+ },
3447
+
3448
+ /**
3449
+ * Do actions when panel is visible
3450
+ *
3451
+ * @since 3.0
3452
+ * @return null
3453
+ */
3454
+ panelVisible: function () {
3455
+ this.$elmt.find( '.ditty-data-list__item' ).removeClass( 'editing' );
3456
+ },
3457
+
3458
+ /**
3459
+ * Setup triggers
3460
+ *
3461
+ * @since 3.0
3462
+ * @return null
3463
+ */
3464
+ trigger: function ( fn, customParams ) {
3465
+ var params = [this.settings];
3466
+ if ( customParams ) {
3467
+ params = customParams;
3468
+ }
3469
+
3470
+ this.$elmt.trigger( 'ditty_displays_panel_' + fn, params );
3471
+ if ( typeof this.settings[fn] === 'function' ) {
3472
+ this.settings[fn].apply( this.$elmt, params );
3473
+ }
3474
+ },
3475
+
3476
+ /**
3477
+ * Allow settings to be modified
3478
+ *
3479
+ * @since 3.0
3480
+ * @return null
3481
+ */
3482
+ options: function ( key, value ) {
3483
+ if ( typeof key === 'object' ) {
3484
+ this.settings = $.extend( {}, defaults, $.ditty_displays_panel.defaults, key );
3485
+ } else if ( typeof key === 'string' ) {
3486
+ if ( value === undefined ) {
3487
+ return this.settings[key];
3488
+ }
3489
+ this.settings[key] = value;
3490
+ } else {
3491
+ return this.settings;
3492
+ }
3493
+
3494
+ this.trigger( 'options_update' );
3495
+ },
3496
+
3497
+ /**
3498
+ * Destroy the panel
3499
+ *
3500
+ * @since 3.0
3501
+ * @return null
3502
+ */
3503
+ destroy: function () {
3504
+
3505
+ // Remove the init class
3506
+ this.$elmt.removeClass( 'init' );
3507
+
3508
+ // Destroy the display list
3509
+ this.$elmt.ditty_ui_data_list( 'destroy' );
3510
+
3511
+ // Remove listeners
3512
+ this.$elmt.off( 'click', '.ditty-data-list__item', { self: this }, this._selectDisplay );
3513
+ this.$elmt.off( 'click', '.ditty-data-list__item__edit', { self: this }, this._editDisplay );
3514
+ this.$elmt.off( 'click', '.ditty-data-list__item__clone', { self: this }, this._cloneDisplay );
3515
+ this.$elmt.off( 'click', '.ditty-data-list__item__delete', { self: this }, this._deleteDisplay );
3516
+ this.settings.editor.$elmt.off( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
3517
+
3518
+ this.trigger( 'destroy' );
3519
+ this.elmt._ditty_displays_panel = null;
3520
+ }
3521
+ };
3522
+
3523
+ /**
3524
+ * Create the data list
3525
+ *
3526
+ * @since 3.0
3527
+ * @return null
3528
+ */
3529
+ $.fn.ditty_displays_panel = function( options ) {
3530
+ var args = arguments,
3531
+ error = false,
3532
+ returns;
3533
+
3534
+ if ( options === undefined || typeof options === 'object' ) {
3535
+ return this.each( function () {
3536
+ if ( ! this._ditty_displays_panel ) {
3537
+ this._ditty_displays_panel = new Ditty_Displays_Panel( this, options );
3538
+ }
3539
+ });
3540
+ } else if ( typeof options === 'string' ) {
3541
+ this.each( function () {
3542
+ var instance = this._ditty_displays_panel;
3543
+
3544
+ if ( ! instance ) {
3545
+ throw new Error( 'No Ditty_Displays_Panel applied to this element.' );
3546
+ }
3547
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
3548
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
3549
+ } else {
3550
+ error = true;
3551
+ }
3552
+ } );
3553
+
3554
+ if ( error ) {
3555
+ throw new Error( 'No method "' + options + '" in Ditty_Displays_Panel.' );
3556
+ }
3557
+
3558
+ return returns !== undefined ? returns : this;
3559
+ }
3560
+ };
3561
+
3562
+ $.ditty_displays_panel = {};
3563
+ $.ditty_displays_panel.defaults = defaults;
3564
+
3565
+ } )( jQuery );
3566
+
3567
+
3568
+ /**
3569
+ * Ditty Display Editor Panel
3570
+ *
3571
+ * @since 3.0
3572
+ * @return null
3573
+ */
3574
+
3575
+ (function ($) {
3576
+ 'use strict';
3577
+
3578
+ var defaults = {
3579
+ editor: null
3580
+ };
3581
+
3582
+ var Ditty_Display_Editor_Panel = function ( elmt, options ) {
3583
+
3584
+ this.elmt = elmt;
3585
+ this.settings = $.extend( {}, defaults, $.ditty_display_editor_panel.defaults, options );
3586
+ this.$elmt = $( elmt );
3587
+ this.$form = this.$elmt.find( '.ditty-editor-options' );
3588
+ this.$back = this.$elmt.find( '.ditty-editor-options__back' );
3589
+ this.$optionsTitle = this.$elmt.find( '.ditty-editor-options__title' );
3590
+ this.$importExportField = this.$elmt.find( '.ditty-editor__import-export__field' );
3591
+ this.$importExportUpdate = this.$elmt.find( '.ditty-editor__import-export__update' );
3592
+ this.displayTitle = null;
3593
+ this.displayId = this.settings.editor.ditty.options( 'display' );
3594
+ this.displayType = this.settings.editor.ditty.options( 'type' );
3595
+ this.$editorDisplay = this.settings.editor.$panels.find( '.ditty-editor__panel--displays' ).find( '.ditty-data-list__item.editing' );
3596
+ this.$editorDisplayTitle = this.$editorDisplay.find( '.ditty-data-list__item__label' );
3597
+ this.displayOptions = null;
3598
+ this.initData = null;
3599
+ this.afterUpdateAction = '';
3600
+
3601
+ this._init();
3602
+ };
3603
+
3604
+
3605
+ Ditty_Display_Editor_Panel.prototype = {
3606
+
3607
+ /**
3608
+ * Initialize the data list
3609
+ *
3610
+ * @since 3.0
3611
+ * @return null
3612
+ */
3613
+ _init: function () {
3614
+
3615
+ var self = this,
3616
+ displayOptions;
3617
+
3618
+ // Save the initial data
3619
+ this.initData = this.$form.serialize();
3620
+
3621
+ // Initialize dynamic fields
3622
+ this.settings.editor.initFields( this.$elmt );
3623
+
3624
+ // Store the current ditty options
3625
+ displayOptions = this.settings.editor.ditty.$elmt['ditty_' + this.displayType]( 'options' );
3626
+ this.displayOptions = $.extend( {}, displayOptions );
3627
+
3628
+ this.displayTitle = this.$optionsTitle.val();
3629
+
3630
+ // Add actions
3631
+ this.$importExportUpdate.on( 'click', { self: this }, this._importUpdate );
3632
+ this.settings.editor.$elmt.on( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
3633
+ this.settings.editor.$elmt.on( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
3634
+ this.$form.on( 'submit', { self: this }, this._submitForm );
3635
+ this.$back.on( 'click', { self: this }, this._backClick );
3636
+ this.$elmt.on( 'change', 'input[type="text"], input[type="number"]', { self: this }, this._textfieldListeners );
3637
+ this.$form.on( 'click', 'input[type="radio"]', { self: this }, this._radioListeners );
3638
+ this.$form.on( 'click', 'input[type="checkbox"]', { self: this }, this._checkboxListeners );
3639
+ this.$form.on( 'change', 'select', { self: this }, this._selectListeners );
3640
+ this.$form.on( 'ditty_field_clone_update', { self: this }, this._cloneListeners );
3641
+
3642
+ // Trigger the init
3643
+ setTimeout( function() {
3644
+ self.trigger( 'init', [self] );
3645
+ }, 1 );
3646
+ },
3647
+
3648
+ /**
3649
+ * Return to the displays list
3650
+ *
3651
+ * @since 3.0
3652
+ * @return null
3653
+ */
3654
+ _showDisplayList: function() {
3655
+ this.settings.editor.$panels.ditty_slider( 'options', 'transition', 'slideRight' );
3656
+ this.settings.editor.$panels.ditty_slider( 'showSlideById', 'displays' );
3657
+ },
3658
+
3659
+ /**
3660
+ * Check for updates
3661
+ *
3662
+ * @since 3.0
3663
+ * @return null
3664
+ */
3665
+ _checkUpdates: function() {
3666
+ var currentData = this.$form.serialize();
3667
+ if ( currentData !== this.initData ) {
3668
+ this.settings.editor.addUpdate( 'displaySettings', this.displayId );
3669
+ this.settings.editor.delayedSubmitEnable(); // Enable the delayed submit since we have changes
3670
+ } else {
3671
+ this.settings.editor.removeUpdate( 'displaySettings', this.displayId );
3672
+ }
3673
+ },
3674
+
3675
+ /**
3676
+ * Editor tabs listener
3677
+ *
3678
+ * @since 3.0
3679
+ * @return null
3680
+ */
3681
+ _addDrafts: function( e ) {
3682
+ var self = e.data.self,
3683
+ currentData = self.$form.serialize();
3684
+
3685
+ if ( currentData !== self.initData ) {
3686
+ self.$form.trigger( 'submit' );
3687
+ }
3688
+ },
3689
+
3690
+ /**
3691
+ * Editor updated listener
3692
+ *
3693
+ * @since 3.0
3694
+ * @return null
3695
+ */
3696
+ _saveDrafts: function( e ) {
3697
+ var self = e.data.self,
3698
+ currentData = self.$form.serialize();
3699
+
3700
+ if ( currentData !== self.initData ) {
3701
+ self.afterUpdateAction = 'save';
3702
+ self.$form.trigger( 'submit' );
3703
+ }
3704
+ },
3705
+
3706
+ /**
3707
+ * Back click
3708
+ *
3709
+ * @since 3.0
3710
+ * @return null
3711
+ */
3712
+ _backClick: function( e ) {
3713
+ e.preventDefault();
3714
+ var self = e.data.self,
3715
+ currentData = self.$form.serialize();
3716
+
3717
+ if ( currentData === self.initData ) {
3718
+ self._showDisplayList();
3719
+ } else {
3720
+ self.afterUpdateAction = 'return';
3721
+ self.$form.trigger( 'submit' );
3722
+ }
3723
+ },
3724
+
3725
+ /**
3726
+ * Cancel click
3727
+ *
3728
+ * @since 3.0
3729
+ * @return null
3730
+ */
3731
+ _submitForm: function( e ) {
3732
+ e.preventDefault();
3733
+ var self = e.data.self;
3734
+
3735
+ self.settings.editor.updateStart(); // Start the update overlay
3736
+
3737
+ var data = {
3738
+ action : 'ditty_editor_display_update',
3739
+ display_id : self.displayId,
3740
+ draft_values : self.settings.editor.getDraftValues(),
3741
+ security : dittyVars.security
3742
+ };
3743
+ self.$form.ajaxSubmit( {
3744
+ url : dittyVars.ajaxurl,
3745
+ type : 'post',
3746
+ dataType : 'json',
3747
+ data : data,
3748
+ success: function( response ) {
3749
+ self.initData = self.$form.serialize();
3750
+
3751
+ if ( response.draft_id && response.draft_label ) {
3752
+ self.displayTitle = response.draft_label;
3753
+ self.$editorDisplayTitle.text( response.draft_label );
3754
+ dittyDraftDisplayUpdate( self, response.draft_id, 'label', response.draft_label );
3755
+ }
3756
+ if ( response.draft_id && response.draft_settings ) {
3757
+ self.displayOptions = response.draft_settings;
3758
+ dittyDraftDisplayUpdate( self, response.draft_id, 'settings', response.draft_settings );
3759
+ }
3760
+ if ( response.draft_settings_json && self.$importExportField.length ) {
3761
+ self.$importExportField.val( response.draft_settings_json );
3762
+ }
3763
+
3764
+ self.settings.editor.updateStop(); // Stop the update overlay
3765
+ self.settings.editor.delayedSubmitDisable(); // Remove the delayed submit since we just submitted
3766
+
3767
+ // Show the display list
3768
+ if ( 'return' === self.afterUpdateAction ) {
3769
+ self._showDisplayList();
3770
+ }
3771
+ // Update the ticker
3772
+ if ( 'save' === self.afterUpdateAction ) {
3773
+ self.settings.editor.saveDitty();
3774
+ }
3775
+ self.afterUpdateAction = '';
3776
+ }
3777
+ } );
3778
+ },
3779
+
3780
+ /**
3781
+ * Update the imported values
3782
+ *
3783
+ * @since 3.0
3784
+ * @return null
3785
+ */
3786
+ _importUpdate: function( e ) {
3787
+ e.preventDefault();
3788
+
3789
+ // var self = e.data.self,
3790
+ // values = self.$importExportField.val();
3791
+ },
3792
+
3793
+ /**
3794
+ * Listen for clone changes
3795
+ *
3796
+ * @since 3.0
3797
+ * @return null
3798
+ */
3799
+ _cloneListeners: function( e, fieldData, cloneName ) {
3800
+ var self = e.data.self,
3801
+ $target = $( e.target );
3802
+
3803
+ self.settings.editor.ditty.options( cloneName, fieldData );
3804
+ },
3805
+
3806
+ /**
3807
+ * Listen for textfield changes
3808
+ *
3809
+ * @since 3.0
3810
+ * @return null
3811
+ */
3812
+ _textfieldListeners: function( e ) {
3813
+ var self = e.data.self,
3814
+ $target = $( e.target ),
3815
+ name = $target.attr( 'name' ),
3816
+ $fieldset = $target.parents( '.ditty-input--spacing__group, .ditty-input--radius__group' );
3817
+
3818
+ if ( $fieldset.length ) {
3819
+ var fieldsetName = '',
3820
+ fieldsetValue = {};
3821
+ $fieldset.find( 'input').each( function() {
3822
+ name = $( this ).attr( 'name' );
3823
+ fieldsetName = name.split( '[' );
3824
+ fieldsetName = fieldsetName[0];
3825
+ var matches = name.match(/\[(.*)\]/);
3826
+ fieldsetValue[matches[1]] = $( this ).val();
3827
+ } );
3828
+ self.settings.editor.ditty.options( fieldsetName, fieldsetValue );
3829
+ } else {
3830
+ self.settings.editor.ditty.options( name, $target.val() );
3831
+ }
3832
+ self._checkUpdates();
3833
+ },
3834
+
3835
+ /**
3836
+ * Listen for radio button changes
3837
+ *
3838
+ * @since 3.0
3839
+ * @return null
3840
+ */
3841
+ _radioListeners: function( e ) {
3842
+ var self = e.data.self,
3843
+ $target = $( e.target ),
3844
+ value = $target.val(),
3845
+ name = $target.attr( 'name' );
3846
+
3847
+ self.settings.editor.ditty.options( name, value );
3848
+ self._checkUpdates();
3849
+ },
3850
+
3851
+ /**
3852
+ * Listen for checkbox changes
3853
+ *
3854
+ * @since 3.0
3855
+ * @return null
3856
+ */
3857
+ _checkboxListeners: function( e ) {
3858
+ var self = e.data.self,
3859
+ $target = $( e.target ),
3860
+ value = $target.is( ':checked' ) ? $( this ).val() : false,
3861
+ name = $target.attr( 'name' );
3862
+
3863
+ self.settings.editor.ditty.options( name, value );
3864
+ self._checkUpdates();
3865
+ },
3866
+
3867
+ /**
3868
+ * Listen for select changes
3869
+ *
3870
+ * @since 3.0
3871
+ * @return null
3872
+ */
3873
+ _selectListeners: function( e ) {
3874
+ var self = e.data.self,
3875
+ $target = $( e.target ),
3876
+ value = $target.val(),
3877
+ name = $target.attr( 'name' );
3878
+
3879
+ self.settings.editor.ditty.options( name, value );
3880
+ self._checkUpdates();
3881
+ },
3882
+
3883
+ /**
3884
+ * Return a specific setting
3885
+ *
3886
+ * @since 3.0
3887
+ * @return null
3888
+ */
3889
+ _options: function ( key ) {
3890
+ return this.settings[key];
3891
+ },
3892
+
3893
+ /**
3894
+ * Setup triggers
3895
+ *
3896
+ * @since 3.0
3897
+ * @return null
3898
+ */
3899
+ trigger: function ( fn, customParams ) {
3900
+ var params = [this.settings];
3901
+
3902
+ if ( customParams ) {
3903
+ params = customParams;
3904
+ }
3905
+
3906
+ this.$elmt.trigger( 'ditty_display_editor_panel_' + fn, params );
3907
+
3908
+ if ( typeof this.settings[fn] === 'function' ) {
3909
+ this.settings[fn].apply( this.$elmt, params );
3910
+ }
3911
+ },
3912
+
3913
+
3914
+ /**
3915
+ * Allow settings to be modified
3916
+ *
3917
+ * @since 3.0
3918
+ * @return null
3919
+ */
3920
+ options: function ( key, value ) {
3921
+
3922
+ if ( typeof key === 'object' ) {
3923
+ this.settings = $.extend( {}, defaults, $.ditty_display_editor_panel.defaults, key );
3924
+ } else if ( typeof key === 'string' ) {
3925
+ if ( value === undefined ) {
3926
+ return this.settings[key];
3927
+ }
3928
+ this.settings[key] = value;
3929
+ } else {
3930
+ return this.settings;
3931
+ }
3932
+
3933
+ this.trigger( 'options_update' );
3934
+ },
3935
+
3936
+
3937
+ /**
3938
+ * Destroy the editor
3939
+ *
3940
+ * @since 3.0
3941
+ * @return null
3942
+ */
3943
+ destroy: function () {
3944
+
3945
+ this.trigger( 'destroy', [this] );
3946
+
3947
+ // Remove actions
3948
+ this.$importExportUpdate.off( 'click', { this: this }, this._importUpdate );
3949
+ this.settings.editor.$elmt.off( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
3950
+ this.settings.editor.$elmt.off( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
3951
+ this.$form.off( 'submit', { this: this }, this._submitForm );
3952
+ this.$back.off( 'click', { this: this }, this._cancel_click );
3953
+ this.$elmt.off( 'change', 'input[type="text"], input[type="number"]', { self: this }, this._textfieldListeners );
3954
+ this.$form.off( 'click', 'input[type="radio"]', { self: this }, this._radioListeners );
3955
+ this.$form.off( 'click', 'input[type="checkbox"]', { self: this }, this._checkboxListeners );
3956
+ this.$form.off( 'change', 'select', { self: this }, this._selectListeners );
3957
+ this.$form.off( 'ditty_field_clone_update', { self: this }, this._cloneListeners );
3958
+
3959
+ this.elmt._ditty_display_editor_panel = null;
3960
+ }
3961
+ };
3962
+
3963
+
3964
+ /**
3965
+ * Create the data list
3966
+ *
3967
+ * @since 3.0
3968
+ * @return null
3969
+ */
3970
+ $.fn.ditty_display_editor_panel = function( options ) {
3971
+ var args = arguments,
3972
+ error = false,
3973
+ returns;
3974
+
3975
+ if ( options === undefined || typeof options === 'object' ) {
3976
+ return this.each( function () {
3977
+ if ( ! this._ditty_display_editor_panel ) {
3978
+ this._ditty_display_editor_panel = new Ditty_Display_Editor_Panel( this, options );
3979
+ }
3980
+ });
3981
+ } else if ( typeof options === 'string' ) {
3982
+ this.each( function () {
3983
+ var instance = this._ditty_display_editor_panel;
3984
+
3985
+ if ( ! instance ) {
3986
+ throw new Error( 'No Ditty_Display_Editor_Panel applied to this element.' );
3987
+ }
3988
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
3989
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
3990
+ } else {
3991
+ error = true;
3992
+ }
3993
+ } );
3994
+
3995
+ if ( error ) {
3996
+ throw new Error( 'No method "' + options + '" in Ditty_Display_Editor_Panel.' );
3997
+ }
3998
+
3999
+ return returns !== undefined ? returns : this;
4000
+ }
4001
+ };
4002
+
4003
+ $.ditty_display_editor_panel = {};
4004
+ $.ditty_display_editor_panel.defaults = defaults;
4005
+
4006
+ } )( jQuery );
4007
+
4008
+
4009
+ /**
4010
+ * Ditty Layout Variations Panel
4011
+ *
4012
+ * @since 3.0
4013
+ * @return null
4014
+ */
4015
+ ( function ( $ ) {
4016
+ 'use strict';
4017
+
4018
+ var defaults = {
4019
+ editor: null
4020
+ };
4021
+
4022
+ var Ditty_Layout_Variations_Panel = function ( elmt, options ) {
4023
+ this.elmt = elmt;
4024
+ this.settings = $.extend( {}, defaults, $.ditty_layout_variations_panel.defaults, options );
4025
+ this.$elmt = $( elmt );
4026
+ this.$back = this.$elmt.find( '.ditty-editor-options__back' );
4027
+ this.$list = $( elmt ).find( '.ditty-data-list__items' );
4028
+ this.$editorItem = dittyVars.editor.currentItem;
4029
+ this.editorItemLabel = this.$editorItem.find( '.ditty-data-list__item__label' ).text();
4030
+ this.editorDittyId = this.$editorItem.data( 'ditty_id' );
4031
+ this.editorItemId = this.$editorItem.data( 'item_id' );
4032
+ this.editorItemType = this.$editorItem.data( 'item_type' );
4033
+
4034
+ this._init();
4035
+ };
4036
+
4037
+
4038
+ Ditty_Layout_Variations_Panel.prototype = {
4039
+
4040
+ /**
4041
+ * Initialize the panel
4042
+ *
4043
+ * @since 3.0
4044
+ * @return null
4045
+ */
4046
+ _init: function () {
4047
+ this.$elmt.addClass( 'init' );
4048
+
4049
+ // Add actions
4050
+ this.$back.on( 'click', { self: this }, this._backClick );
4051
+ this.$elmt.on( 'click', '.ditty-layout-variation__change', { self: this }, this._changeTemplate );
4052
+ this.$elmt.on( 'click', '.ditty-layout-variation__edit_html', { self: this, editType: 'html' }, this._editLayout );
4053
+ this.$elmt.on( 'click', '.ditty-layout-variation__edit_css', { self: this, editType: 'css' }, this._editLayout );
4054
+ $( 'body' ).on( 'ditty_editor_save_ditty_response', { self: this }, this._dittyEditorSaveResponse );
4055
+ },
4056
+
4057
+ /**
4058
+ * Return to the item list
4059
+ *
4060
+ * @since 3.0
4061
+ * @return null
4062
+ */
4063
+ _showItemList: function() {
4064
+ this.settings.editor.$panels.ditty_slider( 'options', 'transition', 'slideRight' );
4065
+ this.settings.editor.$panels.ditty_slider( 'showSlideById', 'items' );
4066
+ },
4067
+
4068
+ /**
4069
+ * Cancel click
4070
+ *
4071
+ * @since 3.0
4072
+ * @return null
4073
+ */
4074
+ _backClick: function( e ) {
4075
+ e.preventDefault();
4076
+ var self = e.data.self;
4077
+ self._showItemList();
4078
+ },
4079
+
4080
+ /**
4081
+ * Update new item ids on save
4082
+ *
4083
+ * @since 3.0
4084
+ * @return null
4085
+ */
4086
+ _dittyEditorSaveResponse: function( e, response ) {
4087
+ var self = e.data.self;
4088
+ if ( response.ditty_new_layout_ids ) {
4089
+ $.each( response.ditty_new_layout_ids, function( draftId, newId ) {
4090
+ var $variationItem = $( '.ditty-layout-variation[data-layout_id="' + draftId + '"]' );
4091
+ if ( $variationItem.length ) {
4092
+ $variationItem.attr( 'data-layout_id', newId ).data( 'layout_id', newId );
4093
+ }
4094
+ } );
4095
+ }
4096
+ },
4097
+
4098
+ /**
4099
+ * Load a new layout
4100
+ *
4101
+ * @since 3.0
4102
+ * @return null
4103
+ */
4104
+ _changeTemplate: function( e ) {
4105
+ e.preventDefault();
4106
+ var self = e.data.self;
4107
+
4108
+ var $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
4109
+ $layoutVariation = $button.parents( '.ditty-data-list__item' ),
4110
+ layoutId = $layoutVariation.data( 'layout_id' ),
4111
+ variationId = $layoutVariation.data( 'layout_variation_id' ),
4112
+ variationLabel = $layoutVariation.data( 'layout_variation_label' );
4113
+
4114
+ dittyVars.editor.currentLayoutVariation = $layoutVariation; // Set the current layout variation
4115
+
4116
+ self.settings.editor.updateStart(); // Start the update overlay
4117
+ $layoutVariation.addClass( 'editing' );
4118
+
4119
+ // Load the item fields
4120
+ var data = {
4121
+ action : 'ditty_editor_layouts',
4122
+ ditty_id : self.editorDittyId,
4123
+ item_type : self.editorItemType,
4124
+ variation_id : variationId,
4125
+ variation_label : variationLabel,
4126
+ layout_id : layoutId,
4127
+ draft_values : self.settings.editor.getDraftValues(),
4128
+ security : dittyVars.security
4129
+ };
4130
+ $.post( dittyVars.ajaxurl, data, function( response ) {
4131
+ if ( response ) {
4132
+ var html = '<div class="ditty-editor__panel ditty-editor__panel--layouts">' + response + '</div>';
4133
+ self.settings.editor.panelOptions( 'transition', 'slideLeft' );
4134
+ self.settings.editor.showPanel( 'layouts', html );
4135
+ }
4136
+ } );
4137
+ },
4138
+
4139
+ /**
4140
+ * Edit the html or css of a layout
4141
+ *
4142
+ * @since 3.0
4143
+ * @return null
4144
+ */
4145
+ _editLayout: function( e ) {
4146
+ e.preventDefault();
4147
+ var self = e.data.self,
4148
+ editType = e.data.editType,
4149
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
4150
+ $layoutVariation = $button.parents( '.ditty-data-list__item' ),
4151
+ layoutId = $layoutVariation.data( 'layout_id' ),
4152
+ itemType = $layoutVariation.data( 'item_type' );
4153
+
4154
+ dittyVars.editor.currentLayoutVariation = $layoutVariation; // Set the current layout variation
4155
+
4156
+ self.settings.editor.updateStart(); // Start the update overlay
4157
+ self.$list.find( '.ditty-data-list__item' ).removeClass( 'editing' );
4158
+ $layoutVariation.addClass( 'editing' );
4159
+
4160
+ var itemIds = [],
4161
+ items = self.settings.editor.ditty.options( 'items' );
4162
+
4163
+ $.each( items, function( index, item ) {
4164
+ itemIds.push( item.uniqId );
4165
+ } );
4166
+
4167
+ // Load the new display fields
4168
+ var data = {
4169
+ action : 'ditty_editor_layout_fields',
4170
+ layout_id : layoutId,
4171
+ item_type : itemType,
4172
+ ditty_id : self.editorDittyId,
4173
+ item_id : self.editorItemId,
4174
+ item_ids : itemIds,
4175
+ edit_type : editType,
4176
+ draft_values : self.settings.editor.getDraftValues(),
4177
+ security : dittyVars.security
4178
+ };
4179
+ $.post( dittyVars.ajaxurl, data, function( response ) {
4180
+ if ( response ) {
4181
+ var slideId = 'layout_' + editType + '_editor',
4182
+ html = '<div class="ditty-editor__panel ditty-editor__panel--' + slideId + '">' + response.form + '</div>';
4183
+
4184
+ self.settings.editor.panelOptions( 'transition', 'slideLeft' );
4185
+ self.settings.editor.showPanel( slideId, html );
4186
+ }
4187
+ }, 'json' );
4188
+ },
4189
+
4190
+ /**
4191
+ * Do actions when panel is visible
4192
+ *
4193
+ * @since 3.0
4194
+ * @return null
4195
+ */
4196
+ panelVisible: function () {
4197
+ this.$list.find( '.ditty-layout-variation' ).removeClass( 'editing' );
4198
+ },
4199
+
4200
+ /**
4201
+ * Setup triggers
4202
+ *
4203
+ * @since 3.0
4204
+ * @return null
4205
+ */
4206
+ trigger: function ( fn, customParams ) {
4207
+ var params = [this.settings];
4208
+ if ( customParams ) {
4209
+ params = customParams;
4210
+ }
4211
+
4212
+ this.$elmt.trigger( 'ditty_layout_variations_panel_' + fn, params );
4213
+ if ( typeof this.settings[fn] === 'function' ) {
4214
+ this.settings[fn].apply( this.$elmt, params );
4215
+ }
4216
+ },
4217
+
4218
+ /**
4219
+ * Allow settings to be modified
4220
+ *
4221
+ * @since 3.0
4222
+ * @return null
4223
+ */
4224
+ options: function ( key, value ) {
4225
+ if ( typeof key === 'object' ) {
4226
+ this.settings = $.extend( {}, defaults, $.ditty_layout_variations_panel.defaults, key );
4227
+ } else if ( typeof key === 'string' ) {
4228
+ if ( value === undefined ) {
4229
+ return this.settings[key];
4230
+ }
4231
+ this.settings[key] = value;
4232
+ } else {
4233
+ return this.settings;
4234
+ }
4235
+
4236
+ this.trigger( 'options_update' );
4237
+ },
4238
+
4239
+ /**
4240
+ * Destroy the editor
4241
+ *
4242
+ * @since 3.0
4243
+ * @return null
4244
+ */
4245
+ destroy: function () {
4246
+ this.$elmt.removeClass( 'init' );
4247
+ this.$back.off( 'click', { self: this }, this._backClick );
4248
+ this.$elmt.off( 'click', '.ditty-layout-variation__change', { self: this }, this._changeTemplate );
4249
+ this.$elmt.off( 'click', '.ditty-layout-variation__edit_html', { self: this, editType: 'html' }, this._editLayout );
4250
+ this.$elmt.off( 'click', '.ditty-layout-variation__edit_css', { self: this, editType: 'css' }, this._editLayout );
4251
+ $( 'body' ).off( 'ditty_editor_save_ditty_response', { self: this }, this._dittyEditorSaveResponse );
4252
+
4253
+ this.elmt._ditty_layout_variations_panel = null;
4254
+ }
4255
+ };
4256
+
4257
+ /**
4258
+ * Create the data list
4259
+ *
4260
+ * @since 3.0
4261
+ * @return null
4262
+ */
4263
+ $.fn.ditty_layout_variations_panel = function( options ) {
4264
+ var args = arguments,
4265
+ error = false,
4266
+ returns;
4267
+
4268
+ if ( options === undefined || typeof options === 'object' ) {
4269
+ return this.each( function () {
4270
+ if ( ! this._ditty_layout_variations_panel ) {
4271
+ this._ditty_layout_variations_panel = new Ditty_Layout_Variations_Panel( this, options );
4272
+ }
4273
+ });
4274
+ } else if ( typeof options === 'string' ) {
4275
+ this.each( function () {
4276
+ var instance = this._ditty_layout_variations_panel;
4277
+
4278
+ if ( ! instance ) {
4279
+ throw new Error( 'No Ditty_Layout_Variations_Panel applied to this element.' );
4280
+ }
4281
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
4282
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
4283
+ } else {
4284
+ error = true;
4285
+ }
4286
+ } );
4287
+
4288
+ if ( error ) {
4289
+ throw new Error( 'No method "' + options + '" in Ditty_Layout_Variations_Panel.' );
4290
+ }
4291
+
4292
+ return returns !== undefined ? returns : this;
4293
+ }
4294
+ };
4295
+
4296
+ $.ditty_layout_variations_panel = {};
4297
+ $.ditty_layout_variations_panel.defaults = defaults;
4298
+
4299
+ } )( jQuery );
4300
+
4301
+ /**
4302
+ * Ditty Layouts Panel
4303
+ *
4304
+ * @since 3.0
4305
+ * @return null
4306
+ */
4307
+ ( function ( $ ) {
4308
+ 'use strict';
4309
+
4310
+ var defaults = {
4311
+ editor: null
4312
+ };
4313
+
4314
+ var Ditty_Layouts_Panel = function ( elmt, options ) {
4315
+ this.elmt = elmt;
4316
+ this.settings = $.extend( {}, defaults, $.ditty_layouts_panel.defaults, options );
4317
+ this.$elmt = $( elmt );
4318
+ this.$back = this.$elmt.find( '.ditty-editor-options__back' );
4319
+ this.$list = $( elmt ).find( '.ditty-data-list__items' );
4320
+ this.$editorItem = dittyVars.editor.currentItem;
4321
+ this.editorDittyId = this.$editorItem.data( 'ditty_id' );
4322
+ this.editorItemId = this.$editorItem.data( 'item_id' );
4323
+ this.editorItemtype = this.$editorItem.data( 'item_type' );
4324
+ this.$editorVariation = dittyVars.editor.currentLayoutVariation;
4325
+ this.editorVariationId = this.$editorVariation.data( 'layout_variation_id' );
4326
+ this.editorLayoutId = this.$editorVariation.data( 'layout_id' );
4327
+ this._init();
4328
+ };
4329
+
4330
+
4331
+ Ditty_Layouts_Panel.prototype = {
4332
+
4333
+ /**
4334
+ * Initialize the panel
4335
+ *
4336
+ * @since 3.0
4337
+ * @return null
4338
+ */
4339
+ _init: function () {
4340
+ this.$elmt.addClass( 'init' );
4341
+
4342
+ // Add actions
4343
+ this.$back.on( 'click', { self: this }, this._backClick );
4344
+ this.$elmt.on( 'click', '.ditty-data-list__item', { self: this }, this._selectLayout );
4345
+ this.$elmt.on( 'click', '.ditty-data-list__item__edit_html', { self: this, editType: 'html' }, this._editLayout );
4346
+ this.$elmt.on( 'click', '.ditty-data-list__item__edit_css', { self: this, editType: 'css' }, this._editLayout );
4347
+ this.$elmt.on( 'click', '.ditty-data-list__item__clone', { self: this }, this._cloneLayout );
4348
+ this.$elmt.on( 'click', '.ditty-data-list__item__delete', { self: this }, this._deleteLayout );
4349
+ this.$list.on( 'click', '.ditty-editor-layout > a', { self: this }, this._actionClick );
4350
+ $( 'body' ).on( 'ditty_editor_save_ditty_response', { self: this }, this._dittyEditorSaveResponse );
4351
+
4352
+ // Activate the current layout
4353
+ this._activateLayout( this.$list.find( '#ditty-editor-layout--' + this.editorLayoutId ) );
4354
+ },
4355
+
4356
+ /**
4357
+ * Activate a layout
4358
+ *
4359
+ * @since 3.0
4360
+ * @return null
4361
+ */
4362
+ _activateLayout: function ( $layout ) {
4363
+ this.$list.find( '.ditty-editor-layout' ).removeClass( 'active' );
4364
+ $layout.addClass( 'active' );
4365
+ },
4366
+
4367
+ /**
4368
+ * Return to the item list
4369
+ *
4370
+ * @since 3.0
4371
+ * @return null
4372
+ */
4373
+ _showVariationsList: function() {
4374
+ this.settings.editor.$panels.ditty_slider( 'options', 'transition', 'slideRight' );
4375
+ this.settings.editor.$panels.ditty_slider( 'showSlideById', 'layout_variations' );
4376
+ },
4377
+
4378
+ /**
4379
+ * Cancel click
4380
+ *
4381
+ * @since 3.0
4382
+ * @return null
4383
+ */
4384
+ _backClick: function( e ) {
4385
+ e.preventDefault();
4386
+ var self = e.data.self;
4387
+ self._showVariationsList();
4388
+ },
4389
+
4390
+ /**
4391
+ * Update new item ids on save
4392
+ *
4393
+ * @since 3.0
4394
+ * @return null
4395
+ */
4396
+ _dittyEditorSaveResponse: function( e, response ) {
4397
+ var self = e.data.self;
4398
+ if ( response.ditty_new_layout_ids ) {
4399
+ $.each( response.ditty_new_layout_ids, function( draftId, newId ) {
4400
+ var $editorItem = $( '#ditty-editor-layout--' + draftId );
4401
+ if ( $editorItem.length ) {
4402
+ $editorItem.attr( 'id', 'ditty-editor-layout--' + newId );
4403
+ $editorItem.attr( 'data-layout_id', newId ).data( 'layout_id', newId );
4404
+ }
4405
+ } );
4406
+ }
4407
+ },
4408
+
4409
+ /**
4410
+ * Update new layout ids on save
4411
+ *
4412
+ * @since 3.0
4413
+ * @return null
4414
+ */
4415
+ // dittyUpdatedDraftLayouts: function( variationType, layoutId ) {
4416
+ // var self = this;
4417
+ //
4418
+ // $.each( $( '.ditty-editor-item' ), function() {
4419
+ // var itemID = $( this ).data( 'item_id' ),
4420
+ // itemType = $( this ).data( 'item_type' ),
4421
+ // layoutValue = $( this ).data( 'layout_value' );
4422
+ // $.each( layoutValue, function( type, id ) {
4423
+ // if ( String( itemType ) === String( self.editorItemtype ) && String( type ) === String( variationType ) ) {
4424
+ // layoutValue[type] = String( layoutId );
4425
+ // dittyDraftItemUpdateData( self, itemID, 'layout_value', layoutValue );
4426
+ // }
4427
+ // } );
4428
+ // } );
4429
+ // },
4430
+
4431
+ /**
4432
+ * Load a new layout
4433
+ *
4434
+ * @since 3.0
4435
+ * @return null
4436
+ */
4437
+ _selectLayout: function( e ) {
4438
+ e.preventDefault();
4439
+ var self = e.data.self;
4440
+ if ( $( e.target ).parent().is( 'a' ) ) {
4441
+ return false;
4442
+ }
4443
+
4444
+ var $layout = $( e.target ).is( '.ditty-data-list__item' ) ? $( e.target ) : $( e.target ).parents( '.ditty-data-list__item' ),
4445
+ layoutId = $layout.data( 'layout_id' ),
4446
+ layoutVersion = $layout.data( 'layout_version' ),
4447
+ layoutValue = self.$editorItem.data( 'layout_value' );
4448
+
4449
+ if ( $layout.hasClass( 'active' ) ) {
4450
+ return false;
4451
+ }
4452
+ $.each( layoutValue, function( type ) {
4453
+ if ( self.editorVariationId === type ) {
4454
+ layoutValue[type] = String( layoutId );
4455
+ }
4456
+ } );
4457
+
4458
+ // Highlight the active layout
4459
+ self.settings.editor.updateStart(); // Start the update overlay
4460
+ //self.dittyUpdatedDraftLayouts( self.editorVariationId, layoutId );
4461
+ //dittyDraftItemUpdateData( self, self.editorItemId, 'layout_id', layoutId );
4462
+ dittyDraftItemUpdateData( self, self.editorItemId, 'layout_value', layoutValue );
4463
+ self._activateLayout( $layout );
4464
+
4465
+ // Use ajax to load the new layout
4466
+ var data = {
4467
+ action : 'ditty_editor_select_layout',
4468
+ layout_id : layoutId,
4469
+ item_id : self.editorItemId,
4470
+ ditty_id : self.editorDittyId,
4471
+ draft_values : self.settings.editor.getDraftValues(),
4472
+ security : dittyVars.security
4473
+ };
4474
+ $.post( dittyVars.ajaxurl, data, function( response ) {
4475
+ self.settings.editor.updateStop(); // Stop the update overlay
4476
+ if ( response.display_items ) {
4477
+ //self.settings.editor.ditty.updateItems( response.display_items, false, false, true );
4478
+ self.settings.editor.ditty.updateItems( response.display_items, self.editorItemId );
4479
+ }
4480
+ if ( response.editor_item ) {
4481
+ var $newEditorItem = $( response.editor_item );
4482
+ self.$editorItem.replaceWith( $newEditorItem );
4483
+ }
4484
+
4485
+ // Update the current Ditty
4486
+ self.$editorItem.attr( 'data-layout_value', layoutValue ).data( 'layout_value', layoutValue );
4487
+ self.$editorVariation.attr( 'data-layout_id', layoutId ).data( 'layout_id', layoutId );
4488
+ self.$editorVariation.find( '.ditty-layout-variation__template > span' ).text( response.layout_label );
4489
+ if ( layoutVersion ) {
4490
+ self.$editorVariation.find( '.ditty-layout-variation__template > small' ).text( '(' + layoutVersion + ')' );
4491
+ } else {
4492
+ self.$editorVariation.find( '.ditty-layout-variation__template > small' ).text( '' );
4493
+ }
4494
+ }, 'json' );
4495
+ },
4496
+
4497
+ /**
4498
+ * Clone a layout
4499
+ *
4500
+ * @since 3.0
4501
+ * @return null
4502
+ */
4503
+ _cloneLayout: function( e ) {
4504
+ e.preventDefault();
4505
+ var self = e.data.self,
4506
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
4507
+ $item = $button.parents( '.ditty-data-list__item' ),
4508
+ layoutId = $item.data( 'layout_id' );
4509
+
4510
+ self.settings.editor.updateStart(); // Start the update overlay
4511
+
4512
+ // Use ajax to clone the layout
4513
+ var data = {
4514
+ action : 'ditty_editor_layout_clone',
4515
+ layout_id : layoutId,
4516
+ draft_values : self.settings.editor.getDraftValues(),
4517
+ security : dittyVars.security
4518
+ };
4519
+ $.post( dittyVars.ajaxurl, data, function( response ) {
4520
+ if ( response.editor_layout ) {
4521
+ var $new = $( response.editor_layout );
4522
+ $new.hide();
4523
+ $item.after( $new );
4524
+ $new.slideDown();
4525
+ }
4526
+ if ( response.draft_id && response.draft_meta ) {
4527
+ dittyDraftLayoutUpdate( self, response.draft_id, null, response.draft_meta );
4528
+ }
4529
+ self.settings.editor.updateStop(); // Stop the update overlay
4530
+ }, 'json' );
4531
+ },
4532
+
4533
+ /**
4534
+ * Delete a layout
4535
+ *
4536
+ * @since 3.0
4537
+ * @return null
4538
+ */
4539
+ _deleteLayout: function( e ) {
4540
+ e.preventDefault();
4541
+
4542
+ var self = e.data.self,
4543
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
4544
+ $item = $button.parents( '.ditty-data-list__item' ),
4545
+ $nextItem = null,
4546
+ layoutId = $item.data( 'layout_id' );
4547
+
4548
+ // Find the layout to load if this one is active
4549
+ if ( $item.hasClass( 'active' ) ) {
4550
+ if ( $item.prev().length ) {
4551
+ $nextItem = $item.prev();
4552
+ } else if ( $item.next().length ) {
4553
+ $nextItem = $item.next();
4554
+ }
4555
+ }
4556
+
4557
+ // Remove the layout
4558
+ $item.slideUp( function() {
4559
+ $( this ).remove();
4560
+ } );
4561
+ dittyDraftLayoutDelete( self, layoutId );
4562
+
4563
+ // Possibly select another layout
4564
+ if ( null !== $nextItem ) {
4565
+ $nextItem.trigger( 'click' );
4566
+ }
4567
+ },
4568
+
4569
+ /**
4570
+ * Edit the html or css of a layout
4571
+ *
4572
+ * @since 3.0
4573
+ * @return null
4574
+ */
4575
+ _editLayout: function( e ) {
4576
+ e.preventDefault();
4577
+ var self = e.data.self,
4578
+ editType = e.data.editType,
4579
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
4580
+ $layout = $button.parents( '.ditty-data-list__item' ),
4581
+ layoutId = $layout.data( 'layout_id' );
4582
+
4583
+ self.settings.editor.updateStart(); // Start the update overlay
4584
+ self.$list.find( '.ditty-data-list__item' ).removeClass( 'editing' );
4585
+ $layout.addClass( 'editing' );
4586
+
4587
+ // Load the new display fields
4588
+ var data = {
4589
+ action : 'ditty_editor_layout_fields',
4590
+ layout_id : layoutId,
4591
+ item_id : self.editorItemId,
4592
+ edit_type : editType,
4593
+ draft_values : self.settings.editor.getDraftValues(),
4594
+ security : dittyVars.security
4595
+ };
4596
+ $.post( dittyVars.ajaxurl, data, function( response ) {
4597
+ if ( response ) {
4598
+ var slideId = 'layout_' + editType + '_editor',
4599
+ html = '<div class="ditty-editor__panel ditty-editor__panel--' + slideId + '">' + response.form + '</div>';
4600
+
4601
+ self.settings.editor.panelOptions( 'transition', 'slideLeft' );
4602
+ self.settings.editor.showPanel( slideId, html );
4603
+ }
4604
+ }, 'json' );
4605
+ },
4606
+
4607
+ /**
4608
+ * Trigger an actions when a button is clicked
4609
+ *
4610
+ * @since 3.0
4611
+ * @return null
4612
+ */
4613
+ _actionClick: function( e ) {
4614
+ e.preventDefault();
4615
+ var self = e.data.self,
4616
+ $button = $( e.target ).is( 'a' ) ? $( e.target ) : $( e.target ).parent( 'a' ),
4617
+ $layout = $button.parents( '.ditty-data-list__item' ),
4618
+ layoutId = $layout.data( 'layout_id' );
4619
+
4620
+ dittyVars.editor.currentLayout = $layout; // Set the current layout
4621
+
4622
+ $( 'body' ).trigger( 'ditty_editor_layout_action_click', [$button, $layout, layoutId, self.editorDittyId, self.settings.editor] );
4623
+ },
4624
+
4625
+ /**
4626
+ * Setup triggers
4627
+ *
4628
+ * @since 3.0
4629
+ * @return null
4630
+ */
4631
+ trigger: function ( fn, customParams ) {
4632
+ var params = [this.settings];
4633
+ if ( customParams ) {
4634
+ params = customParams;
4635
+ }
4636
+
4637
+ this.$elmt.trigger( 'ditty_layouts_panel_' + fn, params );
4638
+ if ( typeof this.settings[fn] === 'function' ) {
4639
+ this.settings[fn].apply( this.$elmt, params );
4640
+ }
4641
+ },
4642
+
4643
+ /**
4644
+ * Allow settings to be modified
4645
+ *
4646
+ * @since 3.0
4647
+ * @return null
4648
+ */
4649
+ options: function ( key, value ) {
4650
+ if ( typeof key === 'object' ) {
4651
+ this.settings = $.extend( {}, defaults, $.ditty_layouts_panel.defaults, key );
4652
+ } else if ( typeof key === 'string' ) {
4653
+ if ( value === undefined ) {
4654
+ return this.settings[key];
4655
+ }
4656
+ this.settings[key] = value;
4657
+ } else {
4658
+ return this.settings;
4659
+ }
4660
+
4661
+ this.trigger( 'options_update' );
4662
+ },
4663
+
4664
+
4665
+ /**
4666
+ * Destroy the editor
4667
+ *
4668
+ * @since 3.0
4669
+ * @return null
4670
+ */
4671
+ destroy: function () {
4672
+
4673
+ // Remove the init class
4674
+ this.$elmt.removeClass( 'init' );
4675
+
4676
+ // Remove actions
4677
+ this.$back.off( 'click', { self: this }, this._backClick );
4678
+ this.$elmt.off( 'click', '.ditty-data-list__item', { self: this }, this._selectLayout );
4679
+ this.$elmt.off( 'click', '.ditty-data-list__item__edit_html', { self: this, editType: 'html' }, this._editLayout );
4680
+ this.$elmt.off( 'click', '.ditty-data-list__item__edit_css', { self: this, editType: 'css' }, this._editLayout );
4681
+ this.$elmt.off( 'click', '.ditty-data-list__item__clone', { self: this }, this._cloneLayout );
4682
+ this.$elmt.off( 'click', '.ditty-data-list__item__delete', { self: this }, this._deleteLayout );
4683
+ this.$list.off( 'click', '.ditty-editor-layout > a', { self: this }, this._actionClick );
4684
+ $( 'body' ).off( 'ditty_editor_save_ditty_response', { self: this }, this._dittyEditorSaveResponse );
4685
+
4686
+ this.elmt._ditty_layouts_panel = null;
4687
+ }
4688
+ };
4689
+
4690
+ /**
4691
+ * Create the data list
4692
+ *
4693
+ * @since 3.0
4694
+ * @return null
4695
+ */
4696
+ $.fn.ditty_layouts_panel = function( options ) {
4697
+ var args = arguments,
4698
+ error = false,
4699
+ returns;
4700
+
4701
+ if ( options === undefined || typeof options === 'object' ) {
4702
+ return this.each( function () {
4703
+ if ( ! this._ditty_layouts_panel ) {
4704
+ this._ditty_layouts_panel = new Ditty_Layouts_Panel( this, options );
4705
+ }
4706
+ });
4707
+ } else if ( typeof options === 'string' ) {
4708
+ this.each( function () {
4709
+ var instance = this._ditty_layouts_panel;
4710
+
4711
+ if ( ! instance ) {
4712
+ throw new Error( 'No Ditty_Layouts_Panel applied to this element.' );
4713
+ }
4714
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
4715
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
4716
+ } else {
4717
+ error = true;
4718
+ }
4719
+ } );
4720
+
4721
+ if ( error ) {
4722
+ throw new Error( 'No method "' + options + '" in Ditty_Layouts_Panel.' );
4723
+ }
4724
+
4725
+ return returns !== undefined ? returns : this;
4726
+ }
4727
+ };
4728
+
4729
+ $.ditty_layouts_panel = {};
4730
+ $.ditty_layouts_panel.defaults = defaults;
4731
+
4732
+ } )( jQuery );
4733
+
4734
+
4735
+ /* global wp:true */
4736
+ /* global _:true */
4737
+
4738
+ /**
4739
+ * Ditty Layout HTML Editor Panel
4740
+ * @since 3.0
4741
+ * @return null
4742
+ */
4743
+
4744
+ (function ($) {
4745
+ 'use strict';
4746
+
4747
+ var defaults = {
4748
+ editor : null,
4749
+ prevPanel : ''
4750
+ };
4751
+
4752
+ var Ditty_Layout_Html_Editor_Panel = function ( elmt, options ) {
4753
+
4754
+ this.elmt = elmt;
4755
+ this.settings = $.extend( {}, defaults, $.ditty_layout_html_editor_panel.defaults, options );
4756
+ this.$elmt = $( elmt );
4757
+ this.$form = this.$elmt.find( '.ditty-editor-options' );
4758
+ this.$textarea = this.$elmt.find( '.ditty-editor-options__code' );
4759
+ this.$back = this.$elmt.find( '.ditty-editor-options__back' );
4760
+ this.$preview = this.$elmt.find( '.ditty-editor-options__preview' );
4761
+ this.$editCss = this.$elmt.find( '.ditty-editor-options__edit-css' );
4762
+ this.$title = this.$elmt.find( '.ditty-editor-options__title' );
4763
+ this.$tags = this.$elmt.find( '.ditty-editor-options__tags' );
4764
+ this.itemType = this.$form.data( 'item_type' );
4765
+ this.layoutId = this.$form.data( 'layout_id' );
4766
+ this.$editorItem = dittyVars.editor.currentItem;
4767
+ this.$editorLayout = dittyVars.editor.currentLayout;
4768
+ this.$editorLayoutTitle = this.$editorLayout ? this.$editorLayout.find( '.ditty-data-list__item__label' ) : false;
4769
+ this.$editorLayoutVariation = dittyVars.editor.currentLayoutVariation;
4770
+ this.$editorLayoutVariationTitle = this.$editorLayoutVariation.find( '.ditty-layout-variation__template span' );
4771
+ this.editorDittyId = this.$editorItem.data( 'ditty_id' );
4772
+ this.editorItemId = this.$editorItem.data( 'item_id' );
4773
+ this.codeEditor = null;
4774
+ this.codeHasUpdates = false;
4775
+ this.initData = null;
4776
+ this.afterUpdateAction = '';
4777
+ this._init();
4778
+ };
4779
+
4780
+
4781
+ Ditty_Layout_Html_Editor_Panel.prototype = {
4782
+
4783
+ /**
4784
+ * Initialize the data list
4785
+ * @since 3.0
4786
+ * @return null
4787
+ */
4788
+ _init: function () {
4789
+
4790
+ // Save the initial data
4791
+ this.initData = this.$form.serialize();
4792
+
4793
+ // Initialize dynamic fields
4794
+ this._initEditor();
4795
+
4796
+ // Add actions
4797
+ this.$back.on( 'click', { self: this }, this._backClick );
4798
+ this.$preview.on( 'click', { self: this }, this._previewClick );
4799
+ this.$editCss.on( 'click', { self: this }, this._editCss );
4800
+ this.$form.on( 'submit', { self: this }, this._submitForm );
4801
+ this.$form.on( 'click', '.ditty-editor-options__tag', { self: this }, this._insertTag );
4802
+ this.$title.on( 'keyup', { self: this }, this._titleUpdate );
4803
+ this.settings.editor.$elmt.on( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
4804
+ this.settings.editor.$elmt.on( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
4805
+ },
4806
+
4807
+ /**
4808
+ * Return to the previous panel
4809
+ * @since 3.0
4810
+ * @return null
4811
+ */
4812
+ _showPrevPanel: function() {
4813
+ this.settings.editor.$panels.ditty_slider( 'options', 'transition', 'slideRight' );
4814
+ this.settings.editor.$panels.ditty_slider( 'showSlideById', this.settings.prevPanel );
4815
+ },
4816
+
4817
+ /**
4818
+ * Editor updated listener
4819
+ * @since 3.0
4820
+ * @return null
4821
+ */
4822
+ _titleUpdate: function( e ) {
4823
+ var self = e.data.self;
4824
+ self.settings.editor.addUpdate( 'layoutUpdate', self.layoutId );
4825
+ },
4826
+
4827
+ /**
4828
+ * Preview button add updates class
4829
+ * @since 3.0
4830
+ * @return null
4831
+ */
4832
+ _enablePreviewButton: function() {
4833
+ this.$preview.addClass( 'ditty-has-updates' );
4834
+ },
4835
+
4836
+ /**
4837
+ * Preview button remove updates class
4838
+ * @since 3.0
4839
+ * @return null
4840
+ */
4841
+ _disablePreviewButton: function() {
4842
+ this.$preview.removeClass( 'ditty-has-updates' );
4843
+ this.$preview.children( 'i' ).attr( 'class', this.$preview.children( 'i' ).data( 'class' ) );
4844
+ },
4845
+
4846
+ /**
4847
+ * Return item ids of current layout
4848
+ * @since 3.0
4849
+ * @return null
4850
+ */
4851
+ _getLayoutItems: function() {
4852
+ var items = this.settings.editor.ditty.options( 'items' ),
4853
+ itemIds = [];
4854
+
4855
+ $.each( items, function( key, value ) {
4856
+ if ( String( value.layoutId ) === String( this.layoutId ) ) {
4857
+ itemIds.push( value.id );
4858
+ }
4859
+ } );
4860
+ return itemIds;
4861
+ },
4862
+
4863
+ /**
4864
+ * Editor tabs listener
4865
+ * @since 3.0
4866
+ * @return null
4867
+ */
4868
+ _addDrafts: function( e ) {
4869
+ var self = e.data.self;
4870
+ self.codeEditor.codemirror.save();
4871
+
4872
+ var currentData = self.$form.serialize();
4873
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
4874
+ self.$form.trigger( 'submit' );
4875
+ }
4876
+ },
4877
+
4878
+ /**
4879
+ * Editor updated listener
4880
+ * @since 3.0
4881
+ * @return null
4882
+ */
4883
+ _saveDrafts: function( e ) {
4884
+ var self = e.data.self;
4885
+ self.codeEditor.codemirror.save();
4886
+
4887
+ var currentData = self.$form.serialize();
4888
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
4889
+ self.afterUpdateAction = 'save';
4890
+ self.$form.trigger( 'submit' );
4891
+ }
4892
+ },
4893
+
4894
+ /**
4895
+ * Back click
4896
+ * @since 3.0
4897
+ * @return null
4898
+ */
4899
+ _backClick: function( e ) {
4900
+ e.preventDefault();
4901
+ var self = e.data.self;
4902
+
4903
+ self.codeEditor.codemirror.save();
4904
+ var currentData = self.$form.serialize();
4905
+
4906
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
4907
+ self.afterUpdateAction = 'return';
4908
+ self.$form.trigger( 'submit' );
4909
+ } else {
4910
+ self._showPrevPanel();
4911
+ }
4912
+ },
4913
+
4914
+ /**
4915
+ * Preview any changes
4916
+ * @since 3.0
4917
+ * @return null
4918
+ */
4919
+ _previewClick: function( e ) {
4920
+ e.preventDefault();
4921
+ var self = e.data.self;
4922
+
4923
+ self.codeEditor.codemirror.save(); // Update the textarea
4924
+ var currentData = self.$form.serialize();
4925
+
4926
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
4927
+ self.$preview.children( 'i' ).attr( 'class', dittyVars.updateIcon );
4928
+ self.$form.trigger( 'submit' );
4929
+ }
4930
+ },
4931
+
4932
+ /**
4933
+ * Edit the css of the layout
4934
+ * @since 3.0
4935
+ * @return null
4936
+ */
4937
+ _editCss: function( e ) {
4938
+ e.preventDefault();
4939
+ var self = e.data.self,
4940
+ panelId = 'layout_css_editor';
4941
+
4942
+ self.settings.editor.updateStart(); // Start the update overlay
4943
+ self.codeEditor.codemirror.save(); // Update the textarea
4944
+ var currentData = self.$form.serialize();
4945
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
4946
+ self.$preview.children( 'i' ).attr( 'class', dittyVars.updateIcon );
4947
+ self.$form.trigger( 'submit' );
4948
+ }
4949
+
4950
+ // Show the panel if it exists
4951
+ if ( self.settings.editor.panelExists( panelId ) ) {
4952
+ self.settings.editor.$elmt.find( '.ditty-editor__panel--layout_css_editor input.ditty-editor-options__title' ).val( self.$title.val() );
4953
+ self.settings.editor.panelOptions( 'transition', 'fade' );
4954
+ self.settings.editor.showPanel( panelId );
4955
+
4956
+ // Else, load the new panel and show
4957
+ } else {
4958
+ var data = {
4959
+ action : 'ditty_editor_layout_fields',
4960
+ layout_id : self.layoutId,
4961
+ layout_title : self.$title.val(),
4962
+ ditty_id : self.editorDittyId,
4963
+ item_id : self.editorItemId,
4964
+ item_type : self.itemType,
4965
+ edit_type : 'css',
4966
+ draft_values : self.settings.editor.getDraftValues(),
4967
+ security : dittyVars.security
4968
+ };
4969
+ $.post( dittyVars.ajaxurl, data, function( response ) {
4970
+ if ( response ) {
4971
+ var html = '<div class="ditty-editor__panel ditty-editor__panel--' + panelId + '">' + response.form + '</div>';
4972
+ self.settings.editor.panelOptions( 'transition', 'fade' );
4973
+ self.settings.editor.showPanel( panelId, html );
4974
+ }
4975
+ }, 'json' );
4976
+ }
4977
+ },
4978
+
4979
+ /**
4980
+ * Submit updates
4981
+ * @since 3.0
4982
+ * @return null
4983
+ */
4984
+ _submitForm: function( e ) {
4985
+ e.preventDefault();
4986
+
4987
+ var self = e.data.self,
4988
+ layoutId = self.layoutId,
4989
+ itemType = self.itemType,
4990
+ itemIds = self._getLayoutItems();
4991
+
4992
+ if ( self.$form.hasClass( 'ditty-editor-has-errors' ) ) {
4993
+ return false;
4994
+ }
4995
+
4996
+ self.codeEditor.codemirror.save(); // Update the textarea
4997
+ self.settings.editor.updateStart(); // Start the update overlay
4998
+
4999
+ var data = {
5000
+ action : 'ditty_editor_layout_update',
5001
+ layout_id : layoutId,
5002
+ item_type : itemType,
5003
+ item_ids : itemIds,
5004
+ edit_type : 'html',
5005
+ draft_values : self.settings.editor.getDraftValues(),
5006
+ security : dittyVars.security
5007
+ };
5008
+ self.$form.ajaxSubmit({
5009
+ url : dittyVars.ajaxurl,
5010
+ type : 'post',
5011
+ dataType : 'json',
5012
+ data : data,
5013
+ success : function( response ) {
5014
+ self.initData = self.$form.serialize();
5015
+ self._disablePreviewButton();
5016
+
5017
+ // Update labels
5018
+ if ( response.label ) {
5019
+ if ( self.$editorLayoutTitle ) {
5020
+ self.$editorLayoutTitle.html( response.label );
5021
+ }
5022
+ self.$editorLayoutVariationTitle.html( response.label );
5023
+ }
5024
+ // Remove the template version numbers
5025
+ if ( self.$editorLayoutTitle ) {
5026
+ self.$editorLayoutTitle.find( '.ditty-layout-version' ).remove();
5027
+ }
5028
+ if ( self.$editorLayoutVariationTitle ) {
5029
+ self.$editorLayoutVariationTitle.find( '.ditty-layout-version' ).remove();
5030
+ }
5031
+
5032
+ if ( response.display_items ) {
5033
+ self.settings.editor.ditty.updateItems( response.display_items, false, false, true );
5034
+ }
5035
+ if ( response.draft_id && response.draft_meta ) {
5036
+ dittyDraftLayoutUpdate( self, response.draft_id, null, response.draft_meta );
5037
+ }
5038
+
5039
+ self.codeHasUpdates = false;
5040
+ self.settings.editor.updateStop(); // Stop the update overlay
5041
+ self.settings.editor.delayedSubmitDisable(); // Remove the delayed submit since we just submitted
5042
+
5043
+ if ( 'return' === self.afterUpdateAction ) {
5044
+ self._showPrevPanel(); // Show the items list
5045
+ }
5046
+ if ( 'save' === self.afterUpdateAction ) {
5047
+ self.settings.editor.saveDitty( { return_items: 0 } ); // Update the ticker
5048
+ }
5049
+ self.afterUpdateAction = '';
5050
+ }
5051
+ } );
5052
+ },
5053
+
5054
+ /**
5055
+ * Initialize the editor
5056
+ * @since 3.0
5057
+ * @return null
5058
+ */
5059
+ _initEditor: function() {
5060
+ var self = this,
5061
+ codeEditorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
5062
+
5063
+ codeEditorSettings.codemirror = _.extend(
5064
+ {},
5065
+ codeEditorSettings.codemirror,
5066
+ {
5067
+ indentUnit : 2,
5068
+ tabSize : 2
5069
+ }
5070
+ );
5071
+ this.codeEditor = wp.codeEditor.initialize( this.$textarea[0], codeEditorSettings );
5072
+ this.codeEditor.codemirror.on( 'change', function() {
5073
+ self.codeEditor.codemirror.save();
5074
+ self.settings.editor.addUpdate( 'layout_html_update', self.layoutId );
5075
+ self.codeHasUpdates = true;
5076
+ self._enablePreviewButton();
5077
+ self.settings.editor.delayedSubmitEnable(); // Enable the delayed submit since we have changes
5078
+ } );
5079
+ },
5080
+
5081
+ /**
5082
+ * Insert a tag
5083
+ * @since 3.0
5084
+ * @return null
5085
+ */
5086
+ _insertTag: function( e ) {
5087
+ var self = e.data.self,
5088
+ $tag = $( e.target ),
5089
+ text = $tag.text(),
5090
+ atts = $tag.data( 'atts' ),
5091
+ cursor = self.codeEditor.codemirror.getCursor();
5092
+
5093
+ if ( e.shiftKey && atts ) {
5094
+ var attsString = '',
5095
+ insertPoint = text.length - 1;
5096
+
5097
+ $.each( atts, function( key, value ) {
5098
+ attsString += ' ' + key + '="' + value.toString() + '"';
5099
+ } );
5100
+ text = text.substring( 0, insertPoint ) + attsString + text.substring( insertPoint );
5101
+ }
5102
+ self.codeEditor.codemirror.replaceRange( text, cursor );
5103
+
5104
+ // Move the cursor position
5105
+ cursor.ch = cursor.ch + text.length;
5106
+ self.codeEditor.codemirror.setCursor( cursor );
5107
+ },
5108
+
5109
+ /**
5110
+ * Return a specific setting
5111
+ * @since 3.0
5112
+ * @return null
5113
+ */
5114
+ _options: function ( key ) {
5115
+ return this.settings[key];
5116
+ },
5117
+
5118
+ /**
5119
+ * Setup triggers
5120
+ * @since 3.0
5121
+ * @return null
5122
+ */
5123
+ trigger: function ( fn, customParams ) {
5124
+ var params = [this.settings];
5125
+ if ( customParams ) {
5126
+ params = customParams;
5127
+ }
5128
+
5129
+ this.$elmt.trigger( 'ditty_layout_html_editor_panel_' + fn, params );
5130
+
5131
+ if ( typeof this.settings[fn] === 'function' ) {
5132
+ this.settings[fn].apply( this.$elmt, params );
5133
+ }
5134
+ },
5135
+
5136
+ /**
5137
+ * Allow settings to be modified
5138
+ * @since 3.0
5139
+ * @return null
5140
+ */
5141
+ options: function ( key, value ) {
5142
+ if ( typeof key === 'object' ) {
5143
+ this.settings = $.extend( {}, defaults, $.ditty_layout_html_editor_panel.defaults, key );
5144
+ } else if ( typeof key === 'string' ) {
5145
+ if ( value === undefined ) {
5146
+ return this.settings[key];
5147
+ }
5148
+ this.settings[key] = value;
5149
+ } else {
5150
+ return this.settings;
5151
+ }
5152
+ this.trigger( 'options_update' );
5153
+ },
5154
+
5155
+ /**
5156
+ * Destroy the class
5157
+ * @since 3.0
5158
+ * @return null
5159
+ */
5160
+ destroy: function () {
5161
+ this.$back.off( 'click', { self: this }, this._backClick );
5162
+ this.$preview.off( 'click', { self: this }, this._previewClick );
5163
+ this.$editCss.off( 'click', { self: this }, this._editCss );
5164
+ this.$form.off( 'submit', { self: this }, this._submitForm );
5165
+ this.$form.off( 'click', '.ditty-editor-options__tag', { self: this }, this._insertTag );
5166
+ this.$title.off( 'keyup', { self: this }, this._titleUpdate );
5167
+ this.settings.editor.$elmt.off( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
5168
+ this.settings.editor.$elmt.off( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
5169
+ this.codeEditor.codemirror.off( 'change' );
5170
+ this.codeEditor.codemirror.toTextArea();
5171
+
5172
+ this.elmt._ditty_layout_html_editor_panel = null;
5173
+ }
5174
+ };
5175
+
5176
+ /**
5177
+ * Create the data list
5178
+ * @since 3.0
5179
+ * @return null
5180
+ */
5181
+ $.fn.ditty_layout_html_editor_panel = function( options ) {
5182
+ var args = arguments,
5183
+ error = false,
5184
+ returns;
5185
+
5186
+ if ( options === undefined || typeof options === 'object' ) {
5187
+ return this.each( function () {
5188
+ if ( ! this._ditty_layout_html_editor_panel ) {
5189
+ this._ditty_layout_html_editor_panel = new Ditty_Layout_Html_Editor_Panel( this, options );
5190
+ }
5191
+ });
5192
+ } else if ( typeof options === 'string' ) {
5193
+ this.each( function () {
5194
+ var instance = this._ditty_layout_html_editor_panel;
5195
+
5196
+ if ( ! instance ) {
5197
+ throw new Error( 'No Ditty_Layout_Html_Editor_Panel applied to this element.' );
5198
+ }
5199
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
5200
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
5201
+ } else {
5202
+ error = true;
5203
+ }
5204
+ } );
5205
+
5206
+ if ( error ) {
5207
+ throw new Error( 'No method "' + options + '" in Ditty_Layout_Html_Editor_Panel.' );
5208
+ }
5209
+
5210
+ return returns !== undefined ? returns : this;
5211
+ }
5212
+ };
5213
+
5214
+ $.ditty_layout_html_editor_panel = {};
5215
+ $.ditty_layout_html_editor_panel.defaults = defaults;
5216
+
5217
+ } )( jQuery );
5218
+
5219
+
5220
+ /* global dittyLayoutCss:true */
5221
+
5222
+ /**
5223
+ * Ditty Layout CSS Editor Panel
5224
+ * @since 3.0
5225
+ * @return null
5226
+ */
5227
+
5228
+ (function ($) {
5229
+ 'use strict';
5230
+
5231
+ var defaults = {
5232
+ editor : null,
5233
+ prevPanel : ''
5234
+ };
5235
+
5236
+ var Ditty_Layout_Css_Editor_Panel = function ( elmt, options ) {
5237
+
5238
+ this.elmt = elmt;
5239
+ this.settings = $.extend( {}, defaults, $.ditty_layout_css_editor_panel.defaults, options );
5240
+ this.$elmt = $( elmt );
5241
+ this.$form = this.$elmt.find( '.ditty-editor-options' );
5242
+ this.$textarea = this.$elmt.find( '.ditty-editor-options__code' );
5243
+ this.$back = this.$elmt.find( '.ditty-editor-options__back' );
5244
+ this.$preview = this.$elmt.find( '.ditty-editor-options__preview' );
5245
+ this.$editHtml = this.$elmt.find( '.ditty-editor-options__edit-html' );
5246
+ this.$title = this.$elmt.find( '.ditty-editor-options__title' );
5247
+ this.$body = this.$elmt.find( '.ditty-editor-options__body' );
5248
+ this.$tags = this.$elmt.find( '.ditty-editor-options__tags' );
5249
+ this.itemType = this.$form.data( 'item_type' );
5250
+ this.layoutId = this.$form.data( 'layout_id' );
5251
+ this.$editorItem = dittyVars.editor.currentItem;
5252
+ this.$editorLayout = dittyVars.editor.currentLayout;
5253
+ this.$editorLayoutTitle = this.$editorLayout ? this.$editorLayout.find( '.ditty-data-list__item__label' ) : false;
5254
+ this.$editorLayoutVariation = dittyVars.editor.currentLayoutVariation;
5255
+ this.$editorLayoutVariationTitle = this.$editorLayoutVariation.find( '.ditty-layout-variation__template span' );
5256
+ this.editorDittyId = this.$editorItem.data( 'ditty_id' );
5257
+ this.editorItemId = this.$editorItem.data( 'item_id' );
5258
+ this.itemSelector = '';
5259
+ this.codeEditor = null;
5260
+ this.codeHasUpdates = false;
5261
+ this.initData = null;
5262
+ this.afterUpdateAction = '';
5263
+
5264
+ this._init();
5265
+ };
5266
+
5267
+
5268
+ Ditty_Layout_Css_Editor_Panel.prototype = {
5269
+
5270
+ /**
5271
+ * Initialize the data list
5272
+ * @since 3.0
5273
+ * @return null
5274
+ */
5275
+ _init: function () {
5276
+
5277
+ // Save the initial data
5278
+ this.initData = this.$form.serialize();
5279
+
5280
+ // Set the css item selector
5281
+ this._setCssSelector();
5282
+
5283
+ // Initialize dynamic fields
5284
+ this._initEditor();
5285
+
5286
+ // Add actions
5287
+ this.$back.on( 'click', { self: this }, this._backClick );
5288
+ this.$preview.on( 'click', { self: this }, this._previewClick );
5289
+ this.$editHtml.on( 'click', { self: this }, this._editHtml );
5290
+ this.$form.on( 'submit', { self: this }, this._submitForm );
5291
+ this.$form.on( 'click', '.ditty-editor-options__tag', { self: this }, this._insertTag );
5292
+ this.$title.on( 'keyup', { self: this }, this._titleUpdate );
5293
+ this.$body.on( 'click', '.ditty-editor-options__body__error', { self: this }, this._removeErrorNotice );
5294
+ this.settings.editor.$elmt.on( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
5295
+ this.settings.editor.$elmt.on( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
5296
+ },
5297
+
5298
+ /**
5299
+ * Set the css item selector
5300
+ * @since 3.0
5301
+ * @return null
5302
+ */
5303
+ _setCssSelector: function() {
5304
+ if ( dittyVars.isTickerPost ) {
5305
+ this.itemSelector = '#poststuff .ditty-layout--' + this.layoutId;
5306
+ } else {
5307
+ this.itemSelector = '.ditty-layout--' + this.layoutId;
5308
+ }
5309
+ },
5310
+
5311
+ /**
5312
+ * Return to the previous panel
5313
+ * @since 3.0
5314
+ * @return null
5315
+ */
5316
+ _showPrevPanel: function() {
5317
+ this.settings.editor.$panels.ditty_slider( 'options', 'transition', 'slideRight' );
5318
+ this.settings.editor.$panels.ditty_slider( 'showSlideById', this.settings.prevPanel );
5319
+ },
5320
+
5321
+ /**
5322
+ * Editor updated listener
5323
+ * @since 3.0
5324
+ * @return null
5325
+ */
5326
+ _titleUpdate: function( e ) {
5327
+ var self = e.data.self;
5328
+ self.settings.editor.addUpdate( 'layoutUpdate', self.layoutId );
5329
+ },
5330
+
5331
+ /**
5332
+ * Preview button add updates class
5333
+ * @since 3.0
5334
+ * @return null
5335
+ */
5336
+ _enablePreviewButton: function() {
5337
+ this.$preview.addClass( 'ditty-has-updates' );
5338
+ },
5339
+
5340
+ /**
5341
+ * Preview button remove updates class
5342
+ * @since 3.0
5343
+ * @return null
5344
+ */
5345
+ _disablePreviewButton: function() {
5346
+ this.$preview.removeClass( 'ditty-has-updates' );
5347
+ this.$preview.children( 'i' ).attr( 'class', this.$preview.children( 'i' ).data( 'class' ) );
5348
+ },
5349
+
5350
+ /**
5351
+ * Editor tabs listener
5352
+ * @since 3.0
5353
+ * @return null
5354
+ */
5355
+ _addDrafts: function( e ) {
5356
+ var self = e.data.self;
5357
+ self.codeEditor.codemirror.save();
5358
+
5359
+ var currentData = self.$form.serialize();
5360
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
5361
+ self.$form.trigger( 'submit' );
5362
+ }
5363
+ },
5364
+
5365
+ /**
5366
+ * Editor updated listener
5367
+ * @since 3.0
5368
+ * @return null
5369
+ */
5370
+ _saveDrafts: function( e ) {
5371
+ var self = e.data.self;
5372
+ self.codeEditor.codemirror.save();
5373
+
5374
+ var currentData = self.$form.serialize();
5375
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
5376
+ self.afterUpdateAction = 'save';
5377
+ self.$form.trigger( 'submit' );
5378
+ }
5379
+ },
5380
+
5381
+ /**
5382
+ * Back click
5383
+ * @since 3.0
5384
+ * @return null
5385
+ */
5386
+ _backClick: function( e ) {
5387
+ e.preventDefault();
5388
+ var self = e.data.self;
5389
+
5390
+ self.codeEditor.codemirror.save();
5391
+ var currentData = self.$form.serialize();
5392
+
5393
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
5394
+ self.afterUpdateAction = 'return';
5395
+ self.$form.trigger( 'submit' );
5396
+ } else {
5397
+ self._showPrevPanel();
5398
+ }
5399
+ },
5400
+
5401
+ /**
5402
+ * Preview any changes
5403
+ * @since 3.0
5404
+ * @return null
5405
+ */
5406
+ _previewClick: function( e ) {
5407
+ e.preventDefault();
5408
+ var self = e.data.self;
5409
+
5410
+ self.codeEditor.codemirror.save(); // Update the textarea
5411
+ var currentData = self.$form.serialize();
5412
+
5413
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
5414
+ self.$preview.children( 'i' ).attr( 'class', dittyVars.updateIcon );
5415
+ self.$form.trigger( 'submit' );
5416
+ }
5417
+ },
5418
+
5419
+ /**
5420
+ * Edit the html of the layout
5421
+ * @since 3.0
5422
+ * @return null
5423
+ */
5424
+ _editHtml: function( e ) {
5425
+ e.preventDefault();
5426
+ var self = e.data.self,
5427
+ panelId = 'layout_html_editor';
5428
+
5429
+ self.settings.editor.updateStart(); // Start the update overlay
5430
+ self.codeEditor.codemirror.save(); // Update the textarea
5431
+ var currentData = self.$form.serialize();
5432
+ if ( currentData !== self.initData || self.codeHasUpdates ) {
5433
+ self.$preview.children( 'i' ).attr( 'class', dittyVars.updateIcon );
5434
+ self.$form.trigger( 'submit' );
5435
+ }
5436
+
5437
+ // Show the panel if it exists
5438
+ if ( self.settings.editor.panelExists( panelId ) ) {
5439
+ self.settings.editor.$elmt.find( '.ditty-editor__panel--layout_html_editor input.ditty-editor-options__title' ).val( self.$title.val() );
5440
+ self.settings.editor.panelOptions( 'transition', 'fade' );
5441
+ self.settings.editor.showPanel( panelId );
5442
+
5443
+ // Else, load the new panel and show
5444
+ } else {
5445
+ var data = {
5446
+ action : 'ditty_editor_layout_fields',
5447
+ layout_id : self.layoutId,
5448
+ layout_title : self.$title.val(),
5449
+ ditty_id : self.editorDittyId,
5450
+ item_id : self.editorItemId,
5451
+ item_type : self.itemType,
5452
+ edit_type : 'html',
5453
+ draft_values : self.settings.editor.getDraftValues(),
5454
+ security : dittyVars.security
5455
+ };
5456
+ $.post( dittyVars.ajaxurl, data, function( response ) {
5457
+ if ( response ) {
5458
+ var html = '<div class="ditty-editor__panel ditty-editor__panel--' + panelId + '">' + response.form + '</div>';
5459
+ self.settings.editor.panelOptions( 'transition', 'fade' );
5460
+ self.settings.editor.showPanel( panelId, html );
5461
+ }
5462
+ }, 'json' );
5463
+ }
5464
+ },
5465
+
5466
+ /**
5467
+ * Add an error notice
5468
+ * @since 3.0
5469
+ * @return null
5470
+ */
5471
+ _showErrorNotice: function() {
5472
+ var $error = $( '<div class="ditty-editor-options__body__error"><span>' + dittyVars.strings.layout_css_error + '</span></div>' );
5473
+ this.$body.append( $error );
5474
+
5475
+ },
5476
+
5477
+ /**
5478
+ * Remove the error notice
5479
+ * @since 3.0
5480
+ * @return null
5481
+ */
5482
+ _removeErrorNotice: function( e ) {
5483
+ var self = e.data.self;
5484
+ self.$body.find( '.ditty-editor-options__body__error' ).remove();
5485
+ },
5486
+
5487
+ /**
5488
+ * Submit updates
5489
+ * @since 3.0
5490
+ * @return null
5491
+ */
5492
+ _submitForm: function( e ) {
5493
+ e.preventDefault();
5494
+
5495
+ var self = e.data.self,
5496
+ layoutId = self.layoutId,
5497
+ itemType = self.itemType;
5498
+
5499
+ if ( self.$form.hasClass( 'ditty-editor-has-errors' ) ) {
5500
+ return false;
5501
+ }
5502
+
5503
+ self.codeEditor.codemirror.save(); // Update the textarea
5504
+ self.settings.editor.updateStart(); // Start the update overlay
5505
+
5506
+ var data = {
5507
+ action : 'ditty_editor_layout_update',
5508
+ layout_id : layoutId,
5509
+ item_type : itemType,
5510
+ edit_type : 'css',
5511
+ draft_values : self.settings.editor.getDraftValues(),
5512
+ security : dittyVars.security
5513
+ };
5514
+ self.$form.ajaxSubmit( {
5515
+ url : dittyVars.ajaxurl,
5516
+ type : 'post',
5517
+ dataType: 'json',
5518
+ data : data,
5519
+ success: function( response ) {
5520
+ self.initData = self.$form.serialize();
5521
+ self._disablePreviewButton();
5522
+ if ( response.label ) {
5523
+ if ( self.$editorLayoutTitle ) {
5524
+ self.$editorLayoutTitle.html( response.label );
5525
+ }
5526
+ self.$editorLayoutVariationTitle.html( response.label );
5527
+ }
5528
+ // Remove the template version numbers
5529
+ if ( self.$editorLayoutTitle ) {
5530
+ self.$editorLayoutTitle.find( '.ditty-layout-version' ).remove();
5531
+ }
5532
+ if ( self.$editorLayoutVariationTitle ) {
5533
+ self.$editorLayoutVariationTitle.find( '.ditty-layout-version' ).remove();
5534
+ }
5535
+
5536
+ if ( response.code ) {
5537
+ dittyLayoutCss( response.code, self.layoutId );
5538
+ } else {
5539
+ self._showErrorNotice();
5540
+ }
5541
+ if ( response.draft_id && response.draft_meta ) {
5542
+ dittyDraftLayoutUpdate( self, response.draft_id, null, response.draft_meta );
5543
+ }
5544
+
5545
+ self.codeHasUpdates = false;
5546
+ self.settings.editor.updateStop(); // Stop the update overlay
5547
+ self.settings.editor.delayedSubmitDisable(); // Remove the delayed submit since we just submitted
5548
+
5549
+ if ( 'return' === self.afterUpdateAction ) {
5550
+ self._showPrevPanel(); // Show the items list
5551
+ }
5552
+ if ( 'save' === self.afterUpdateAction ) {
5553
+ self.settings.editor.saveDitty(); // Update the ticker
5554
+ }
5555
+ self.afterUpdateAction = '';
5556
+ }
5557
+ } );
5558
+ },
5559
+
5560
+ /**
5561
+ * Initialize the editor
5562
+ * @since 3.0
5563
+ * @return null
5564
+ */
5565
+ _initEditor: function() {
5566
+ var self = this,
5567
+ codeEditorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {},
5568
+ mode = dittyVars.editor.ditty_layouts_sass ? 'sass' : 'css';
5569
+
5570
+ codeEditorSettings.codemirror = _.extend(
5571
+ {},
5572
+ codeEditorSettings.codemirror,
5573
+ {
5574
+ mode : mode,
5575
+ indentUnit : 2,
5576
+ tabSize : 2
5577
+ }
5578
+ );
5579
+ this.codeEditor = wp.codeEditor.initialize( this.$textarea[0], codeEditorSettings );
5580
+ this.codeEditor.codemirror.on( 'change', function() {
5581
+ self.codeEditor.codemirror.save();
5582
+ self.settings.editor.addUpdate( 'layoutCssUpdate', self.layoutId );
5583
+ self.codeHasUpdates = true;
5584
+ self._enablePreviewButton();
5585
+ self.settings.editor.delayedSubmitEnable(); // Enable the delayed submit since we have changes
5586
+ } );
5587
+ },
5588
+
5589
+ /**
5590
+ * Insert a tag
5591
+ * @since 3.0
5592
+ * @return null
5593
+ */
5594
+ _insertTag: function( e ) {
5595
+ var self = e.data.self,
5596
+ $tag = $( e.target ),
5597
+ text = $tag.text(),
5598
+ cursor = self.codeEditor.codemirror.getCursor();
5599
+
5600
+ self.codeEditor.codemirror.replaceRange( text, cursor );
5601
+
5602
+ // Move the cursor position
5603
+ cursor.ch = cursor.ch + text.length;
5604
+ self.codeEditor.codemirror.setCursor( cursor );
5605
+ //self.codeEditor.codemirror.trigger( 'focus' );
5606
+ },
5607
+
5608
+ /**
5609
+ * Return a specific setting
5610
+ * @since 3.0
5611
+ * @return null
5612
+ */
5613
+ _options: function ( key ) {
5614
+ return this.settings[key];
5615
+ },
5616
+
5617
+ /**
5618
+ * Setup triggers
5619
+ * @since 3.0
5620
+ * @return null
5621
+ */
5622
+ trigger: function ( fn, customParams ) {
5623
+ var params = [this.settings];
5624
+ if ( customParams ) {
5625
+ params = customParams;
5626
+ }
5627
+
5628
+ this.$elmt.trigger( 'ditty_layout_css_editor_panel_' + fn, params );
5629
+
5630
+ if ( typeof this.settings[fn] === 'function' ) {
5631
+ this.settings[fn].apply( this.$elmt, params );
5632
+ }
5633
+ },
5634
+
5635
+ /**
5636
+ * Allow settings to be modified
5637
+ * @since 3.0
5638
+ * @return null
5639
+ */
5640
+ options: function ( key, value ) {
5641
+ if ( typeof key === 'object' ) {
5642
+ this.settings = $.extend( {}, defaults, $.ditty_layout_css_editor_panel.defaults, key );
5643
+ } else if ( typeof key === 'string' ) {
5644
+ if ( value === undefined ) {
5645
+ return this.settings[key];
5646
+ }
5647
+ this.settings[key] = value;
5648
+ } else {
5649
+ return this.settings;
5650
+ }
5651
+ this.trigger( 'options_update' );
5652
+ },
5653
+
5654
+ /**
5655
+ * Destroy the class
5656
+ * @since 3.0
5657
+ * @return null
5658
+ */
5659
+ destroy: function () {
5660
+
5661
+ // Remove actions
5662
+ this.$back.off( 'click', { self: this }, this._backClick );
5663
+ this.$preview.off( 'click', { self: this }, this._previewClick );
5664
+ this.$editHtml.off( 'click', { self: this }, this._editHtml );
5665
+ this.$form.off( 'submit', { self: this }, this._submitForm );
5666
+ this.$form.off( 'click', '.ditty-editor-options__tag', { self: this }, this._insertTag );
5667
+ this.$title.off( 'keyup', { self: this }, this._titleUpdate );
5668
+ this.$body.off( 'click', '.ditty-editor-options__body__error', { self: this }, this._removeErrorNotice );
5669
+ this.settings.editor.$elmt.off( 'ditty_editor_add_drafts', { self: this }, this._addDrafts );
5670
+ this.settings.editor.$elmt.off( 'ditty_editor_save_drafts', { self: this }, this._saveDrafts );
5671
+ this.codeEditor.codemirror.off( 'change' );
5672
+ this.codeEditor.codemirror.toTextArea();
5673
+
5674
+ this.elmt._ditty_layout_css_editor_panel = null;
5675
+ }
5676
+ };
5677
+
5678
+ /**
5679
+ * Create the data list
5680
+ * @since 3.0
5681
+ * @return null
5682
+ */
5683
+ $.fn.ditty_layout_css_editor_panel = function( options ) {
5684
+ var args = arguments,
5685
+ error = false,
5686
+ returns;
5687
+
5688
+ if ( options === undefined || typeof options === 'object' ) {
5689
+ return this.each( function () {
5690
+ if ( ! this._ditty_layout_css_editor_panel ) {
5691
+ this._ditty_layout_css_editor_panel = new Ditty_Layout_Css_Editor_Panel( this, options );
5692
+ }
5693
+ });
5694
+ } else if ( typeof options === 'string' ) {
5695
+ this.each( function () {
5696
+ var instance = this._ditty_layout_css_editor_panel;
5697
+
5698
+ if ( ! instance ) {
5699
+ throw new Error( 'No Ditty_Layout_Css_Editor_Panel applied to this element.' );
5700
+ }
5701
+ if ( typeof instance[options] === 'function' && options[0] !== '_' ) {
5702
+ returns = instance[options].apply( instance, [].slice.call( args, 1 ) );
5703
+ } else {
5704
+ error = true;
5705
+ }
5706
+ } );
5707
+
5708
+ if ( error ) {
5709
+ throw new Error( 'No method "' + options + '" in Ditty_Layout_Css_Editor_Panel.' );
5710
+ }
5711
+
5712
+ return returns !== undefined ? returns : this;
5713
+ }
5714
+ };
5715
+
5716
+ $.ditty_layout_css_editor_panel = {};
5717
+ $.ditty_layout_css_editor_panel.defaults = defaults;
5718
+
5719
+ } )( jQuery );
5720
+
5721
+
5722
+ /* global dittyVars:true */
5723
+
5724
+ jQuery( document ).ready( function( $ ) {
5725
+
5726
+ // Setup strict mode
5727
+ (function() {
5728
+
5729
+ "use strict";
5730
+
5731
+ function modifyItemsPerPage( $perPage, pagingValue ) {
5732
+ if ( 0 === parseInt( pagingValue ) ) {
5733
+ $perPage.hide();
5734
+ } else {
5735
+ $perPage.show();
5736
+ }
5737
+ }
5738
+
5739
+ function modifyArrows( arrowSiblings, arrowsValue ) {
5740
+ if ( 'none' === arrowsValue ) {
5741
+ arrowSiblings.hide();
5742
+ } else {
5743
+ arrowSiblings.show();
5744
+ }
5745
+ }
5746
+
5747
+ function modifyBullets( bulletSiblings, bulletsValue ) {
5748
+ if ( 'none' === bulletsValue ) {
5749
+ bulletSiblings.hide();
5750
+ } else {
5751
+ bulletSiblings.show();
5752
+ }
5753
+ }
5754
+
5755
+ $( '#ditty-editor' ).on( 'ditty_display_editor_panel_init', '.ditty-editor__panel--displayEditor', function( e, editorPanel ) {
5756
+ if ( 'list' === editorPanel.displayType ) {
5757
+ var $form = editorPanel.$form,
5758
+ $perPage = $form.find( '.ditty-field--perPage' ),
5759
+ arrowSiblings = $form.find( '.ditty-field--arrows' ).siblings(),
5760
+ bulletSiblings = $form.find( '.ditty-field--bullets' ).siblings();
5761
+
5762
+ // Set paging
5763
+ modifyItemsPerPage( $perPage, $form.find( 'input[name="paging"]:checked' ).val() );
5764
+ $form.find( 'input[name="paging"]' ).on( 'change', function() {
5765
+ modifyItemsPerPage( $perPage, $( this ).val() );
5766
+ } );
5767
+
5768
+ // Set arrows
5769
+ modifyArrows( arrowSiblings, $form.find( 'select[name="arrows"]' ).val() );
5770
+ $form.find( 'select[name="arrows"]' ).on( 'change', function() {
5771
+ modifyArrows( arrowSiblings, $( this ).val() );
5772
+ } );
5773
+
5774
+ // Set bullets
5775
+ modifyBullets( bulletSiblings, $form.find( 'select[name="bullets"]' ).val() );
5776
+ $form.find( 'select[name="bullets"]' ).on( 'change', function() {
5777
+ modifyBullets( bulletSiblings, $( this ).val() );
5778
+ } );
5779
+ }
5780
+ } );
5781
+
5782
+ }() );
5783
+
5784
+ } );
includes/js/ditty-editor.min.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ function dittyEditorInit(t){if(!t)return!1;var i="auto-draft"===t.options("status")&&"settings";jQuery("#ditty-editor__settings").ditty_editor({ditty:t,panel:i})}function dittyGetItemsById(t,i){var e=[];return jQuery.each(t,(function(t,s){String(s.id)===String(i)&&e.push(s)})),e}function dittyItemsReorder(t,i){var e=[];return jQuery.each(i,(function(i,s){e=jQuery.merge(e,dittyGetItemsById(t,s))})),e}function dittyDraftUpdate(t,i,e,s){var a=t.settings.editor.getDraftValues(i);return a||(a={}),e?a[e]=s:a=s,t.settings.editor.updateDraftValues(i,a)}function dittyDraftGet(t,i,e){var s=t.settings.editor.getDraftValues(i);return!!s&&(e&&s[e]?s[e]:s)}function dittyDraftDelete(t,i,e){var s=i.settings.editor.getDraftValues(t),a={};return jQuery.each(s,(function(t,i){String(e)!==String(t)&&(a[t]=i)})),"new-"!==String(e).substring(0,4)&&(a[e]="DELETE"),i.settings.editor.updateDraftValues(t,a)}function dittyDraftItemDelete(t,i){return dittyDraftDelete("items",t,i)}function dittyDraftLayoutDelete(t,i){return dittyDraftDelete("layouts",t,i)}function dittyDraftDisplayDelete(t,i){return dittyDraftDelete("displays",t,i)}function dittyDraftItemUpdateData(t,i,e,s){var a=t.settings.editor.getDraftValues("items");return a||(a={}),a[i]||(a[i]={}),a[i].data||(a[i].data={}),e?a[i].data[e]=s:a[i].data=s,t.settings.editor.updateDraftValues("items",a)}function dittyDraftItemGetData(t,i,e){var s=t.settings.editor.getDraftValues("items");return!!s[i]&&(!!s[i].data&&(e?s[i].data[e]?s[i].data[e]:void 0:s[i].data))}function dittyDraftItemUpdateMeta(t,i,e,s){var a=t.settings.editor.getDraftValues("items");return a||(a={}),a[i]||(a[i]={}),a[i].meta||(a[i].meta={}),e?a[i].meta[e]=s:a[i].meta=s,t.settings.editor.updateDraftValues("items",a)}function dittyDraftItemGetMeta(t,i,e){var s=t.settings.editor.getDraftValues("items");return!!s[i]&&(!!s[i].meta&&(e?s[i].meta[e]?s[i].meta[e]:void 0:s[i].meta))}function dittyDraftLayoutUpdate(t,i,e,s){var a=t.settings.editor.getDraftValues("layouts");return a||(a={}),a[i]||(a[i]={}),e?a[i][e]=s:a[i]=s,t.settings.editor.updateDraftValues("layouts",a)}function dittyDraftLayoutGet(t,i,e){var s=t.settings.editor.getDraftValues("layouts");return!!s[i]&&(e?s[i][e]?s[i][e]:void 0:s[i])}function dittyDraftDisplayUpdate(t,i,e,s){var a=t.settings.editor.getDraftValues("displays");return a||(a={}),a[i]||(a[i]={}),e?a[i][e]=s:a[i]=s,t.settings.editor.updateDraftValues("displays",a)}function dittyDraftDisplayGet(t,i,e){var s=t.settings.editor.getDraftValues("layouts");return!!s[i]&&(e?s[i][e]?s[i][e]:void 0:s[i])}function dittyGetItemsById(t,i){var e=[];return jQuery.each(t,(function(t,s){String(s.id)===String(i)&&e.push(s)})),e}function dittyItemsReorder(t,i){var e=[];return jQuery.each(i,(function(i,s){e=jQuery.merge(e,dittyGetItemsById(t,s))})),e}function dittyDraftUpdate(t,i,e,s){var a=t.settings.editor.getDraftValues(i);return a||(a={}),e?a[e]=s:a=s,t.settings.editor.updateDraftValues(i,a)}function dittyDraftGet(t,i,e){var s=t.settings.editor.getDraftValues(i);return!!s&&(e&&s[e]?s[e]:s)}function dittyDraftDelete(t,i,e){var s=i.settings.editor.getDraftValues(t),a={};return jQuery.each(s,(function(t,i){String(e)!==String(t)&&(a[t]=i)})),"new-"!==String(e).substring(0,4)&&(a[e]="DELETE"),i.settings.editor.updateDraftValues(t,a)}function dittyDraftItemDelete(t,i){return dittyDraftDelete("items",t,i)}function dittyDraftLayoutDelete(t,i){return dittyDraftDelete("layouts",t,i)}function dittyDraftDisplayDelete(t,i){return dittyDraftDelete("displays",t,i)}function dittyDraftItemUpdateData(t,i,e,s){var a=t.settings.editor.getDraftValues("items");return a||(a={}),a[i]||(a[i]={}),a[i].data||(a[i].data={}),e?a[i].data[e]=s:a[i].data=s,t.settings.editor.updateDraftValues("items",a)}function dittyDraftItemGetData(t,i,e){var s=t.settings.editor.getDraftValues("items");return!!s[i]&&(!!s[i].data&&(e?s[i].data[e]?s[i].data[e]:void 0:s[i].data))}function dittyDraftItemUpdateMeta(t,i,e,s){var a=t.settings.editor.getDraftValues("items");return a||(a={}),a[i]||(a[i]={}),a[i].meta||(a[i].meta={}),e?a[i].meta[e]=s:a[i].meta=s,t.settings.editor.updateDraftValues("items",a)}function dittyDraftItemGetMeta(t,i,e){var s=t.settings.editor.getDraftValues("items");return!!s[i]&&(!!s[i].meta&&(e?s[i].meta[e]?s[i].meta[e]:void 0:s[i].meta))}function dittyDraftLayoutUpdate(t,i,e,s){var a=t.settings.editor.getDraftValues("layouts");return a||(a={}),a[i]||(a[i]={}),e?a[i][e]=s:a[i]=s,t.settings.editor.updateDraftValues("layouts",a)}function dittyDraftLayoutGet(t,i,e){var s=t.settings.editor.getDraftValues("layouts");return!!s[i]&&(e?s[i][e]?s[i][e]:void 0:s[i])}function dittyDraftDisplayUpdate(t,i,e,s){var a=t.settings.editor.getDraftValues("displays");return a||(a={}),a[i]||(a[i]={}),e?a[i][e]=s:a[i]=s,t.settings.editor.updateDraftValues("displays",a)}function dittyDraftDisplayGet(t,i,e){var s=t.settings.editor.getDraftValues("layouts");return!!s[i]&&(e?s[i][e]?s[i][e]:void 0:s[i])}jQuery(document).ready((function($){!function(){"use strict";$("body").on("ditty_editor_before_panel_update",(function(t,i,e,s,a,d){switch(d.delayedSubmitDisable(),$.protip({defaults:{position:"top",size:"small",scheme:"black",classes:"ditty-protip"}}),i){case"settings":e.hasClass("init")||e.ditty_settings_panel({editor:d});break;case"items":e.hasClass("init")?e.ditty_items_panel("panelVisible"):e.ditty_items_panel({editor:d});break;case"displays":e.find(".ditty-data-list__item").removeClass("editing"),e.hasClass("init")?e.ditty_displays_panel("panelVisible"):e.ditty_displays_panel({editor:d});break;case"item_types":e.find(".ditty-data-list__item").removeClass("editing"),e.hasClass("init")?e.ditty_item_types_panel("panelVisible"):e.ditty_item_types_panel({editor:d});break;case"item_editor":e.ditty_item_editor_panel({editor:d});break;case"display_editor":e.ditty_display_editor_panel({editor:d});break;case"layouts":"layoutHtmlEditor"!==s&&"layoutCssEditor"!==s&&e.ditty_layouts_panel({editor:d});break;case"layout_variations":e.hasClass("init")?e.ditty_layout_variations_panel("panelVisible"):e.ditty_layout_variations_panel({editor:d});break;case"layout_html_editor":e.ditty_layout_html_editor_panel({editor:d,prevPanel:s});break;case"layout_css_editor":e.ditty_layout_css_editor_panel({editor:d,prevPanel:s})}})),$("body").on("ditty_editor_panel_removed",(function(t,i,e){switch(i){case"item_editor":e.ditty_item_editor_panel&&e.ditty_item_editor_panel("destroy");break;case"display_editor":e.ditty_display_editor_panel&&e.ditty_display_editor_panel("destroy");break;case"layouts":case"layouts":e.ditty_layouts_panel&&e.ditty_layouts_panel("destroy");break;case"layout_variations":e.ditty_layout_variations_panel&&e.ditty_layout_variations_panel("destroy");break;case"layout_html_editor":e.ditty_layout_html_editor_panel&&e.ditty_layout_html_editor_panel("destroy");break;case"layout_css_editor":e.ditty_layout_css_editor_panel&&e.ditty_layout_css_editor_panel("destroy")}}))}()})),dittyEditorInit(),function($){"use strict";var t={listType:"toggle",showAll:!0,activeFilter:"*",filter:".ditty-data-list__filter",filterSelector:"filter",item:".ditty-data-list__item",itemSelector:"filter"},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_ui_data_list.defaults,e),this.$elmt=$(i),this.filters=[],this._init()};i.prototype={_init:function(){var t=this;this.$elmt.on("click",this.settings.filter,{self:this},this._filterClick),this.$elmt.find(this.settings.filter+".active").each((function(){t._filterList($(this).data(t.settings.filterSelector))})),"*"!==this.settings.activeFilter&&this._filterList(this.settings.activeFilter),setTimeout((function(){t.trigger("init")}),1)},_filterList:function(t){var i=this,e=this.filters;if("toggle"===this.settings.listType)this.filters.includes(t)?this.settings.showAll&&(this.filters=[],this.$elmt.find(this.settings.filter).removeClass("active"),this.$elmt.find(this.settings.item).show()):(this.filters=[t],this.$elmt.find(this.settings.filter).removeClass("active"),this.$elmt.find(this.settings.filter+"[data-"+this.settings.filterSelector+'="'+t+'"]').addClass("active"),this.$elmt.find(this.settings.item).hide(),this.$elmt.find(this.settings.item+"[data-"+this.settings.itemSelector+'="'+t+'"]').show());else if("filter"===this.settings.listType){if(this.$elmt.find(this.settings.item).hide(),this.filters.includes(t)){this.$elmt.find(this.settings.filter+"[data-"+this.settings.filterSelector+'="'+t+'"]').removeClass("active");for(var s=0;s<this.filters.length;s++)i.filters[s]===t&&i.filters.splice(s,1)}else this.$elmt.find(this.settings.filter+"[data-"+this.settings.filterSelector+'="'+t+'"]').addClass("active"),this.filters.push(t);$.each(this.filters,(function(t,e){i.$elmt.find(this.settings.item+"[data-"+this.settings.itemSelector+'="'+e+'"]').show()})),0===this.filters.length&&i.$elmt.find(this.settings.item).show()}e!==this.filters&&i.trigger("update")},_filterClick:function(t){t.preventDefault();var i=t.data.self,e=$(t.target);e.is("a")||(e=e.parents("a")),i._filterList(e.data(i.settings.filterSelector))},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings,this.filters];i&&(e=i),this.$elmt.trigger("ditty_ui_data_list_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_ui_data_list.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.off("click",this.settings.filter,{self:this},this._filterClick),this.trigger("destroy"),this.elmt._ditty_ui_data_list=null}},$.fn.ditty_ui_data_list=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_ui_data_list||(this._ditty_ui_data_list=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_ui_data_list;if(!i)throw new Error("No Ditty_UI_Data_List applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_UI_Data_List.');return void 0!==e?e:this}},$.ditty_ui_data_list={},$.ditty_ui_data_list.defaults=t}(jQuery),function($){"use strict";var t={screen:"admin",ditty:null,panel:""},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_editor.defaults,e),this.$elmt=$(i),this.ditty=this.settings.ditty,this.dittyId=this.settings.ditty.options("id"),this.dittyType=this.settings.ditty.options("type"),this.displayId=0,this.panelsLoaded=0,this.unsavedUpdates={},this.draftValues={},this.$overlay=null,this.$contents=null,this.$header=null,this.$update=null,this.$updateCount=null,this.$updateLabel=null,this.$tabs=null,this.$panels=null,this.currentTab=0,this.currentPanel=this.settings.panel,this.delayedSubmit=!1,this.tabs=[],this.panels=[],this.activeItems=[],this._init()};i.prototype={_init:function(){var t,i,e,s,a,d,r,o=this;t=$('<div class="ditty-editor__contents"></div>'),this.$contents=t,i=$('<div class="ditty-editor__header"></div>'),this.$header=i,e=$('<span class="ditty-editor__update__count"></span>'),this.$updateCount=e,s=$('<span class="ditty-editor__update__label">Save Ditty</span>'),this.$updateLabel=s,a=$('<button type="submit" class="ditty-editor__update ditty-button ditty-button--primary"></button>'),this.$update=a,d=$('<div class="ditty-editor__tabs"></div>'),this.$tabs=d,r=$('<div class="ditty-editor__panels"></div>'),this.$panels=r,a.prepend(e,s),i.append(a),t.append(i,d,r),this.$elmt.append(t),this.$overlay=$('<div class="ditty-updating-overlay ditty-admin-item__overlay"><div class="ditty-updating-overlay__inner"><i class="fas fa-sync-alt fa-spin"></i></div></div>'),this.$elmt.append(this.$overlay),$(document).on("postbox-moved",{self:this},this._postboxMoved),$(document).on("postboxes-columnchange",{self:this},this._postboxMoved),$(window).on("beforeunload",{self:this},this._beforeunload),this.ditty.$elmt.on("ditty_active_items_update",{self:this},this._dittyItemsUpdated),this.ditty.$elmt.on("ditty_disabled_items_update",{self:this},this._disabledItemsUpdate),this.$tabs.on("click",".ditty-editor__tab",{self:this},this._showPanel),this.$update.on("click",{self:this},this._saveClick),this.$panels.on("ditty_slider_init",{self:this},this._editorLoaded),this.$panels.on("ditty_slider_before_slide_update",{self:this},this._beforeSlideUpdate),this.$panels.on("ditty_slider_after_slide_update",{self:this},this._afterSlideUpdate),this.$panels.on("ditty_slider_slide_removed",{self:this},this._slideRemoved),this._loadContents(),this.trigger("stop_live_updates"),setTimeout((function(){o.trigger("init")}),1)},_loadContents:function(){var t=this,i={action:"ditty_editor_load_contents",ditty_id:this.dittyId,security:dittyVars.security};$.post(dittyVars.ajaxurl,i,(function(i){t._initTabs(i.tabs),t._initPanels(i.panels),t._initSlider()}),"json")},_editorLoaded:function(t){var i=t.data.self;$("body").trigger("ditty_editor_loaded",[i])},_setUpdateCount:function(){},_initSlider:function(){var t=this.tabs[0].id;this.currentPanel&&""!==this.currentPanel&&(t=this.currentPanel),this.$panels.ditty_slider({transition:"fade",transitionSpeed:.75,heightSpeed:.75,touchSwipe:!1,slides:this.panels,slideId:t})},_beforeSlideUpdate:function(t,i,e,s,a){var d=t.data.self;d.updateStart(),d._updateTab(e.id),$("body").trigger("ditty_editor_before_panel_update",[e.id,e.$elmt,a.id,a.$elmt,d])},_afterSlideUpdate:function(t,i,e,s,a){var d=t.data.self;d.updateStop(),$("body").trigger("ditty_editor_after_panel_update",[e.id,e.$elmt,a.id,a.$elmt,d])},_slideRemoved:function(t,i){var e=t.data.self;$("body").trigger("ditty_editor_panel_removed",[i.id,i.$elmt,e])},_showPanel:function(t){t.preventDefault();var i=t.data.self,e=$(t.target).is("a")?$(t.target):$(t.target).parent("a"),s=e.data("panel"),a=parseInt(e.data("index"));if(s===i.currentTab)return!1;var d=a>i.currentTab?"slideLeft":"slideRight";i.$panels.ditty_slider("options","transition",d),i.$panels.ditty_slider("showSlideById",s),i.currentTab=a,i.$elmt.trigger("ditty_editor_add_drafts")},_updateTab:function(t){var i=$('.ditty-editor__tab[data-panel="'+t+'"]');void 0!==i[0]&&($(".ditty-editor__tab").removeClass("active"),i.addClass("active"),this.currentTab=parseInt(i.data("index")))},_initTabs:function(t){var i=this,e=0;$.each(t,(function(t,s){var a=$('<a href="#" class="ditty-editor__tab ditty-editor__tab--'+t+'" data-panel="'+t+'" data-index="'+e+'"><i class="'+s.icon+'"></i><span>'+s.label+"</span></a>");i.$tabs.append(a),i.tabs.push({id:t,tab:a}),e++}))},_initPanels:function(t){var i=this;$.each(t,(function(t,e){var s='<div class="ditty-editor__panel ditty-editor__panel--'+t+'">'+e+"</div>";i.panels.push({id:t,html:s,cache:!0})}))},_initFields:function(t){t.find(".ditty-data-list").ditty_ui_data_list(),t.trigger("ditty_init_fields"),$.protip({defaults:{position:"top",size:"small",scheme:"black",classes:"ditty-protip"}})},saveDitty:function(t){var i=this,e=i.dittyId;i.$updateLabel.text("Updating..."),i.updateStart();var s={action:"ditty_editor_save",ditty_id:e,draft_values:i.draftValues,return_items:1,security:dittyVars.security};s=$.extend({},s,t),$.post(dittyVars.ajaxurl,s,(function(t){$("body").trigger("ditty_editor_save_ditty_response",[t]),t.display_items&&i.ditty.options("items",t.display_items),i.draftValues={},i.unsavedUpdates={},i._setUpdateCount(),i.$elmt.removeClass("ditty-editor--updates-exist"),i.$updateLabel.text("Ditty Saved!"),setTimeout((function(){i.$updateLabel.text("Save Ditty")}),2e3),i.updateStop(),t.new_ditty_url&&window.history.pushState(null,"","/wp-admin/post.php?post="+e+"&action=edit")}))},_saveClick:function(t){t.preventDefault();var i=t.data.self;i.$elmt.trigger("ditty_editor_save_drafts"),i.delayedSubmit||i.saveDitty()},_dittyItemsUpdated:function(t,i,e){var s=t.data.self;s.activeItems=e,s.trigger("active_items_update")},_disabledItemsUpdate:function(t,i){var e=t.data.self;$.each(i,(function(t,i){"disabled"===i?e.$elmt.find("#ditty-editor-item--"+t).addClass("ditty-editor-item--disabled"):e.$elmt.find("#ditty-editor-item--"+t).removeClass("ditty-editor-item--disabled")}))},_postboxMoved:function(t,i){if(!window.tinymce)return!1;$(i).find(".wp-editor-area").each((function(){var t=$(this).attr("id");tinymce.execCommand("mceRemoveEditor",!0,t),tinymce.execCommand("mceAddEditor",!0,t)}))},_beforeunload:function(t){var i=t.data.self;return Object.keys(i.unsavedUpdates).length>0||void 0},_windowResize:function(t){t.preventDefault()},_options:function(t){return this.settings[t]},panelExists:function(t){var i=this.$panels.ditty_slider("options","slides"),e=!1;return $.each(i,(function(i,s){String(s.id)!==String(t)||(e=!0)})),e},showPanel:function(t,i){i&&this.$panels.ditty_slider("addSlideById",t,i),this.$panels.ditty_slider("showSlideById",t,!0)},updateExists:function(t,i){if(void 0===this.unsavedUpdates[t]&&(this.unsavedUpdates[t]=[]),-1!==$.inArray(i,this.unsavedUpdates[t]))return!0},addUpdate:function(t,i){var e=!1;return void 0===this.unsavedUpdates[t]&&(this.unsavedUpdates[t]=[]),-1===$.inArray(i,this.unsavedUpdates[t])&&(e=!0,this.unsavedUpdates[t].push(i)),this._setUpdateCount(),this.$elmt.addClass("ditty-editor--updates-exist"),e},removeUpdate:function(t,i){if(void 0===this.unsavedUpdates[t])return!1;if(-1===$.inArray(i,this.unsavedUpdates[t]))return!1;var e=!1,s=[];return $.each(this.unsavedUpdates[t],(function(t,a){String(i)===String(a)?e=!0:s.push(a)})),this.unsavedUpdates[t]=s,this._setUpdateCount(),""===this.$updateCount.text()&&this.$elmt.removeClass("ditty-editor--updates-exist"),e},updateStart:function(){this.$overlay.fadeIn()},updateStop:function(){this.$overlay.fadeOut()},initFields:function(t){this._initFields(t)},updateDraftValues:function(t,i){return this.$elmt.addClass("ditty-editor--updates-exist"),t?(this.draftValues[t]=i,"development"===dittyVars.mode&&window.console&&console.log("draftValues:",this.draftValues),this.draftValues[t]):(this.draftValues=i,"development"===dittyVars.mode&&window.console&&console.log("draftValues:",this.draftValues),this.draftValues)},getDraftValues:function(t){return t?!!this.draftValues[t]&&this.draftValues[t]:this.draftValues},delayedSubmitEnable:function(){this.delayedSubmit=!0},delayedSubmitDisable:function(){this.delayedSubmit=!1},trigger:function(t,i){var e=[];switch(t){case"active_items_update":e=[this.ditty,this.activeItems];break;case"stop_live_updates":e=[this.dittyId];break;default:e=[this.settings]}i&&(e=i),this.$elmt.trigger("ditty_editor_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e),$("body").trigger("ditty_"+t,e)},_getPanelOption:function(t){return"elmnt"===t?this.$panels:this.settings[t]},_setPanelOption:function(t,i){if(void 0===i)return!1;this.$panels.ditty_slider("options",t,i),this.trigger("update")},panelOptions:function(t,i){var e=this;if("object"==typeof t)$.each(t,(function(t,i){e._setPanelOption(t,i)}));else{if("string"!=typeof t)return e.$panels.ditty_slider("options");if(void 0===i)return e._getPanelOption(t);e._setPanelOption(t,i)}},_getOption:function(t){return"elmnt"===t?this:this.settings[t]},_setOption:function(t,i){if(void 0===i)return!1;this.settings[t]=i,this.trigger("update")},options:function(t,i){var e=this;if("object"==typeof t)$.each(t,(function(t,i){e._setOption(t,i)}));else{if("string"!=typeof t)return e.settings;if(void 0===i)return e._getOption(t);e._setOption(t,i)}},destroy:function(){this.$panels.ditty_slider&&this.$panels.ditty_slider("destroy"),$(document).off("postbox-moved",{self:this},this._postboxMoved),$(document).off("postboxes-columnchange",{self:this},this._postboxMoved),$(window).off("beforeunload",{self:this},this._beforeunload),this.ditty.$elmt.off("ditty_active_items_update",{self:this},this._dittyItemsUpdated),this.ditty.$elmt.off("ditty_disabled_items_update",{self:this},this._disabledItemsUpdate),this.$tabs.off("click","ditty-editor__tab",{self:this},this._showPanel),this.$update.off("click",{self:this},this._saveClick),this.$panels.off("ditty_slider_init",{self:this},this._editorLoaded),this.$panels.off("ditty_slider_before_slide_update",{self:this},this._beforeSlideUpdate),this.$panels.off("ditty_slider_after_slide_update",{self:this},this._afterSlideUpdate),this.$panels.off("ditty_slider_slide_removed",{self:this},this._slideRemoved),this.trigger("destroy"),this.elmt._ditty_editor=null}},$.fn.ditty_editor=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_editor||(this._ditty_editor=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_editor;if(!i)throw new Error("No Ditty_Editor applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Editor.');return void 0!==e?e:this}},$.ditty_editor={},$.ditty_editor.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_settings_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$title=this.$elmt.find('input[name="title]'),this.$previewBg=this.$elmt.find('input[name="previewBg"]'),this.$previewPaddingTop=this.$elmt.find('input[name="previewPadding[paddingTop]"]'),this.$previewPaddingBottom=this.$elmt.find('input[name="previewPadding[paddingBottom]"]'),this.$previewPaddingLeft=this.$elmt.find('input[name="previewPadding[paddingLeft]"]'),this.$previewPaddingRight=this.$elmt.find('input[name="previewPadding[paddingRight]"]'),this.$postTitle=$(".ditty-post__title"),this.$editorPreview=$("#ditty-editor__preview"),this.dittyId=this.$form.data("ditty_id"),this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this.settings.editor.initFields(this.$elmt),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.on("submit",{self:this},this._submitForm),this.$form.on("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.on("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.on("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.$form.on("keyup change",'input[name="title"]',{self:this},this._titleChange),this.$form.on("keyup change",".ditty-field--preview_settings *",{self:this},this._previewBgChange),this.$elmt.addClass("init")},_checkUpdates:function(t){var i=t?t.data.self:this;i.$form.serialize()!==i.initData?(i.settings.editor.addUpdate("settings",i.itemId),i.settings.editor.delayedSubmitEnable()):i.settings.editor.removeUpdate("settings",i.itemId)},_titleChange:function(t){var i=t?t.data.self:this,e=$(t.target).val();i.$postTitle.text(e)},_previewBgChange:function(t){var i=t?t.data.self:this,e={backgroundColor:i.$previewBg.val(),paddingTop:i.$previewPaddingTop.val(),paddingBottom:i.$previewPaddingBottom.val(),paddingLeft:i.$previewPaddingLeft.val(),paddingRight:i.$previewPaddingRight.val()};i.$editorPreview.css(e)},_addDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.dittyId;i.settings.editor.updateStart();var s={action:"ditty_editor_settings_update",ditty_id:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:s,success:function(t){i.initData=i.$form.serialize(),dittyDraftUpdate(i,"settings",!1,t),i.settings.editor.delayedSubmitDisable(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty({return_items:0}),i.afterUpdateAction=""}})},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_settings_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_settings_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._addDrafts),this.$form.off("submit",{self:this},this._submitForm),this.$form.off("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.off("keyup change",'input[name="previewBg"]',{self:this},this._previewBg_cahnge),this.$form.off("keyup change",'input[name="title"]',{self:this},this._titleChange),this.$form.off("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.off("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.trigger("destroy"),this.elmt._ditty_settings_panel=null}},$.fn.ditty_settings_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_settings_panel||(this._ditty_settings_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_settings_panel;if(!i)throw new Error("No Ditty_Settings_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Settings_Panel.');return void 0!==e?e:this}},$.ditty_settings_panel={},$.ditty_settings_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_items_panel.defaults,e),this.$elmt=$(i),this.$add=$(i).find(".ditty-editor-options__add"),this.$contents=$(i).find(".ditty-editor__panel__contents"),this.$list=$(i).find(".ditty-data-list"),this.$listItems=$(i).find(".ditty-data-list__items"),this.isEmptyTicker=!1,this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.settings.editor.$elmt.on("ditty_editor_aactive_items_update",{self:this},this._dittyActiveItemsUpdated),this.$add.on("click",{self:this},this._add_item),this.$elmt.on("click",".ditty-data-list__item",{self:this},this._showItem),this.$elmt.on("click",".ditty-data-list__item__icon",{self:this},this._editType),this.$elmt.on("click",".ditty-data-list__item__edit",{self:this},this._editItem),this.$elmt.on("click",".ditty-data-list__item__layout",{self:this},this._editLayoutVariations),this.$elmt.on("click",".ditty-data-list__item__clone",{self:this},this._cloneItem),this.$elmt.on("click",".ditty-data-list__item__delete",{self:this},this._deleteItem),this.$list.on("click",".ditty-editor-item > a",{self:this},this._actionClick),$("body").on("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),1>this.$elmt.find(".ditty-data-list__item").length&&(this.isEmptyTicker=!0,this.$add.trigger("click")),this._initializeSorting(),this._highlightListItems(this.settings.editor.activeItems)},dittyUpdateSavedDraftLayouts:function(t,i){$.each($(".ditty-editor-item"),(function(){var e=$(this).data("layout_value");$.each(e,(function(s,a){String(a)===String(t)&&(e[s]=String(i))})),$(this).attr("data-layout_value",e).data("layout_value",e)}))},_dittyEditorSaveResponse:function(t,i){var e=t.data.self;i.ditty_new_item_ids&&$.each(i.ditty_new_item_ids,(function(t,i){var e=$("#ditty-editor-item--"+t);e.length&&(e.attr("id","ditty-editor-item--"+i),e.attr("data-item_id",i).data("item_id",i))})),i.ditty_new_layout_ids&&$.each(i.ditty_new_layout_ids,(function(t,i){e.dittyUpdateSavedDraftLayouts(t,i)}))},_highlightListItem:function(t){var i=t.id+"";i=i.split("_"),this.$elmt.find("#ditty-editor-item--"+i[0]).addClass("active")},_highlightListItems:function(t){this.$elmt.find(".ditty-data-list__item").removeClass("active");var i=this;Array.isArray(t)?$.each(t,(function(t,e){i._highlightListItem(e)})):i._highlightListItem(t)},_dittyActiveItemsUpdated:function(t,i,e){t.data.self._highlightListItems(e)},_initializeSorting:function(){var t=this;this.$listItems.sortable({handle:".ditty-data-list__item__move",items:".ditty-data-list__item",axis:"y",start:function(t,i){$(i.item).addClass("ditty-data-list__item--moving")},stop:function(i,e){$(e.item).removeClass("ditty-data-list__item--moving"),t.settings.editor.addUpdate("item_order",t.settings.editor.dittyId)},update:function(){t._updateItemIndexes("updateDitty")}})},_showItem:function(t){t.preventDefault();var i=t.data.self;if(!$(t.target).is("a")&&!$(t.target).parent().is("a")){var e=($(t.target).is(".ditty-data-list__item")?$(t.target):$(t.target).parents(".ditty-data-list__item")).data("item_id");i.settings.editor.ditty.showItem(e)}},_actionClick:function(t){t.preventDefault();var i=t.data.self,e=$(t.target).is("a")?$(t.target):$(t.target).parent("a"),s=e.parents(".ditty-data-list__item"),a=s.data("ditty_id"),d=s.data("item_id");dittyVars.editor.currentItem=s,$("body").trigger("ditty_editor_item_action_click",[e,s,d,a,i.settings.editor])},_editType:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item");e.trigger("click"),e.addClass("editing"),i.settings.editor.updateStart(),i.settings.editor.panelOptions("transition","slideRight"),i.settings.editor.showPanel("item_types")},_editItem:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_id");e.trigger("click"),e.addClass("editing"),i.settings.editor.updateStart();var a={action:"ditty_editor_item_fields",item_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--item_editor">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("item_editor",e)}}))},_editLayoutVariations:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_type"),a=e.data("layout_value"),d=e.find(".ditty-data-list__item__label").html();e.trigger("click"),e.addClass("editing"),i.settings.editor.updateStart();var r={action:"ditty_editor_layout_variations",ditty_id:i.settings.editor.dittyId,item_type:s,item_label:d,layout_value:a,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,r,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--layout-variations">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("layout_variations",e)}}))},_add_item:function(t){t.preventDefault();var i=t.data.self,e={action:"ditty_editor_item_add",ditty_id:i.settings.editor.dittyId,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,e,(function(t){if(t.display_items){if(i.isEmptyTicker){var e=i.settings.editor.ditty.options("items");$.each(e,(function(t,e){i.settings.editor.ditty.deleteItem(e.id)})),i.isEmptyTicker=!1}$.each(t.display_items,(function(t,e){i.settings.editor.ditty.addItem(e,0)}))}if(t.editor_item){var s=$(t.editor_item);s.hide(),i.$listItems.prepend(s),s.slideDown(),i._updateItemIndexes()}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),t.draft_id&&t.draft_meta&&dittyDraftItemUpdateMeta(i,t.draft_id,null,t.draft_meta)}),"json")},_cloneItem:function(t){t.preventDefault()
2
+ ;var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_id");i.settings.editor.updateStart();var a={action:"ditty_editor_item_clone",item_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t.display_items&&t.display_items.length&&i.settings.editor.ditty.updateItems(t.display_items,s,"after"),t.editor_item){var a=$(t.editor_item);a.hide(),e.after(a),a.slideDown(),i._updateItemIndexes()}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),t.draft_id&&t.draft_meta&&dittyDraftItemUpdateMeta(i,t.draft_id,null,t.draft_meta),i.settings.editor.updateStop()}),"json")},_deleteItem:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_id");1>=i.$elmt.find(".ditty-data-list__item").length&&i.$add.trigger("click"),e.slideUp((function(){$(this).remove()})),i.settings.editor.ditty.deleteItem(s),dittyDraftItemDelete(i,s)},_updateItemIndexes:function(t){var i=this,e=[];if(this.$elmt.find(".ditty-data-list__item").each((function(t){var s=$(this).data("item_id");e.push(s),dittyDraftItemUpdateData(i,s,"item_index",t)})),"updateDitty"===t){var s=dittyItemsReorder(i.settings.editor.ditty.options("items"),e);i.settings.editor.ditty.options("items",s)}},panelVisible:function(){this.$elmt.find(".ditty-data-list__item").removeClass("editing")},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_items_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_items_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.settings.editor.$elmt.off("ditty_editor_active_items_update",{self:this},this._dittyActiveItemsUpdated),this.$add.off("click",{self:this},this._add_item),this.$elmt.off("click",".ditty-data-list__item",{self:this},this._showItem),this.$elmt.off("click",".ditty-data-list__item__icon",{self:this},this._editType),this.$elmt.off("click",".ditty-data-list__item__edit",{self:this},this._editItem),this.$elmt.off("click",".ditty-data-list__item__layout",{self:this},this._editLayoutVariations),this.$elmt.off("click",".ditty-data-list__item__clone",{self:this},this._cloneItem),this.$elmt.off("click",".ditty-data-list__item__delete",{self:this},this._deleteItem),this.$list.off("click",".ditty-editor-item > a",{self:this},this._actionClick),$("body").off("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),this.trigger("destroy"),this.elmt._ditty_items_panel=null}},$.fn.ditty_items_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_items_panel||(this._ditty_items_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_items_panel;if(!i)throw new Error("No Ditty_Items_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Items_Panel.');return void 0!==e?e:this}},$.ditty_items_panel={},$.ditty_items_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_item_types_panel.defaults,e),this.$elmt=$(i),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$editorItem=this.settings.editor.$panels.find(".ditty-editor__panel--items").find(".ditty-data-list__item.editing"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.currentType=null,this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.settings.editor.initFields(this.$elmt),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("click",".ditty-editor-item-type",{self:this},this._typeClick),this.panelVisible()},_showItemsList:function(){this.settings.editor.panelOptions("transition","slideLeft"),this.settings.editor.showPanel("items")},_backClick:function(t){t.preventDefault(),t.data.self._showItemsList()},_typeClick:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is(".ditty-editor-item-type")?$(t.target):$(t.target).parents(".ditty-editor-item-type")).data("item_type");if(e===i.currentType)i._showItemsList();else{i.settings.editor.updateStart();var s={action:"ditty_editor_item_type_update",item_id:i.editorItemId,item_type:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,s,(function(t){if(t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,i.editorItemId),t.editor_item){var e=$(t.editor_item);i.$editorItem.after(e),i.$editorItem.remove(),i.$editorItem=e}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),i._showItemsList(),i.settings.editor.updateStop()}),"json")}},panelVisible:function(){this.$editorItem=this.settings.editor.$panels.find(".ditty-editor__panel--items").find(".ditty-data-list__item.editing"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.currentType=this.$editorItem.data("item_type"),this.$elmt.find(".ditty-editor-item-type").removeClass("active"),this.$elmt.find('.ditty-editor-item-type[data-itemType="'+this.currentType+'"]').addClass("active")},panelHidden:function(){var t=this.$editorItem.find(".ditty-data-list__item__icon").children("i");t.attr("class",t.data("class"))},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_item_types_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_item_types_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$back.off("click",{self:this},this._backClick),this.$elmt.off("click",".ditty-editor-item-type",{self:this},this._typeClick),this.trigger("destroy"),this.elmt._ditty_item_types_panel=null}},$.fn.ditty_item_types_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_item_types_panel||(this._ditty_item_types_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_item_types_panel;if(!i)throw new Error("No Ditty_Item_Types_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Item_Types_Panel.');return void 0!==e?e:this}},$.ditty_item_types_panel={},$.ditty_item_types_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_item_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$preview=this.$elmt.find(".ditty-editor-options__preview"),this.$title=this.$elmt.find(".ditty-editor-options__title"),this.itemId=this.$form.data("item_id"),this.itemType=this.$form.data("item_type"),this.dittyId=this.$form.data("ditty_id"),this.$editorItem=this.settings.editor.$panels.find(".ditty-editor__panel--items").find(".ditty-data-list__item.editing"),this.$editorItemTitle=this.$editorItem.find(".ditty-data-list__item__label"),this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this.settings.editor.initFields(this.$elmt),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.on("submit",{self:this},this._submitForm),this.$back.on("click",{self:this},this._backClick),this.$preview.on("click",{self:this},this._previewClick),this.$form.on("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.on("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.on("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.$form.on("ditty_field_update",".ditty-field__input",{self:this},this._checkUpdates)},_showItemList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","items")},_enablePreviewButton:function(){this.$preview.addClass("ditty-has-updates")},_disablePreviewButton:function(){this.$preview.removeClass("ditty-has-updates"),this.$preview.children("i").attr("class",this.$preview.children("i").data("class"))},_checkUpdates:function(t){var i=t?t.data.self:this;i.$form.serialize()!==i.initData?(i._enablePreviewButton(),i.settings.editor.addUpdate("item_settings",i.itemId),i.settings.editor.delayedSubmitEnable()):(i._disablePreviewButton(),i.settings.editor.removeUpdate("item_settings",i.itemId))},_addDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.$form.serialize()===i.initData?i._showItemList():(i.afterUpdateAction="return",i.$form.trigger("submit"))},_previewClick:function(t){t.preventDefault();var i=t.data.self;i.$form.serialize()!==i.initData&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit"))},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.itemId;i.settings.editor.updateStart();var s={action:"ditty_editor_item_update",item_id:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:s,error:function(){},success:function(t){if(t.value_updates&&i._updateValues(t.value_updates),i.initData=i.$form.serialize(),i._disablePreviewButton(),t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,e),t.editor_item){var s=$(t.editor_item).children(".ditty-data-list__item__label").text();i.$title.html(s),i.$editorItemTitle.html(s)}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),t.draft_id&&t.draft_meta&&dittyDraftItemUpdateMeta(i,t.draft_id,null,t.draft_meta),i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showItemList(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty({return_items:0}),i.afterUpdateAction=""}})},_updateValues:function(t){var i=this;$.each(t,(function(t,e){var s=i.$form.find('[name="'+t+'"]');s.length&&s.val(e)}))},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_item_editor_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_item_editor_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._saveDrafts),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.off("submit",{self:this},this._submitForm),this.$back.off("click",{self:this},this._backClick),this.$preview.off("click",{self:this},this._previewClick),this.$form.off("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.off("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.off("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.$form.off("ditty_field_update",".ditty-field__input",{self:this},this._checkUpdates),this.elmt._ditty_item_editor_panel=null}},$.fn.ditty_item_editor_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_item_editor_panel||(this._ditty_item_editor_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_item_editor_panel;if(!i)throw new Error("No Ditty_Item_Editor_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Item_Editor_Panel.');return void 0!==e?e:this}},$.ditty_item_editor_panel={},$.ditty_item_editor_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_displays_panel.defaults,e),this.$elmt=$(i),this.$list=$(i).find(".ditty-data-list__items"),this.$contents=$(i).find(".ditty-editor__panel__contents"),this.initDisplay=null,this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.$elmt.ditty_ui_data_list({filter:".ditty-display-panel__filter",item:".ditty-editor-display",itemSelector:"display_type"}),this.initDisplay=this.$list.data("active"),this._activateDisplay(this.$list.find("#ditty-editor-display--"+this.initDisplay)),this.$elmt.on("click",".ditty-data-list__item",{self:this},this._selectDisplay),this.$elmt.on("click",".ditty-data-list__item__edit",{self:this},this._editDisplay),this.$elmt.on("click",".ditty-data-list__item__clone",{self:this},this._cloneDisplay),this.$elmt.on("click",".ditty-data-list__item__delete",{self:this},this._deleteDisplay),this.settings.editor.$elmt.on("ditty_editor_saveDrafts",{self:this},this._saveDrafts)},_saveDrafts:function(t){var i=t.data.self;i.initDisplay=i.$list.find(".ditty-editor-display.active").data("display_id")},_activateDisplay:function(t){this.$list.find(".ditty-editor-display").removeClass("active"),t.addClass("active")},_initDitty:function(t,i,e){var s=this.settings.editor.ditty.$elmt;e.display=i,e.id=this.settings.editor.ditty.options("id"),e.items=this.settings.editor.ditty.options("items"),e.height=this.settings.editor.ditty.options("height"),this.settings.editor.ditty.destroy(),s["ditty_"+t](e),this.settings.editor.ditty=s["ditty_"+t]("options","ditty")},_selectDisplay:function(t){t.preventDefault();var i=t.data.self;if($(t.target).parent().is("a"))return!1;var e=$(t.target).is(".ditty-data-list__item")?$(t.target):$(t.target).parents(".ditty-data-list__item"),s=e.data("display_id"),a=e.data("display_type");if(e.hasClass("active"))return!1;i.settings.editor.updateStart(),dittyDraftUpdate(i,"post_meta","_ditty_display",s),i._activateDisplay(e);var d={action:"ditty_editor_select_display",display_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,d,(function(t){if(!t)return!1;i._initDitty(a,s,t),i.settings.editor.updateStop()}),"json")},_cloneDisplay:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("display_id");i.settings.editor.updateStart();var a={action:"ditty_editor_display_clone",display_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t.editor_display){var s=$(t.editor_display);s.hide(),e.after(s),s.slideDown()}t.draft_id&&t.draft_data&&dittyDraftDisplayUpdate(i,t.draft_id,null,t.draft_data),i.settings.editor.updateStop()}),"json")},_deleteDisplay:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=null,a=e.data("display_id");e.hasClass("active")&&(e.prev().length?s=e.prev():e.next().length&&(s=e.next())),e.slideUp((function(){$(this).remove()})),dittyDraftDisplayDelete(i,a),null!==s&&s.trigger("click")},_editDisplay:function(t){t.preventDefault();var i=t.data.self;i.$displayEdit=$(this).parents(".ditty-data-list__item");var e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("display_id");i.settings.editor.updateStart(),e.addClass("editing");var a={action:"ditty_editor_display_fields",display_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--displayEditor">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("display_editor",e)}}))},panelVisible:function(){this.$elmt.find(".ditty-data-list__item").removeClass("editing")},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_displays_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_displays_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$elmt.ditty_ui_data_list("destroy"),this.$elmt.off("click",".ditty-data-list__item",{self:this},this._selectDisplay),this.$elmt.off("click",".ditty-data-list__item__edit",{self:this},this._editDisplay),this.$elmt.off("click",".ditty-data-list__item__clone",{self:this},this._cloneDisplay),this.$elmt.off("click",".ditty-data-list__item__delete",{self:this},this._deleteDisplay),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.trigger("destroy"),this.elmt._ditty_displays_panel=null}},$.fn.ditty_displays_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_displays_panel||(this._ditty_displays_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_displays_panel;if(!i)throw new Error("No Ditty_Displays_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Displays_Panel.');return void 0!==e?e:this}},$.ditty_displays_panel={},$.ditty_displays_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_display_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$optionsTitle=this.$elmt.find(".ditty-editor-options__title"),this.$importExportField=this.$elmt.find(".ditty-editor__import-export__field"),this.$importExportUpdate=this.$elmt.find(".ditty-editor__import-export__update"),this.displayTitle=null,this.displayId=this.settings.editor.ditty.options("display"),this.displayType=this.settings.editor.ditty.options("type"),this.$editorDisplay=this.settings.editor.$panels.find(".ditty-editor__panel--displays").find(".ditty-data-list__item.editing"),this.$editorDisplayTitle=this.$editorDisplay.find(".ditty-data-list__item__label"),this.displayOptions=null,this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){var t,i=this;this.initData=this.$form.serialize(),this.settings.editor.initFields(this.$elmt),t=this.settings.editor.ditty.$elmt["ditty_"+this.displayType]("options"),this.displayOptions=$.extend({},t),this.displayTitle=this.$optionsTitle.val(),this.$importExportUpdate.on("click",{self:this},this._importUpdate),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.on("submit",{self:this},this._submitForm),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("change",'input[type="text"], input[type="number"]',{self:this},this._textfieldListeners),this.$form.on("click",'input[type="radio"]',{self:this},this._radioListeners),this.$form.on("click",'input[type="checkbox"]',{self:this},this._checkboxListeners),this.$form.on("change","select",{self:this},this._selectListeners),this.$form.on("ditty_field_clone_update",{self:this},this._cloneListeners),setTimeout((function(){i.trigger("init",[i])}),1)},_showDisplayList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","displays")},_checkUpdates:function(){this.$form.serialize()!==this.initData?(this.settings.editor.addUpdate("displaySettings",this.displayId),this.settings.editor.delayedSubmitEnable()):this.settings.editor.removeUpdate("displaySettings",this.displayId)},_addDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.$form.serialize()===i.initData?i._showDisplayList():(i.afterUpdateAction="return",i.$form.trigger("submit"))},_submitForm:function(t){t.preventDefault();var i=t.data.self;i.settings.editor.updateStart();var e={action:"ditty_editor_display_update",display_id:i.displayId,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:e,success:function(t){i.initData=i.$form.serialize(),t.draft_id&&t.draft_label&&(i.displayTitle=t.draft_label,i.$editorDisplayTitle.text(t.draft_label),dittyDraftDisplayUpdate(i,t.draft_id,"label",t.draft_label)),t.draft_id&&t.draft_settings&&(i.displayOptions=t.draft_settings,dittyDraftDisplayUpdate(i,t.draft_id,"settings",t.draft_settings)),t.draft_settings_json&&i.$importExportField.length&&i.$importExportField.val(t.draft_settings_json),i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showDisplayList(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty(),i.afterUpdateAction=""}})},_importUpdate:function(t){t.preventDefault()},_cloneListeners:function(t,i,e){var s=t.data.self;$(t.target);s.settings.editor.ditty.options(e,i)},_textfieldListeners:function(t){var i=t.data.self,e=$(t.target),s=e.attr("name"),a=e.parents(".ditty-input--spacing__group, .ditty-input--radius__group");if(a.length){var d="",r={};a.find("input").each((function(){s=$(this).attr("name"),d=(d=s.split("["))[0];var t=s.match(/\[(.*)\]/);r[t[1]]=$(this).val()})),i.settings.editor.ditty.options(d,r)}else i.settings.editor.ditty.options(s,e.val());i._checkUpdates()},_radioListeners:function(t){var i=t.data.self,e=$(t.target),s=e.val(),a=e.attr("name");i.settings.editor.ditty.options(a,s),i._checkUpdates()},_checkboxListeners:function(t){var i=t.data.self,e=$(t.target),s=!!e.is(":checked")&&$(this).val(),a=e.attr("name");i.settings.editor.ditty.options(a,s),i._checkUpdates()},_selectListeners:function(t){var i=t.data.self,e=$(t.target),s=e.val(),a=e.attr("name");i.settings.editor.ditty.options(a,s),i._checkUpdates()},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_display_editor_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_display_editor_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.trigger("destroy",[this]),this.$importExportUpdate.off("click",{this:this},this._importUpdate),this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.off("submit",{this:this},this._submitForm),this.$back.off("click",{this:this},this._cancel_click),this.$elmt.off("change",'input[type="text"], input[type="number"]',{self:this},this._textfieldListeners),this.$form.off("click",'input[type="radio"]',{self:this},this._radioListeners),this.$form.off("click",'input[type="checkbox"]',{self:this},this._checkboxListeners),this.$form.off("change","select",{self:this},this._selectListeners),this.$form.off("ditty_field_clone_update",{self:this},this._cloneListeners),this.elmt._ditty_display_editor_panel=null}},$.fn.ditty_display_editor_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_display_editor_panel||(this._ditty_display_editor_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_display_editor_panel;if(!i)throw new Error("No Ditty_Display_Editor_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Display_Editor_Panel.');return void 0!==e?e:this}},$.ditty_display_editor_panel={},$.ditty_display_editor_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layout_variations_panel.defaults,e),this.$elmt=$(i),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$list=$(i).find(".ditty-data-list__items"),this.$editorItem=dittyVars.editor.currentItem,this.editorItemLabel=this.$editorItem.find(".ditty-data-list__item__label").text(),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.editorItemType=this.$editorItem.data("item_type"),this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("click",".ditty-layout-variation__change",{self:this},this._changeTemplate),this.$elmt.on("click",".ditty-layout-variation__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.on("click",".ditty-layout-variation__edit_css",{self:this,editType:"css"},this._editLayout),$("body").on("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse)},_showItemList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","items")},_backClick:function(t){t.preventDefault(),t.data.self._showItemList()},_dittyEditorSaveResponse:function(t,i){t.data.self;i.ditty_new_layout_ids&&$.each(i.ditty_new_layout_ids,(function(t,i){var e=$('.ditty-layout-variation[data-layout_id="'+t+'"]');e.length&&e.attr("data-layout_id",i).data("layout_id",i)}))},_changeTemplate:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("layout_id"),a=e.data("layout_variation_id"),d=e.data("layout_variation_label");dittyVars.editor.currentLayoutVariation=e,i.settings.editor.updateStart(),e.addClass("editing");var r={action:"ditty_editor_layouts",ditty_id:i.editorDittyId,item_type:i.editorItemType,variation_id:a,variation_label:d,layout_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,r,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--layouts">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("layouts",e)}}))},_editLayout:function(t){t.preventDefault();var i=t.data.self,e=t.data.editType,s=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),a=s.data("layout_id"),d=s.data("item_type");dittyVars.editor.currentLayoutVariation=s,i.settings.editor.updateStart(),i.$list.find(".ditty-data-list__item").removeClass("editing"),s.addClass("editing");var r=[],o=i.settings.editor.ditty.options("items");$.each(o,(function(t,i){r.push(i.uniqId)}));var n={action:"ditty_editor_layout_fields",layout_id:a,item_type:d,ditty_id:i.editorDittyId,item_id:i.editorItemId,item_ids:r,edit_type:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,n,(function(t){if(t){var s="layout_"+e+"_editor",a='<div class="ditty-editor__panel ditty-editor__panel--'+s+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel(s,a)}}),"json")},panelVisible:function(){this.$list.find(".ditty-layout-variation").removeClass("editing")},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_layout_variations_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_layout_variations_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$back.off("click",{self:this},this._backClick),this.$elmt.off("click",".ditty-layout-variation__change",{self:this},this._changeTemplate),this.$elmt.off("click",".ditty-layout-variation__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.off("click",".ditty-layout-variation__edit_css",{self:this,editType:"css"},this._editLayout),$("body").off("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),this.elmt._ditty_layout_variations_panel=null}},$.fn.ditty_layout_variations_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_layout_variations_panel||(this._ditty_layout_variations_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_layout_variations_panel;if(!i)throw new Error("No Ditty_Layout_Variations_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Layout_Variations_Panel.');return void 0!==e?e:this}},$.ditty_layout_variations_panel={},$.ditty_layout_variations_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layouts_panel.defaults,e),this.$elmt=$(i),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$list=$(i).find(".ditty-data-list__items"),this.$editorItem=dittyVars.editor.currentItem,this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.editorItemtype=this.$editorItem.data("item_type"),this.$editorVariation=dittyVars.editor.currentLayoutVariation,this.editorVariationId=this.$editorVariation.data("layout_variation_id"),this.editorLayoutId=this.$editorVariation.data("layout_id"),this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("click",".ditty-data-list__item",{self:this},this._selectLayout),this.$elmt.on("click",".ditty-data-list__item__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.on("click",".ditty-data-list__item__edit_css",{self:this,editType:"css"},this._editLayout),this.$elmt.on("click",".ditty-data-list__item__clone",{self:this},this._cloneLayout),this.$elmt.on("click",".ditty-data-list__item__delete",{self:this},this._deleteLayout),this.$list.on("click",".ditty-editor-layout > a",{self:this},this._actionClick),$("body").on("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),
3
+ this._activateLayout(this.$list.find("#ditty-editor-layout--"+this.editorLayoutId))},_activateLayout:function(t){this.$list.find(".ditty-editor-layout").removeClass("active"),t.addClass("active")},_showVariationsList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","layout_variations")},_backClick:function(t){t.preventDefault(),t.data.self._showVariationsList()},_dittyEditorSaveResponse:function(t,i){t.data.self;i.ditty_new_layout_ids&&$.each(i.ditty_new_layout_ids,(function(t,i){var e=$("#ditty-editor-layout--"+t);e.length&&(e.attr("id","ditty-editor-layout--"+i),e.attr("data-layout_id",i).data("layout_id",i))}))},_selectLayout:function(t){t.preventDefault();var i=t.data.self;if($(t.target).parent().is("a"))return!1;var e=$(t.target).is(".ditty-data-list__item")?$(t.target):$(t.target).parents(".ditty-data-list__item"),s=e.data("layout_id"),a=e.data("layout_version"),d=i.$editorItem.data("layout_value");if(e.hasClass("active"))return!1;$.each(d,(function(t){i.editorVariationId===t&&(d[t]=String(s))})),i.settings.editor.updateStart(),dittyDraftItemUpdateData(i,i.editorItemId,"layout_value",d),i._activateLayout(e);var r={action:"ditty_editor_select_layout",layout_id:s,item_id:i.editorItemId,ditty_id:i.editorDittyId,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,r,(function(t){if(i.settings.editor.updateStop(),t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,i.editorItemId),t.editor_item){var e=$(t.editor_item);i.$editorItem.replaceWith(e)}i.$editorItem.attr("data-layout_value",d).data("layout_value",d),i.$editorVariation.attr("data-layout_id",s).data("layout_id",s),i.$editorVariation.find(".ditty-layout-variation__template > span").text(t.layout_label),a?i.$editorVariation.find(".ditty-layout-variation__template > small").text("("+a+")"):i.$editorVariation.find(".ditty-layout-variation__template > small").text("")}),"json")},_cloneLayout:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("layout_id");i.settings.editor.updateStart();var a={action:"ditty_editor_layout_clone",layout_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t.editor_layout){var s=$(t.editor_layout);s.hide(),e.after(s),s.slideDown()}t.draft_id&&t.draft_meta&&dittyDraftLayoutUpdate(i,t.draft_id,null,t.draft_meta),i.settings.editor.updateStop()}),"json")},_deleteLayout:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=null,a=e.data("layout_id");e.hasClass("active")&&(e.prev().length?s=e.prev():e.next().length&&(s=e.next())),e.slideUp((function(){$(this).remove()})),dittyDraftLayoutDelete(i,a),null!==s&&s.trigger("click")},_editLayout:function(t){t.preventDefault();var i=t.data.self,e=t.data.editType,s=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),a=s.data("layout_id");i.settings.editor.updateStart(),i.$list.find(".ditty-data-list__item").removeClass("editing"),s.addClass("editing");var d={action:"ditty_editor_layout_fields",layout_id:a,item_id:i.editorItemId,edit_type:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,d,(function(t){if(t){var s="layout_"+e+"_editor",a='<div class="ditty-editor__panel ditty-editor__panel--'+s+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel(s,a)}}),"json")},_actionClick:function(t){t.preventDefault();var i=t.data.self,e=$(t.target).is("a")?$(t.target):$(t.target).parent("a"),s=e.parents(".ditty-data-list__item"),a=s.data("layout_id");dittyVars.editor.currentLayout=s,$("body").trigger("ditty_editor_layout_action_click",[e,s,a,i.editorDittyId,i.settings.editor])},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_layouts_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_layouts_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$back.off("click",{self:this},this._backClick),this.$elmt.off("click",".ditty-data-list__item",{self:this},this._selectLayout),this.$elmt.off("click",".ditty-data-list__item__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.off("click",".ditty-data-list__item__edit_css",{self:this,editType:"css"},this._editLayout),this.$elmt.off("click",".ditty-data-list__item__clone",{self:this},this._cloneLayout),this.$elmt.off("click",".ditty-data-list__item__delete",{self:this},this._deleteLayout),this.$list.off("click",".ditty-editor-layout > a",{self:this},this._actionClick),$("body").off("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),this.elmt._ditty_layouts_panel=null}},$.fn.ditty_layouts_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_layouts_panel||(this._ditty_layouts_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_layouts_panel;if(!i)throw new Error("No Ditty_Layouts_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Layouts_Panel.');return void 0!==e?e:this}},$.ditty_layouts_panel={},$.ditty_layouts_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null,prevPanel:""},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layout_html_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$textarea=this.$elmt.find(".ditty-editor-options__code"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$preview=this.$elmt.find(".ditty-editor-options__preview"),this.$editCss=this.$elmt.find(".ditty-editor-options__edit-css"),this.$title=this.$elmt.find(".ditty-editor-options__title"),this.$tags=this.$elmt.find(".ditty-editor-options__tags"),this.itemType=this.$form.data("item_type"),this.layoutId=this.$form.data("layout_id"),this.$editorItem=dittyVars.editor.currentItem,this.$editorLayout=dittyVars.editor.currentLayout,this.$editorLayoutTitle=!!this.$editorLayout&&this.$editorLayout.find(".ditty-data-list__item__label"),this.$editorLayoutVariation=dittyVars.editor.currentLayoutVariation,this.$editorLayoutVariationTitle=this.$editorLayoutVariation.find(".ditty-layout-variation__template span"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.codeEditor=null,this.codeHasUpdates=!1,this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this._initEditor(),this.$back.on("click",{self:this},this._backClick),this.$preview.on("click",{self:this},this._previewClick),this.$editCss.on("click",{self:this},this._editCss),this.$form.on("submit",{self:this},this._submitForm),this.$form.on("click",".ditty-editor-options__tag",{self:this},this._insertTag),this.$title.on("keyup",{self:this},this._titleUpdate),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts)},_showPrevPanel:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById",this.settings.prevPanel)},_titleUpdate:function(t){var i=t.data.self;i.settings.editor.addUpdate("layoutUpdate",i.layoutId)},_enablePreviewButton:function(){this.$preview.addClass("ditty-has-updates")},_disablePreviewButton:function(){this.$preview.removeClass("ditty-has-updates"),this.$preview.children("i").attr("class",this.$preview.children("i").data("class"))},_getLayoutItems:function(){var t=this.settings.editor.ditty.options("items"),i=[];return $.each(t,(function(t,e){String(e.layoutId)===String(this.layoutId)&&i.push(e.id)})),i},_addDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),i.$form.serialize()!==i.initData||i.codeHasUpdates?(i.afterUpdateAction="return",i.$form.trigger("submit")):i._showPrevPanel()},_previewClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit"))},_editCss:function(t){t.preventDefault();var i=t.data.self,e="layout_css_editor";if(i.settings.editor.updateStart(),i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit")),i.settings.editor.panelExists(e))i.settings.editor.$elmt.find(".ditty-editor__panel--layout_css_editor input.ditty-editor-options__title").val(i.$title.val()),i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e);else{var s={action:"ditty_editor_layout_fields",layout_id:i.layoutId,layout_title:i.$title.val(),ditty_id:i.editorDittyId,item_id:i.editorItemId,item_type:i.itemType,edit_type:"css",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,s,(function(t){if(t){var s='<div class="ditty-editor__panel ditty-editor__panel--'+e+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e,s)}}),"json")}},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.layoutId,s=i.itemType,a=i._getLayoutItems();if(i.$form.hasClass("ditty-editor-has-errors"))return!1;i.codeEditor.codemirror.save(),i.settings.editor.updateStart();var d={action:"ditty_editor_layout_update",layout_id:e,item_type:s,item_ids:a,edit_type:"html",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:d,success:function(t){i.initData=i.$form.serialize(),i._disablePreviewButton(),t.label&&(i.$editorLayoutTitle&&i.$editorLayoutTitle.html(t.label),i.$editorLayoutVariationTitle.html(t.label)),i.$editorLayoutTitle&&i.$editorLayoutTitle.find(".ditty-layout-version").remove(),i.$editorLayoutVariationTitle&&i.$editorLayoutVariationTitle.find(".ditty-layout-version").remove(),t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,!1,!1,!0),t.draft_id&&t.draft_meta&&dittyDraftLayoutUpdate(i,t.draft_id,null,t.draft_meta),i.codeHasUpdates=!1,i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showPrevPanel(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty({return_items:0}),i.afterUpdateAction=""}})},_initEditor:function(){var t=this,i=wp.codeEditor.defaultSettings?_.clone(wp.codeEditor.defaultSettings):{};i.codemirror=_.extend({},i.codemirror,{indentUnit:2,tabSize:2}),this.codeEditor=wp.codeEditor.initialize(this.$textarea[0],i),this.codeEditor.codemirror.on("change",(function(){t.codeEditor.codemirror.save(),t.settings.editor.addUpdate("layout_html_update",t.layoutId),t.codeHasUpdates=!0,t._enablePreviewButton(),t.settings.editor.delayedSubmitEnable()}))},_insertTag:function(t){var i=t.data.self,e=$(t.target),s=e.text(),a=e.data("atts"),d=i.codeEditor.codemirror.getCursor();if(t.shiftKey&&a){var r="",o=s.length-1;$.each(a,(function(t,i){r+=" "+t+'="'+i.toString()+'"'})),s=s.substring(0,o)+r+s.substring(o)}i.codeEditor.codemirror.replaceRange(s,d),d.ch=d.ch+s.length,i.codeEditor.codemirror.setCursor(d)},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_layout_html_editor_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_layout_html_editor_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$back.off("click",{self:this},this._backClick),this.$preview.off("click",{self:this},this._previewClick),this.$editCss.off("click",{self:this},this._editCss),this.$form.off("submit",{self:this},this._submitForm),this.$form.off("click",".ditty-editor-options__tag",{self:this},this._insertTag),this.$title.off("keyup",{self:this},this._titleUpdate),this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.codeEditor.codemirror.off("change"),this.codeEditor.codemirror.toTextArea(),this.elmt._ditty_layout_html_editor_panel=null}},$.fn.ditty_layout_html_editor_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_layout_html_editor_panel||(this._ditty_layout_html_editor_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_layout_html_editor_panel;if(!i)throw new Error("No Ditty_Layout_Html_Editor_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Layout_Html_Editor_Panel.');return void 0!==e?e:this}},$.ditty_layout_html_editor_panel={},$.ditty_layout_html_editor_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null,prevPanel:""},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layout_css_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$textarea=this.$elmt.find(".ditty-editor-options__code"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$preview=this.$elmt.find(".ditty-editor-options__preview"),this.$editHtml=this.$elmt.find(".ditty-editor-options__edit-html"),this.$title=this.$elmt.find(".ditty-editor-options__title"),this.$body=this.$elmt.find(".ditty-editor-options__body"),this.$tags=this.$elmt.find(".ditty-editor-options__tags"),this.itemType=this.$form.data("item_type"),this.layoutId=this.$form.data("layout_id"),this.$editorItem=dittyVars.editor.currentItem,this.$editorLayout=dittyVars.editor.currentLayout,this.$editorLayoutTitle=!!this.$editorLayout&&this.$editorLayout.find(".ditty-data-list__item__label"),this.$editorLayoutVariation=dittyVars.editor.currentLayoutVariation,this.$editorLayoutVariationTitle=this.$editorLayoutVariation.find(".ditty-layout-variation__template span"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.itemSelector="",this.codeEditor=null,this.codeHasUpdates=!1,this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this._setCssSelector(),this._initEditor(),this.$back.on("click",{self:this},this._backClick),this.$preview.on("click",{self:this},this._previewClick),this.$editHtml.on("click",{self:this},this._editHtml),this.$form.on("submit",{self:this},this._submitForm),this.$form.on("click",".ditty-editor-options__tag",{self:this},this._insertTag),this.$title.on("keyup",{self:this},this._titleUpdate),this.$body.on("click",".ditty-editor-options__body__error",{self:this},this._removeErrorNotice),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts)},_setCssSelector:function(){dittyVars.isTickerPost?this.itemSelector="#poststuff .ditty-layout--"+this.layoutId:this.itemSelector=".ditty-layout--"+this.layoutId},_showPrevPanel:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById",this.settings.prevPanel)},_titleUpdate:function(t){var i=t.data.self;i.settings.editor.addUpdate("layoutUpdate",i.layoutId)},_enablePreviewButton:function(){this.$preview.addClass("ditty-has-updates")},_disablePreviewButton:function(){this.$preview.removeClass("ditty-has-updates"),this.$preview.children("i").attr("class",this.$preview.children("i").data("class"))},_addDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),i.$form.serialize()!==i.initData||i.codeHasUpdates?(i.afterUpdateAction="return",i.$form.trigger("submit")):i._showPrevPanel()},_previewClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit"))},_editHtml:function(t){t.preventDefault();var i=t.data.self,e="layout_html_editor";if(i.settings.editor.updateStart(),i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit")),i.settings.editor.panelExists(e))i.settings.editor.$elmt.find(".ditty-editor__panel--layout_html_editor input.ditty-editor-options__title").val(i.$title.val()),i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e);else{var s={action:"ditty_editor_layout_fields",layout_id:i.layoutId,layout_title:i.$title.val(),ditty_id:i.editorDittyId,item_id:i.editorItemId,item_type:i.itemType,edit_type:"html",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,s,(function(t){if(t){var s='<div class="ditty-editor__panel ditty-editor__panel--'+e+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e,s)}}),"json")}},_showErrorNotice:function(){var t=$('<div class="ditty-editor-options__body__error"><span>'+dittyVars.strings.layout_css_error+"</span></div>");this.$body.append(t)},_removeErrorNotice:function(t){t.data.self.$body.find(".ditty-editor-options__body__error").remove()},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.layoutId,s=i.itemType;if(i.$form.hasClass("ditty-editor-has-errors"))return!1;i.codeEditor.codemirror.save(),i.settings.editor.updateStart();var a={action:"ditty_editor_layout_update",layout_id:e,item_type:s,edit_type:"css",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:a,success:function(t){i.initData=i.$form.serialize(),i._disablePreviewButton(),t.label&&(i.$editorLayoutTitle&&i.$editorLayoutTitle.html(t.label),i.$editorLayoutVariationTitle.html(t.label)),i.$editorLayoutTitle&&i.$editorLayoutTitle.find(".ditty-layout-version").remove(),i.$editorLayoutVariationTitle&&i.$editorLayoutVariationTitle.find(".ditty-layout-version").remove(),t.code?dittyLayoutCss(t.code,i.layoutId):i._showErrorNotice(),t.draft_id&&t.draft_meta&&dittyDraftLayoutUpdate(i,t.draft_id,null,t.draft_meta),i.codeHasUpdates=!1,i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showPrevPanel(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty(),i.afterUpdateAction=""}})},_initEditor:function(){var t=this,i=wp.codeEditor.defaultSettings?_.clone(wp.codeEditor.defaultSettings):{},e=dittyVars.editor.ditty_layouts_sass?"sass":"css";i.codemirror=_.extend({},i.codemirror,{mode:e,indentUnit:2,tabSize:2}),this.codeEditor=wp.codeEditor.initialize(this.$textarea[0],i),this.codeEditor.codemirror.on("change",(function(){t.codeEditor.codemirror.save(),t.settings.editor.addUpdate("layoutCssUpdate",t.layoutId),t.codeHasUpdates=!0,t._enablePreviewButton(),t.settings.editor.delayedSubmitEnable()}))},_insertTag:function(t){var i=t.data.self,e=$(t.target).text(),s=i.codeEditor.codemirror.getCursor();i.codeEditor.codemirror.replaceRange(e,s),s.ch=s.ch+e.length,i.codeEditor.codemirror.setCursor(s)},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_layout_css_editor_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_layout_css_editor_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$back.off("click",{self:this},this._backClick),this.$preview.off("click",{self:this},this._previewClick),this.$editHtml.off("click",{self:this},this._editHtml),this.$form.off("submit",{self:this},this._submitForm),this.$form.off("click",".ditty-editor-options__tag",{self:this},this._insertTag),this.$title.off("keyup",{self:this},this._titleUpdate),this.$body.off("click",".ditty-editor-options__body__error",{self:this},this._removeErrorNotice),this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.codeEditor.codemirror.off("change"),this.codeEditor.codemirror.toTextArea(),this.elmt._ditty_layout_css_editor_panel=null}},$.fn.ditty_layout_css_editor_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_layout_css_editor_panel||(this._ditty_layout_css_editor_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_layout_css_editor_panel;if(!i)throw new Error("No Ditty_Layout_Css_Editor_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Layout_Css_Editor_Panel.');return void 0!==e?e:this}},$.ditty_layout_css_editor_panel={},$.ditty_layout_css_editor_panel.defaults=t}(jQuery),jQuery(document).ready((function($){!function(){"use strict";function t(t,i){0===parseInt(i)?t.hide():t.show()}function i(t,i){"none"===i?t.hide():t.show()}function e(t,i){"none"===i?t.hide():t.show()}$("#ditty-editor").on("ditty_display_editor_panel_init",".ditty-editor__panel--displayEditor",(function(s,a){if("list"===a.displayType){var d=a.$form,r=d.find(".ditty-field--perPage"),o=d.find(".ditty-field--arrows").siblings(),n=d.find(".ditty-field--bullets").siblings();t(r,d.find('input[name="paging"]:checked').val()),d.find('input[name="paging"]').on("change",(function(){t(r,$(this).val())})),i(o,d.find('select[name="arrows"]').val()),d.find('select[name="arrows"]').on("change",(function(){i(o,$(this).val())})),e(n,d.find('select[name="bullets"]').val()),d.find('select[name="bullets"]').on("change",(function(){e(n,$(this).val())}))}}))}()})),function($){"use strict";var t={listType:"toggle",showAll:!0,activeFilter:"*",filter:".ditty-data-list__filter",filterSelector:"filter",item:".ditty-data-list__item",itemSelector:"filter"},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_ui_data_list.defaults,e),this.$elmt=$(i),this.filters=[],this._init()};i.prototype={_init:function(){var t=this;this.$elmt.on("click",this.settings.filter,{self:this},this._filterClick),this.$elmt.find(this.settings.filter+".active").each((function(){t._filterList($(this).data(t.settings.filterSelector))})),"*"!==this.settings.activeFilter&&this._filterList(this.settings.activeFilter),setTimeout((function(){t.trigger("init")}),1)},_filterList:function(t){var i=this,e=this.filters;if("toggle"===this.settings.listType)this.filters.includes(t)?this.settings.showAll&&(this.filters=[],this.$elmt.find(this.settings.filter).removeClass("active"),this.$elmt.find(this.settings.item).show()):(this.filters=[t],this.$elmt.find(this.settings.filter).removeClass("active"),this.$elmt.find(this.settings.filter+"[data-"+this.settings.filterSelector+'="'+t+'"]').addClass("active"),this.$elmt.find(this.settings.item).hide(),this.$elmt.find(this.settings.item+"[data-"+this.settings.itemSelector+'="'+t+'"]').show());else if("filter"===this.settings.listType){if(this.$elmt.find(this.settings.item).hide(),this.filters.includes(t)){this.$elmt.find(this.settings.filter+"[data-"+this.settings.filterSelector+'="'+t+'"]').removeClass("active");for(var s=0;s<this.filters.length;s++)i.filters[s]===t&&i.filters.splice(s,1)}else this.$elmt.find(this.settings.filter+"[data-"+this.settings.filterSelector+'="'+t+'"]').addClass("active"),this.filters.push(t);$.each(this.filters,(function(t,e){i.$elmt.find(this.settings.item+"[data-"+this.settings.itemSelector+'="'+e+'"]').show()})),0===this.filters.length&&i.$elmt.find(this.settings.item).show()}e!==this.filters&&i.trigger("update")},_filterClick:function(t){t.preventDefault();var i=t.data.self,e=$(t.target);e.is("a")||(e=e.parents("a")),i._filterList(e.data(i.settings.filterSelector))},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings,this.filters];i&&(e=i),this.$elmt.trigger("ditty_ui_data_list_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_ui_data_list.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.off("click",this.settings.filter,{self:this},this._filterClick),this.trigger("destroy"),this.elmt._ditty_ui_data_list=null}},$.fn.ditty_ui_data_list=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_ui_data_list||(this._ditty_ui_data_list=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_ui_data_list;if(!i)throw new Error("No Ditty_UI_Data_List applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_UI_Data_List.');return void 0!==e?e:this}},$.ditty_ui_data_list={},$.ditty_ui_data_list.defaults=t}(jQuery),function($){"use strict";var t={screen:"admin",ditty:null,panel:""},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_editor.defaults,e),this.$elmt=$(i),this.ditty=this.settings.ditty,this.dittyId=this.settings.ditty.options("id"),this.dittyType=this.settings.ditty.options("type"),this.displayId=0,this.panelsLoaded=0,this.unsavedUpdates={},this.draftValues={},this.$overlay=null,this.$contents=null,this.$header=null,this.$update=null,this.$updateCount=null,this.$updateLabel=null,this.$tabs=null,this.$panels=null,this.currentTab=0,this.currentPanel=this.settings.panel,this.delayedSubmit=!1,this.tabs=[],this.panels=[],this.activeItems=[],this._init()};i.prototype={_init:function(){var t,i,e,s,a,d,r,o=this;t=$('<div class="ditty-editor__contents"></div>'),this.$contents=t,i=$('<div class="ditty-editor__header"></div>'),this.$header=i,e=$('<span class="ditty-editor__update__count"></span>'),this.$updateCount=e,s=$('<span class="ditty-editor__update__label">Save Ditty</span>'),this.$updateLabel=s,a=$('<button type="submit" class="ditty-editor__update ditty-button ditty-button--primary"></button>'),this.$update=a,d=$('<div class="ditty-editor__tabs"></div>'),this.$tabs=d,r=$('<div class="ditty-editor__panels"></div>'),this.$panels=r,a.prepend(e,s),i.append(a),t.append(i,d,r),this.$elmt.append(t),this.$overlay=$('<div class="ditty-updating-overlay ditty-admin-item__overlay"><div class="ditty-updating-overlay__inner"><i class="fas fa-sync-alt fa-spin"></i></div></div>'),this.$elmt.append(this.$overlay),$(document).on("postbox-moved",{self:this},this._postboxMoved),$(document).on("postboxes-columnchange",{self:this},this._postboxMoved),$(window).on("beforeunload",{self:this},this._beforeunload),this.ditty.$elmt.on("ditty_active_items_update",{self:this},this._dittyItemsUpdated),this.ditty.$elmt.on("ditty_disabled_items_update",{self:this},this._disabledItemsUpdate),this.$tabs.on("click",".ditty-editor__tab",{self:this},this._showPanel),this.$update.on("click",{self:this},this._saveClick),this.$panels.on("ditty_slider_init",{self:this},this._editorLoaded),this.$panels.on("ditty_slider_before_slide_update",{self:this},this._beforeSlideUpdate),this.$panels.on("ditty_slider_after_slide_update",{self:this},this._afterSlideUpdate),this.$panels.on("ditty_slider_slide_removed",{self:this},this._slideRemoved),this._loadContents(),this.trigger("stop_live_updates"),setTimeout((function(){o.trigger("init")}),1)},_loadContents:function(){var t=this,i={action:"ditty_editor_load_contents",ditty_id:this.dittyId,security:dittyVars.security};$.post(dittyVars.ajaxurl,i,(function(i){t._initTabs(i.tabs),t._initPanels(i.panels),t._initSlider()}),"json")},_editorLoaded:function(t){var i=t.data.self;$("body").trigger("ditty_editor_loaded",[i])},_setUpdateCount:function(){},_initSlider:function(){var t=this.tabs[0].id;this.currentPanel&&""!==this.currentPanel&&(t=this.currentPanel),this.$panels.ditty_slider({transition:"fade",transitionSpeed:.75,heightSpeed:.75,touchSwipe:!1,slides:this.panels,slideId:t})},_beforeSlideUpdate:function(t,i,e,s,a){var d=t.data.self;d.updateStart(),d._updateTab(e.id),$("body").trigger("ditty_editor_before_panel_update",[e.id,e.$elmt,a.id,a.$elmt,d])},_afterSlideUpdate:function(t,i,e,s,a){var d=t.data.self;d.updateStop(),$("body").trigger("ditty_editor_after_panel_update",[e.id,e.$elmt,a.id,a.$elmt,d])},_slideRemoved:function(t,i){var e=t.data.self;$("body").trigger("ditty_editor_panel_removed",[i.id,i.$elmt,e])},_showPanel:function(t){t.preventDefault();var i=t.data.self,e=$(t.target).is("a")?$(t.target):$(t.target).parent("a"),s=e.data("panel"),a=parseInt(e.data("index"));if(s===i.currentTab)return!1;var d=a>i.currentTab?"slideLeft":"slideRight";i.$panels.ditty_slider("options","transition",d),i.$panels.ditty_slider("showSlideById",s),i.currentTab=a,i.$elmt.trigger("ditty_editor_add_drafts")},_updateTab:function(t){var i=$('.ditty-editor__tab[data-panel="'+t+'"]');void 0!==i[0]&&($(".ditty-editor__tab").removeClass("active"),i.addClass("active"),this.currentTab=parseInt(i.data("index")))},_initTabs:function(t){var i=this,e=0;$.each(t,(function(t,s){var a=$('<a href="#" class="ditty-editor__tab ditty-editor__tab--'+t+'" data-panel="'+t+'" data-index="'+e+'"><i class="'+s.icon+'"></i><span>'+s.label+"</span></a>");i.$tabs.append(a),i.tabs.push({id:t,tab:a}),e++}))},_initPanels:function(t){var i=this;$.each(t,(function(t,e){var s='<div class="ditty-editor__panel ditty-editor__panel--'+t+'">'+e+"</div>";i.panels.push({id:t,html:s,cache:!0})}))},_initFields:function(t){t.find(".ditty-data-list").ditty_ui_data_list(),t.trigger("ditty_init_fields"),$.protip({defaults:{position:"top",size:"small",scheme:"black",classes:"ditty-protip"}})},saveDitty:function(t){var i=this,e=i.dittyId;i.$updateLabel.text("Updating..."),i.updateStart();var s={action:"ditty_editor_save",ditty_id:e,draft_values:i.draftValues,return_items:1,security:dittyVars.security};s=$.extend({},s,t),$.post(dittyVars.ajaxurl,s,(function(t){$("body").trigger("ditty_editor_save_ditty_response",[t]),
4
+ t.display_items&&i.ditty.options("items",t.display_items),i.draftValues={},i.unsavedUpdates={},i._setUpdateCount(),i.$elmt.removeClass("ditty-editor--updates-exist"),i.$updateLabel.text("Ditty Saved!"),setTimeout((function(){i.$updateLabel.text("Save Ditty")}),2e3),i.updateStop(),t.new_ditty_url&&window.history.pushState(null,"","/wp-admin/post.php?post="+e+"&action=edit")}))},_saveClick:function(t){t.preventDefault();var i=t.data.self;i.$elmt.trigger("ditty_editor_save_drafts"),i.delayedSubmit||i.saveDitty()},_dittyItemsUpdated:function(t,i,e){var s=t.data.self;s.activeItems=e,s.trigger("active_items_update")},_disabledItemsUpdate:function(t,i){var e=t.data.self;$.each(i,(function(t,i){"disabled"===i?e.$elmt.find("#ditty-editor-item--"+t).addClass("ditty-editor-item--disabled"):e.$elmt.find("#ditty-editor-item--"+t).removeClass("ditty-editor-item--disabled")}))},_postboxMoved:function(t,i){if(!window.tinymce)return!1;$(i).find(".wp-editor-area").each((function(){var t=$(this).attr("id");tinymce.execCommand("mceRemoveEditor",!0,t),tinymce.execCommand("mceAddEditor",!0,t)}))},_beforeunload:function(t){var i=t.data.self;return Object.keys(i.unsavedUpdates).length>0||void 0},_windowResize:function(t){t.preventDefault()},_options:function(t){return this.settings[t]},panelExists:function(t){var i=this.$panels.ditty_slider("options","slides"),e=!1;return $.each(i,(function(i,s){String(s.id)!==String(t)||(e=!0)})),e},showPanel:function(t,i){i&&this.$panels.ditty_slider("addSlideById",t,i),this.$panels.ditty_slider("showSlideById",t,!0)},updateExists:function(t,i){if(void 0===this.unsavedUpdates[t]&&(this.unsavedUpdates[t]=[]),-1!==$.inArray(i,this.unsavedUpdates[t]))return!0},addUpdate:function(t,i){var e=!1;return void 0===this.unsavedUpdates[t]&&(this.unsavedUpdates[t]=[]),-1===$.inArray(i,this.unsavedUpdates[t])&&(e=!0,this.unsavedUpdates[t].push(i)),this._setUpdateCount(),this.$elmt.addClass("ditty-editor--updates-exist"),e},removeUpdate:function(t,i){if(void 0===this.unsavedUpdates[t])return!1;if(-1===$.inArray(i,this.unsavedUpdates[t]))return!1;var e=!1,s=[];return $.each(this.unsavedUpdates[t],(function(t,a){String(i)===String(a)?e=!0:s.push(a)})),this.unsavedUpdates[t]=s,this._setUpdateCount(),""===this.$updateCount.text()&&this.$elmt.removeClass("ditty-editor--updates-exist"),e},updateStart:function(){this.$overlay.fadeIn()},updateStop:function(){this.$overlay.fadeOut()},initFields:function(t){this._initFields(t)},updateDraftValues:function(t,i){return this.$elmt.addClass("ditty-editor--updates-exist"),t?(this.draftValues[t]=i,"development"===dittyVars.mode&&window.console&&console.log("draftValues:",this.draftValues),this.draftValues[t]):(this.draftValues=i,"development"===dittyVars.mode&&window.console&&console.log("draftValues:",this.draftValues),this.draftValues)},getDraftValues:function(t){return t?!!this.draftValues[t]&&this.draftValues[t]:this.draftValues},delayedSubmitEnable:function(){this.delayedSubmit=!0},delayedSubmitDisable:function(){this.delayedSubmit=!1},trigger:function(t,i){var e=[];switch(t){case"active_items_update":e=[this.ditty,this.activeItems];break;case"stop_live_updates":e=[this.dittyId];break;default:e=[this.settings]}i&&(e=i),this.$elmt.trigger("ditty_editor_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e),$("body").trigger("ditty_"+t,e)},_getPanelOption:function(t){return"elmnt"===t?this.$panels:this.settings[t]},_setPanelOption:function(t,i){if(void 0===i)return!1;this.$panels.ditty_slider("options",t,i),this.trigger("update")},panelOptions:function(t,i){var e=this;if("object"==typeof t)$.each(t,(function(t,i){e._setPanelOption(t,i)}));else{if("string"!=typeof t)return e.$panels.ditty_slider("options");if(void 0===i)return e._getPanelOption(t);e._setPanelOption(t,i)}},_getOption:function(t){return"elmnt"===t?this:this.settings[t]},_setOption:function(t,i){if(void 0===i)return!1;this.settings[t]=i,this.trigger("update")},options:function(t,i){var e=this;if("object"==typeof t)$.each(t,(function(t,i){e._setOption(t,i)}));else{if("string"!=typeof t)return e.settings;if(void 0===i)return e._getOption(t);e._setOption(t,i)}},destroy:function(){this.$panels.ditty_slider&&this.$panels.ditty_slider("destroy"),$(document).off("postbox-moved",{self:this},this._postboxMoved),$(document).off("postboxes-columnchange",{self:this},this._postboxMoved),$(window).off("beforeunload",{self:this},this._beforeunload),this.ditty.$elmt.off("ditty_active_items_update",{self:this},this._dittyItemsUpdated),this.ditty.$elmt.off("ditty_disabled_items_update",{self:this},this._disabledItemsUpdate),this.$tabs.off("click","ditty-editor__tab",{self:this},this._showPanel),this.$update.off("click",{self:this},this._saveClick),this.$panels.off("ditty_slider_init",{self:this},this._editorLoaded),this.$panels.off("ditty_slider_before_slide_update",{self:this},this._beforeSlideUpdate),this.$panels.off("ditty_slider_after_slide_update",{self:this},this._afterSlideUpdate),this.$panels.off("ditty_slider_slide_removed",{self:this},this._slideRemoved),this.trigger("destroy"),this.elmt._ditty_editor=null}},$.fn.ditty_editor=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_editor||(this._ditty_editor=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_editor;if(!i)throw new Error("No Ditty_Editor applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Editor.');return void 0!==e?e:this}},$.ditty_editor={},$.ditty_editor.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_settings_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$title=this.$elmt.find('input[name="title]'),this.$previewBg=this.$elmt.find('input[name="previewBg"]'),this.$previewPaddingTop=this.$elmt.find('input[name="previewPadding[paddingTop]"]'),this.$previewPaddingBottom=this.$elmt.find('input[name="previewPadding[paddingBottom]"]'),this.$previewPaddingLeft=this.$elmt.find('input[name="previewPadding[paddingLeft]"]'),this.$previewPaddingRight=this.$elmt.find('input[name="previewPadding[paddingRight]"]'),this.$postTitle=$(".ditty-post__title"),this.$editorPreview=$("#ditty-editor__preview"),this.dittyId=this.$form.data("ditty_id"),this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this.settings.editor.initFields(this.$elmt),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.on("submit",{self:this},this._submitForm),this.$form.on("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.on("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.on("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.$form.on("keyup change",'input[name="title"]',{self:this},this._titleChange),this.$form.on("keyup change",".ditty-field--preview_settings *",{self:this},this._previewBgChange),this.$elmt.addClass("init")},_checkUpdates:function(t){var i=t?t.data.self:this;i.$form.serialize()!==i.initData?(i.settings.editor.addUpdate("settings",i.itemId),i.settings.editor.delayedSubmitEnable()):i.settings.editor.removeUpdate("settings",i.itemId)},_titleChange:function(t){var i=t?t.data.self:this,e=$(t.target).val();i.$postTitle.text(e)},_previewBgChange:function(t){var i=t?t.data.self:this,e={backgroundColor:i.$previewBg.val(),paddingTop:i.$previewPaddingTop.val(),paddingBottom:i.$previewPaddingBottom.val(),paddingLeft:i.$previewPaddingLeft.val(),paddingRight:i.$previewPaddingRight.val()};i.$editorPreview.css(e)},_addDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.dittyId;i.settings.editor.updateStart();var s={action:"ditty_editor_settings_update",ditty_id:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:s,success:function(t){i.initData=i.$form.serialize(),dittyDraftUpdate(i,"settings",!1,t),i.settings.editor.delayedSubmitDisable(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty({return_items:0}),i.afterUpdateAction=""}})},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_settings_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_settings_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._addDrafts),this.$form.off("submit",{self:this},this._submitForm),this.$form.off("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.off("keyup change",'input[name="previewBg"]',{self:this},this._previewBg_cahnge),this.$form.off("keyup change",'input[name="title"]',{self:this},this._titleChange),this.$form.off("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.off("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.trigger("destroy"),this.elmt._ditty_settings_panel=null}},$.fn.ditty_settings_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_settings_panel||(this._ditty_settings_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_settings_panel;if(!i)throw new Error("No Ditty_Settings_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Settings_Panel.');return void 0!==e?e:this}},$.ditty_settings_panel={},$.ditty_settings_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_items_panel.defaults,e),this.$elmt=$(i),this.$add=$(i).find(".ditty-editor-options__add"),this.$contents=$(i).find(".ditty-editor__panel__contents"),this.$list=$(i).find(".ditty-data-list"),this.$listItems=$(i).find(".ditty-data-list__items"),this.isEmptyTicker=!1,this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.settings.editor.$elmt.on("ditty_editor_aactive_items_update",{self:this},this._dittyActiveItemsUpdated),this.$add.on("click",{self:this},this._add_item),this.$elmt.on("click",".ditty-data-list__item",{self:this},this._showItem),this.$elmt.on("click",".ditty-data-list__item__icon",{self:this},this._editType),this.$elmt.on("click",".ditty-data-list__item__edit",{self:this},this._editItem),this.$elmt.on("click",".ditty-data-list__item__layout",{self:this},this._editLayoutVariations),this.$elmt.on("click",".ditty-data-list__item__clone",{self:this},this._cloneItem),this.$elmt.on("click",".ditty-data-list__item__delete",{self:this},this._deleteItem),this.$list.on("click",".ditty-editor-item > a",{self:this},this._actionClick),$("body").on("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),1>this.$elmt.find(".ditty-data-list__item").length&&(this.isEmptyTicker=!0,this.$add.trigger("click")),this._initializeSorting(),this._highlightListItems(this.settings.editor.activeItems)},dittyUpdateSavedDraftLayouts:function(t,i){$.each($(".ditty-editor-item"),(function(){var e=$(this).data("layout_value");$.each(e,(function(s,a){String(a)===String(t)&&(e[s]=String(i))})),$(this).attr("data-layout_value",e).data("layout_value",e)}))},_dittyEditorSaveResponse:function(t,i){var e=t.data.self;i.ditty_new_item_ids&&$.each(i.ditty_new_item_ids,(function(t,i){var e=$("#ditty-editor-item--"+t);e.length&&(e.attr("id","ditty-editor-item--"+i),e.attr("data-item_id",i).data("item_id",i))})),i.ditty_new_layout_ids&&$.each(i.ditty_new_layout_ids,(function(t,i){e.dittyUpdateSavedDraftLayouts(t,i)}))},_highlightListItem:function(t){var i=t.id+"";i=i.split("_"),this.$elmt.find("#ditty-editor-item--"+i[0]).addClass("active")},_highlightListItems:function(t){this.$elmt.find(".ditty-data-list__item").removeClass("active");var i=this;Array.isArray(t)?$.each(t,(function(t,e){i._highlightListItem(e)})):i._highlightListItem(t)},_dittyActiveItemsUpdated:function(t,i,e){t.data.self._highlightListItems(e)},_initializeSorting:function(){var t=this;this.$listItems.sortable({handle:".ditty-data-list__item__move",items:".ditty-data-list__item",axis:"y",start:function(t,i){$(i.item).addClass("ditty-data-list__item--moving")},stop:function(i,e){$(e.item).removeClass("ditty-data-list__item--moving"),t.settings.editor.addUpdate("item_order",t.settings.editor.dittyId)},update:function(){t._updateItemIndexes("updateDitty")}})},_showItem:function(t){t.preventDefault();var i=t.data.self;if(!$(t.target).is("a")&&!$(t.target).parent().is("a")){var e=($(t.target).is(".ditty-data-list__item")?$(t.target):$(t.target).parents(".ditty-data-list__item")).data("item_id");i.settings.editor.ditty.showItem(e)}},_actionClick:function(t){t.preventDefault();var i=t.data.self,e=$(t.target).is("a")?$(t.target):$(t.target).parent("a"),s=e.parents(".ditty-data-list__item"),a=s.data("ditty_id"),d=s.data("item_id");dittyVars.editor.currentItem=s,$("body").trigger("ditty_editor_item_action_click",[e,s,d,a,i.settings.editor])},_editType:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item");e.trigger("click"),e.addClass("editing"),i.settings.editor.updateStart(),i.settings.editor.panelOptions("transition","slideRight"),i.settings.editor.showPanel("item_types")},_editItem:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_id");e.trigger("click"),e.addClass("editing"),i.settings.editor.updateStart();var a={action:"ditty_editor_item_fields",item_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--item_editor">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("item_editor",e)}}))},_editLayoutVariations:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_type"),a=e.data("layout_value"),d=e.find(".ditty-data-list__item__label").html();e.trigger("click"),e.addClass("editing"),i.settings.editor.updateStart();var r={action:"ditty_editor_layout_variations",ditty_id:i.settings.editor.dittyId,item_type:s,item_label:d,layout_value:a,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,r,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--layout-variations">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("layout_variations",e)}}))},_add_item:function(t){t.preventDefault();var i=t.data.self,e={action:"ditty_editor_item_add",ditty_id:i.settings.editor.dittyId,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,e,(function(t){if(t.display_items){if(i.isEmptyTicker){var e=i.settings.editor.ditty.options("items");$.each(e,(function(t,e){i.settings.editor.ditty.deleteItem(e.id)})),i.isEmptyTicker=!1}$.each(t.display_items,(function(t,e){i.settings.editor.ditty.addItem(e,0)}))}if(t.editor_item){var s=$(t.editor_item);s.hide(),i.$listItems.prepend(s),s.slideDown(),i._updateItemIndexes()}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),t.draft_id&&t.draft_meta&&dittyDraftItemUpdateMeta(i,t.draft_id,null,t.draft_meta)}),"json")},_cloneItem:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_id");i.settings.editor.updateStart();var a={action:"ditty_editor_item_clone",item_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t.display_items&&t.display_items.length&&i.settings.editor.ditty.updateItems(t.display_items,s,"after"),t.editor_item){var a=$(t.editor_item);a.hide(),e.after(a),a.slideDown(),i._updateItemIndexes()}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),t.draft_id&&t.draft_meta&&dittyDraftItemUpdateMeta(i,t.draft_id,null,t.draft_meta),i.settings.editor.updateStop()}),"json")},_deleteItem:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("item_id");1>=i.$elmt.find(".ditty-data-list__item").length&&i.$add.trigger("click"),e.slideUp((function(){$(this).remove()})),i.settings.editor.ditty.deleteItem(s),dittyDraftItemDelete(i,s)},_updateItemIndexes:function(t){var i=this,e=[];if(this.$elmt.find(".ditty-data-list__item").each((function(t){var s=$(this).data("item_id");e.push(s),dittyDraftItemUpdateData(i,s,"item_index",t)})),"updateDitty"===t){var s=dittyItemsReorder(i.settings.editor.ditty.options("items"),e);i.settings.editor.ditty.options("items",s)}},panelVisible:function(){this.$elmt.find(".ditty-data-list__item").removeClass("editing")},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_items_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_items_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.settings.editor.$elmt.off("ditty_editor_active_items_update",{self:this},this._dittyActiveItemsUpdated),this.$add.off("click",{self:this},this._add_item),this.$elmt.off("click",".ditty-data-list__item",{self:this},this._showItem),this.$elmt.off("click",".ditty-data-list__item__icon",{self:this},this._editType),this.$elmt.off("click",".ditty-data-list__item__edit",{self:this},this._editItem),this.$elmt.off("click",".ditty-data-list__item__layout",{self:this},this._editLayoutVariations),this.$elmt.off("click",".ditty-data-list__item__clone",{self:this},this._cloneItem),this.$elmt.off("click",".ditty-data-list__item__delete",{self:this},this._deleteItem),this.$list.off("click",".ditty-editor-item > a",{self:this},this._actionClick),$("body").off("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),this.trigger("destroy"),this.elmt._ditty_items_panel=null}},$.fn.ditty_items_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_items_panel||(this._ditty_items_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_items_panel;if(!i)throw new Error("No Ditty_Items_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Items_Panel.');return void 0!==e?e:this}},$.ditty_items_panel={},$.ditty_items_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_item_types_panel.defaults,e),this.$elmt=$(i),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$editorItem=this.settings.editor.$panels.find(".ditty-editor__panel--items").find(".ditty-data-list__item.editing"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.currentType=null,this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.settings.editor.initFields(this.$elmt),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("click",".ditty-editor-item-type",{self:this},this._typeClick),this.panelVisible()},_showItemsList:function(){this.settings.editor.panelOptions("transition","slideLeft"),this.settings.editor.showPanel("items")},_backClick:function(t){t.preventDefault(),t.data.self._showItemsList()},_typeClick:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is(".ditty-editor-item-type")?$(t.target):$(t.target).parents(".ditty-editor-item-type")).data("item_type");if(e===i.currentType)i._showItemsList();else{i.settings.editor.updateStart();var s={action:"ditty_editor_item_type_update",item_id:i.editorItemId,item_type:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,s,(function(t){if(t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,i.editorItemId),t.editor_item){var e=$(t.editor_item);i.$editorItem.after(e),i.$editorItem.remove(),i.$editorItem=e}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),i._showItemsList(),i.settings.editor.updateStop()}),"json")}},panelVisible:function(){this.$editorItem=this.settings.editor.$panels.find(".ditty-editor__panel--items").find(".ditty-data-list__item.editing"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.currentType=this.$editorItem.data("item_type"),this.$elmt.find(".ditty-editor-item-type").removeClass("active"),this.$elmt.find('.ditty-editor-item-type[data-itemType="'+this.currentType+'"]').addClass("active")},panelHidden:function(){var t=this.$editorItem.find(".ditty-data-list__item__icon").children("i");t.attr("class",t.data("class"))},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_item_types_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_item_types_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$back.off("click",{self:this},this._backClick),this.$elmt.off("click",".ditty-editor-item-type",{self:this},this._typeClick),this.trigger("destroy"),this.elmt._ditty_item_types_panel=null}},$.fn.ditty_item_types_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_item_types_panel||(this._ditty_item_types_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_item_types_panel;if(!i)throw new Error("No Ditty_Item_Types_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Item_Types_Panel.');return void 0!==e?e:this}},$.ditty_item_types_panel={},$.ditty_item_types_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_item_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$preview=this.$elmt.find(".ditty-editor-options__preview"),this.$title=this.$elmt.find(".ditty-editor-options__title"),this.itemId=this.$form.data("item_id"),this.itemType=this.$form.data("item_type"),this.dittyId=this.$form.data("ditty_id"),this.$editorItem=this.settings.editor.$panels.find(".ditty-editor__panel--items").find(".ditty-data-list__item.editing"),this.$editorItemTitle=this.$editorItem.find(".ditty-data-list__item__label"),this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this.settings.editor.initFields(this.$elmt),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.on("submit",{self:this},this._submitForm),this.$back.on("click",{self:this},this._backClick),this.$preview.on("click",{self:this},this._previewClick),this.$form.on("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.on("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.on("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.$form.on("ditty_field_update",".ditty-field__input",{self:this},this._checkUpdates)},_showItemList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","items")},_enablePreviewButton:function(){this.$preview.addClass("ditty-has-updates")},_disablePreviewButton:function(){this.$preview.removeClass("ditty-has-updates"),this.$preview.children("i").attr("class",this.$preview.children("i").data("class"))},_checkUpdates:function(t){var i=t?t.data.self:this;i.$form.serialize()!==i.initData?(i._enablePreviewButton(),i.settings.editor.addUpdate("item_settings",i.itemId),i.settings.editor.delayedSubmitEnable()):(i._disablePreviewButton(),i.settings.editor.removeUpdate("item_settings",i.itemId))},_addDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.$form.serialize()===i.initData?i._showItemList():(i.afterUpdateAction="return",i.$form.trigger("submit"))},_previewClick:function(t){t.preventDefault();var i=t.data.self;i.$form.serialize()!==i.initData&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit"))},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.itemId;i.settings.editor.updateStart();var s={action:"ditty_editor_item_update",item_id:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:s,error:function(){},success:function(t){if(t.value_updates&&i._updateValues(t.value_updates),i.initData=i.$form.serialize(),i._disablePreviewButton(),t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,e),t.editor_item){var s=$(t.editor_item).children(".ditty-data-list__item__label").text();i.$title.html(s),i.$editorItemTitle.html(s)}t.draft_id&&t.draft_data&&dittyDraftItemUpdateData(i,t.draft_id,null,t.draft_data),t.draft_id&&t.draft_meta&&dittyDraftItemUpdateMeta(i,t.draft_id,null,t.draft_meta),i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showItemList(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty({return_items:0}),i.afterUpdateAction=""}})},_updateValues:function(t){var i=this;$.each(t,(function(t,e){var s=i.$form.find('[name="'+t+'"]');s.length&&s.val(e)}))},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_item_editor_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_item_editor_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._saveDrafts),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.off("submit",{self:this},this._submitForm),this.$back.off("click",{self:this},this._backClick),this.$preview.off("click",{self:this},this._previewClick),this.$form.off("keyup change",'input[type="text"], input[type="number"], textarea, select',{self:this},this._checkUpdates),this.$form.off("click",'input[type="radio"], input[type="checkbox"]',{self:this},this._checkUpdates),this.$form.off("ditty_input_wysiwyg_update",".ditty-input--wysiwyg",{self:this},this._checkUpdates),this.$form.off("ditty_field_update",".ditty-field__input",{self:this},this._checkUpdates),this.elmt._ditty_item_editor_panel=null}},$.fn.ditty_item_editor_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_item_editor_panel||(this._ditty_item_editor_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_item_editor_panel;if(!i)throw new Error("No Ditty_Item_Editor_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Item_Editor_Panel.');return void 0!==e?e:this}},$.ditty_item_editor_panel={},$.ditty_item_editor_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_displays_panel.defaults,e),this.$elmt=$(i),this.$list=$(i).find(".ditty-data-list__items"),this.$contents=$(i).find(".ditty-editor__panel__contents"),this.initDisplay=null,this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.$elmt.ditty_ui_data_list({filter:".ditty-display-panel__filter",item:".ditty-editor-display",itemSelector:"display_type"}),this.initDisplay=this.$list.data("active"),this._activateDisplay(this.$list.find("#ditty-editor-display--"+this.initDisplay)),this.$elmt.on("click",".ditty-data-list__item",{self:this},this._selectDisplay),this.$elmt.on("click",".ditty-data-list__item__edit",{self:this},this._editDisplay),this.$elmt.on("click",".ditty-data-list__item__clone",{self:this},this._cloneDisplay),this.$elmt.on("click",".ditty-data-list__item__delete",{self:this},this._deleteDisplay),this.settings.editor.$elmt.on("ditty_editor_saveDrafts",{self:this},this._saveDrafts)},_saveDrafts:function(t){var i=t.data.self;i.initDisplay=i.$list.find(".ditty-editor-display.active").data("display_id")},_activateDisplay:function(t){this.$list.find(".ditty-editor-display").removeClass("active"),t.addClass("active")},_initDitty:function(t,i,e){var s=this.settings.editor.ditty.$elmt;e.display=i,e.id=this.settings.editor.ditty.options("id"),e.items=this.settings.editor.ditty.options("items"),e.height=this.settings.editor.ditty.options("height"),this.settings.editor.ditty.destroy(),s["ditty_"+t](e),this.settings.editor.ditty=s["ditty_"+t]("options","ditty")},_selectDisplay:function(t){t.preventDefault();var i=t.data.self;if($(t.target).parent().is("a"))return!1;var e=$(t.target).is(".ditty-data-list__item")?$(t.target):$(t.target).parents(".ditty-data-list__item"),s=e.data("display_id"),a=e.data("display_type");if(e.hasClass("active"))return!1;i.settings.editor.updateStart(),dittyDraftUpdate(i,"post_meta","_ditty_display",s),i._activateDisplay(e);var d={action:"ditty_editor_select_display",display_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,d,(function(t){if(!t)return!1
5
+ ;i._initDitty(a,s,t),i.settings.editor.updateStop()}),"json")},_cloneDisplay:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("display_id");i.settings.editor.updateStart();var a={action:"ditty_editor_display_clone",display_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t.editor_display){var s=$(t.editor_display);s.hide(),e.after(s),s.slideDown()}t.draft_id&&t.draft_data&&dittyDraftDisplayUpdate(i,t.draft_id,null,t.draft_data),i.settings.editor.updateStop()}),"json")},_deleteDisplay:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=null,a=e.data("display_id");e.hasClass("active")&&(e.prev().length?s=e.prev():e.next().length&&(s=e.next())),e.slideUp((function(){$(this).remove()})),dittyDraftDisplayDelete(i,a),null!==s&&s.trigger("click")},_editDisplay:function(t){t.preventDefault();var i=t.data.self;i.$displayEdit=$(this).parents(".ditty-data-list__item");var e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("display_id");i.settings.editor.updateStart(),e.addClass("editing");var a={action:"ditty_editor_display_fields",display_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--displayEditor">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("display_editor",e)}}))},panelVisible:function(){this.$elmt.find(".ditty-data-list__item").removeClass("editing")},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_displays_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_displays_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$elmt.ditty_ui_data_list("destroy"),this.$elmt.off("click",".ditty-data-list__item",{self:this},this._selectDisplay),this.$elmt.off("click",".ditty-data-list__item__edit",{self:this},this._editDisplay),this.$elmt.off("click",".ditty-data-list__item__clone",{self:this},this._cloneDisplay),this.$elmt.off("click",".ditty-data-list__item__delete",{self:this},this._deleteDisplay),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.trigger("destroy"),this.elmt._ditty_displays_panel=null}},$.fn.ditty_displays_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_displays_panel||(this._ditty_displays_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_displays_panel;if(!i)throw new Error("No Ditty_Displays_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Displays_Panel.');return void 0!==e?e:this}},$.ditty_displays_panel={},$.ditty_displays_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_display_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$optionsTitle=this.$elmt.find(".ditty-editor-options__title"),this.$importExportField=this.$elmt.find(".ditty-editor__import-export__field"),this.$importExportUpdate=this.$elmt.find(".ditty-editor__import-export__update"),this.displayTitle=null,this.displayId=this.settings.editor.ditty.options("display"),this.displayType=this.settings.editor.ditty.options("type"),this.$editorDisplay=this.settings.editor.$panels.find(".ditty-editor__panel--displays").find(".ditty-data-list__item.editing"),this.$editorDisplayTitle=this.$editorDisplay.find(".ditty-data-list__item__label"),this.displayOptions=null,this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){var t,i=this;this.initData=this.$form.serialize(),this.settings.editor.initFields(this.$elmt),t=this.settings.editor.ditty.$elmt["ditty_"+this.displayType]("options"),this.displayOptions=$.extend({},t),this.displayTitle=this.$optionsTitle.val(),this.$importExportUpdate.on("click",{self:this},this._importUpdate),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.on("submit",{self:this},this._submitForm),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("change",'input[type="text"], input[type="number"]',{self:this},this._textfieldListeners),this.$form.on("click",'input[type="radio"]',{self:this},this._radioListeners),this.$form.on("click",'input[type="checkbox"]',{self:this},this._checkboxListeners),this.$form.on("change","select",{self:this},this._selectListeners),this.$form.on("ditty_field_clone_update",{self:this},this._cloneListeners),setTimeout((function(){i.trigger("init",[i])}),1)},_showDisplayList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","displays")},_checkUpdates:function(){this.$form.serialize()!==this.initData?(this.settings.editor.addUpdate("displaySettings",this.displayId),this.settings.editor.delayedSubmitEnable()):this.settings.editor.removeUpdate("displaySettings",this.displayId)},_addDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.$form.serialize()!==i.initData&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.$form.serialize()===i.initData?i._showDisplayList():(i.afterUpdateAction="return",i.$form.trigger("submit"))},_submitForm:function(t){t.preventDefault();var i=t.data.self;i.settings.editor.updateStart();var e={action:"ditty_editor_display_update",display_id:i.displayId,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:e,success:function(t){i.initData=i.$form.serialize(),t.draft_id&&t.draft_label&&(i.displayTitle=t.draft_label,i.$editorDisplayTitle.text(t.draft_label),dittyDraftDisplayUpdate(i,t.draft_id,"label",t.draft_label)),t.draft_id&&t.draft_settings&&(i.displayOptions=t.draft_settings,dittyDraftDisplayUpdate(i,t.draft_id,"settings",t.draft_settings)),t.draft_settings_json&&i.$importExportField.length&&i.$importExportField.val(t.draft_settings_json),i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showDisplayList(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty(),i.afterUpdateAction=""}})},_importUpdate:function(t){t.preventDefault()},_cloneListeners:function(t,i,e){var s=t.data.self;$(t.target);s.settings.editor.ditty.options(e,i)},_textfieldListeners:function(t){var i=t.data.self,e=$(t.target),s=e.attr("name"),a=e.parents(".ditty-input--spacing__group, .ditty-input--radius__group");if(a.length){var d="",r={};a.find("input").each((function(){s=$(this).attr("name"),d=(d=s.split("["))[0];var t=s.match(/\[(.*)\]/);r[t[1]]=$(this).val()})),i.settings.editor.ditty.options(d,r)}else i.settings.editor.ditty.options(s,e.val());i._checkUpdates()},_radioListeners:function(t){var i=t.data.self,e=$(t.target),s=e.val(),a=e.attr("name");i.settings.editor.ditty.options(a,s),i._checkUpdates()},_checkboxListeners:function(t){var i=t.data.self,e=$(t.target),s=!!e.is(":checked")&&$(this).val(),a=e.attr("name");i.settings.editor.ditty.options(a,s),i._checkUpdates()},_selectListeners:function(t){var i=t.data.self,e=$(t.target),s=e.val(),a=e.attr("name");i.settings.editor.ditty.options(a,s),i._checkUpdates()},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_display_editor_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_display_editor_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.trigger("destroy",[this]),this.$importExportUpdate.off("click",{this:this},this._importUpdate),this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.$form.off("submit",{this:this},this._submitForm),this.$back.off("click",{this:this},this._cancel_click),this.$elmt.off("change",'input[type="text"], input[type="number"]',{self:this},this._textfieldListeners),this.$form.off("click",'input[type="radio"]',{self:this},this._radioListeners),this.$form.off("click",'input[type="checkbox"]',{self:this},this._checkboxListeners),this.$form.off("change","select",{self:this},this._selectListeners),this.$form.off("ditty_field_clone_update",{self:this},this._cloneListeners),this.elmt._ditty_display_editor_panel=null}},$.fn.ditty_display_editor_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_display_editor_panel||(this._ditty_display_editor_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_display_editor_panel;if(!i)throw new Error("No Ditty_Display_Editor_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Display_Editor_Panel.');return void 0!==e?e:this}},$.ditty_display_editor_panel={},$.ditty_display_editor_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layout_variations_panel.defaults,e),this.$elmt=$(i),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$list=$(i).find(".ditty-data-list__items"),this.$editorItem=dittyVars.editor.currentItem,this.editorItemLabel=this.$editorItem.find(".ditty-data-list__item__label").text(),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.editorItemType=this.$editorItem.data("item_type"),this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("click",".ditty-layout-variation__change",{self:this},this._changeTemplate),this.$elmt.on("click",".ditty-layout-variation__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.on("click",".ditty-layout-variation__edit_css",{self:this,editType:"css"},this._editLayout),$("body").on("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse)},_showItemList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","items")},_backClick:function(t){t.preventDefault(),t.data.self._showItemList()},_dittyEditorSaveResponse:function(t,i){t.data.self;i.ditty_new_layout_ids&&$.each(i.ditty_new_layout_ids,(function(t,i){var e=$('.ditty-layout-variation[data-layout_id="'+t+'"]');e.length&&e.attr("data-layout_id",i).data("layout_id",i)}))},_changeTemplate:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("layout_id"),a=e.data("layout_variation_id"),d=e.data("layout_variation_label");dittyVars.editor.currentLayoutVariation=e,i.settings.editor.updateStart(),e.addClass("editing");var r={action:"ditty_editor_layouts",ditty_id:i.editorDittyId,item_type:i.editorItemType,variation_id:a,variation_label:d,layout_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,r,(function(t){if(t){var e='<div class="ditty-editor__panel ditty-editor__panel--layouts">'+t+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel("layouts",e)}}))},_editLayout:function(t){t.preventDefault();var i=t.data.self,e=t.data.editType,s=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),a=s.data("layout_id"),d=s.data("item_type");dittyVars.editor.currentLayoutVariation=s,i.settings.editor.updateStart(),i.$list.find(".ditty-data-list__item").removeClass("editing"),s.addClass("editing");var r=[],o=i.settings.editor.ditty.options("items");$.each(o,(function(t,i){r.push(i.uniqId)}));var n={action:"ditty_editor_layout_fields",layout_id:a,item_type:d,ditty_id:i.editorDittyId,item_id:i.editorItemId,item_ids:r,edit_type:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,n,(function(t){if(t){var s="layout_"+e+"_editor",a='<div class="ditty-editor__panel ditty-editor__panel--'+s+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel(s,a)}}),"json")},panelVisible:function(){this.$list.find(".ditty-layout-variation").removeClass("editing")},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_layout_variations_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_layout_variations_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$back.off("click",{self:this},this._backClick),this.$elmt.off("click",".ditty-layout-variation__change",{self:this},this._changeTemplate),this.$elmt.off("click",".ditty-layout-variation__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.off("click",".ditty-layout-variation__edit_css",{self:this,editType:"css"},this._editLayout),$("body").off("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),this.elmt._ditty_layout_variations_panel=null}},$.fn.ditty_layout_variations_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_layout_variations_panel||(this._ditty_layout_variations_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_layout_variations_panel;if(!i)throw new Error("No Ditty_Layout_Variations_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Layout_Variations_Panel.');return void 0!==e?e:this}},$.ditty_layout_variations_panel={},$.ditty_layout_variations_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layouts_panel.defaults,e),this.$elmt=$(i),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$list=$(i).find(".ditty-data-list__items"),this.$editorItem=dittyVars.editor.currentItem,this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.editorItemtype=this.$editorItem.data("item_type"),this.$editorVariation=dittyVars.editor.currentLayoutVariation,this.editorVariationId=this.$editorVariation.data("layout_variation_id"),this.editorLayoutId=this.$editorVariation.data("layout_id"),this._init()};i.prototype={_init:function(){this.$elmt.addClass("init"),this.$back.on("click",{self:this},this._backClick),this.$elmt.on("click",".ditty-data-list__item",{self:this},this._selectLayout),this.$elmt.on("click",".ditty-data-list__item__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.on("click",".ditty-data-list__item__edit_css",{self:this,editType:"css"},this._editLayout),this.$elmt.on("click",".ditty-data-list__item__clone",{self:this},this._cloneLayout),this.$elmt.on("click",".ditty-data-list__item__delete",{self:this},this._deleteLayout),this.$list.on("click",".ditty-editor-layout > a",{self:this},this._actionClick),$("body").on("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),this._activateLayout(this.$list.find("#ditty-editor-layout--"+this.editorLayoutId))},_activateLayout:function(t){this.$list.find(".ditty-editor-layout").removeClass("active"),t.addClass("active")},_showVariationsList:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById","layout_variations")},_backClick:function(t){t.preventDefault(),t.data.self._showVariationsList()},_dittyEditorSaveResponse:function(t,i){t.data.self;i.ditty_new_layout_ids&&$.each(i.ditty_new_layout_ids,(function(t,i){var e=$("#ditty-editor-layout--"+t);e.length&&(e.attr("id","ditty-editor-layout--"+i),e.attr("data-layout_id",i).data("layout_id",i))}))},_selectLayout:function(t){t.preventDefault();var i=t.data.self;if($(t.target).parent().is("a"))return!1;var e=$(t.target).is(".ditty-data-list__item")?$(t.target):$(t.target).parents(".ditty-data-list__item"),s=e.data("layout_id"),a=e.data("layout_version"),d=i.$editorItem.data("layout_value");if(e.hasClass("active"))return!1;$.each(d,(function(t){i.editorVariationId===t&&(d[t]=String(s))})),i.settings.editor.updateStart(),dittyDraftItemUpdateData(i,i.editorItemId,"layout_value",d),i._activateLayout(e);var r={action:"ditty_editor_select_layout",layout_id:s,item_id:i.editorItemId,ditty_id:i.editorDittyId,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,r,(function(t){if(i.settings.editor.updateStop(),t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,i.editorItemId),t.editor_item){var e=$(t.editor_item);i.$editorItem.replaceWith(e)}i.$editorItem.attr("data-layout_value",d).data("layout_value",d),i.$editorVariation.attr("data-layout_id",s).data("layout_id",s),i.$editorVariation.find(".ditty-layout-variation__template > span").text(t.layout_label),a?i.$editorVariation.find(".ditty-layout-variation__template > small").text("("+a+")"):i.$editorVariation.find(".ditty-layout-variation__template > small").text("")}),"json")},_cloneLayout:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=e.data("layout_id");i.settings.editor.updateStart();var a={action:"ditty_editor_layout_clone",layout_id:s,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,a,(function(t){if(t.editor_layout){var s=$(t.editor_layout);s.hide(),e.after(s),s.slideDown()}t.draft_id&&t.draft_meta&&dittyDraftLayoutUpdate(i,t.draft_id,null,t.draft_meta),i.settings.editor.updateStop()}),"json")},_deleteLayout:function(t){t.preventDefault();var i=t.data.self,e=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),s=null,a=e.data("layout_id");e.hasClass("active")&&(e.prev().length?s=e.prev():e.next().length&&(s=e.next())),e.slideUp((function(){$(this).remove()})),dittyDraftLayoutDelete(i,a),null!==s&&s.trigger("click")},_editLayout:function(t){t.preventDefault();var i=t.data.self,e=t.data.editType,s=($(t.target).is("a")?$(t.target):$(t.target).parent("a")).parents(".ditty-data-list__item"),a=s.data("layout_id");i.settings.editor.updateStart(),i.$list.find(".ditty-data-list__item").removeClass("editing"),s.addClass("editing");var d={action:"ditty_editor_layout_fields",layout_id:a,item_id:i.editorItemId,edit_type:e,draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,d,(function(t){if(t){var s="layout_"+e+"_editor",a='<div class="ditty-editor__panel ditty-editor__panel--'+s+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","slideLeft"),i.settings.editor.showPanel(s,a)}}),"json")},_actionClick:function(t){t.preventDefault();var i=t.data.self,e=$(t.target).is("a")?$(t.target):$(t.target).parent("a"),s=e.parents(".ditty-data-list__item"),a=s.data("layout_id");dittyVars.editor.currentLayout=s,$("body").trigger("ditty_editor_layout_action_click",[e,s,a,i.editorDittyId,i.settings.editor])},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_layouts_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_layouts_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$elmt.removeClass("init"),this.$back.off("click",{self:this},this._backClick),this.$elmt.off("click",".ditty-data-list__item",{self:this},this._selectLayout),this.$elmt.off("click",".ditty-data-list__item__edit_html",{self:this,editType:"html"},this._editLayout),this.$elmt.off("click",".ditty-data-list__item__edit_css",{self:this,editType:"css"},this._editLayout),this.$elmt.off("click",".ditty-data-list__item__clone",{self:this},this._cloneLayout),this.$elmt.off("click",".ditty-data-list__item__delete",{self:this},this._deleteLayout),this.$list.off("click",".ditty-editor-layout > a",{self:this},this._actionClick),$("body").off("ditty_editor_save_ditty_response",{self:this},this._dittyEditorSaveResponse),this.elmt._ditty_layouts_panel=null}},$.fn.ditty_layouts_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_layouts_panel||(this._ditty_layouts_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_layouts_panel;if(!i)throw new Error("No Ditty_Layouts_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Layouts_Panel.');return void 0!==e?e:this}},$.ditty_layouts_panel={},$.ditty_layouts_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null,prevPanel:""},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layout_html_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$textarea=this.$elmt.find(".ditty-editor-options__code"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$preview=this.$elmt.find(".ditty-editor-options__preview"),this.$editCss=this.$elmt.find(".ditty-editor-options__edit-css"),this.$title=this.$elmt.find(".ditty-editor-options__title"),this.$tags=this.$elmt.find(".ditty-editor-options__tags"),this.itemType=this.$form.data("item_type"),this.layoutId=this.$form.data("layout_id"),this.$editorItem=dittyVars.editor.currentItem,this.$editorLayout=dittyVars.editor.currentLayout,this.$editorLayoutTitle=!!this.$editorLayout&&this.$editorLayout.find(".ditty-data-list__item__label"),this.$editorLayoutVariation=dittyVars.editor.currentLayoutVariation,this.$editorLayoutVariationTitle=this.$editorLayoutVariation.find(".ditty-layout-variation__template span"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.codeEditor=null,this.codeHasUpdates=!1,this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this._initEditor(),this.$back.on("click",{self:this},this._backClick),this.$preview.on("click",{self:this},this._previewClick),this.$editCss.on("click",{self:this},this._editCss),this.$form.on("submit",{self:this},this._submitForm),this.$form.on("click",".ditty-editor-options__tag",{self:this},this._insertTag),this.$title.on("keyup",{self:this},this._titleUpdate),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts)},_showPrevPanel:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById",this.settings.prevPanel)},_titleUpdate:function(t){var i=t.data.self;i.settings.editor.addUpdate("layoutUpdate",i.layoutId)},_enablePreviewButton:function(){this.$preview.addClass("ditty-has-updates")},_disablePreviewButton:function(){this.$preview.removeClass("ditty-has-updates"),this.$preview.children("i").attr("class",this.$preview.children("i").data("class"))},_getLayoutItems:function(){var t=this.settings.editor.ditty.options("items"),i=[];return $.each(t,(function(t,e){String(e.layoutId)===String(this.layoutId)&&i.push(e.id)})),i},_addDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),i.$form.serialize()!==i.initData||i.codeHasUpdates?(i.afterUpdateAction="return",i.$form.trigger("submit")):i._showPrevPanel()},_previewClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit"))},_editCss:function(t){t.preventDefault();var i=t.data.self,e="layout_css_editor";if(i.settings.editor.updateStart(),i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit")),i.settings.editor.panelExists(e))i.settings.editor.$elmt.find(".ditty-editor__panel--layout_css_editor input.ditty-editor-options__title").val(i.$title.val()),i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e);else{var s={action:"ditty_editor_layout_fields",layout_id:i.layoutId,layout_title:i.$title.val(),ditty_id:i.editorDittyId,item_id:i.editorItemId,item_type:i.itemType,edit_type:"css",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,s,(function(t){if(t){var s='<div class="ditty-editor__panel ditty-editor__panel--'+e+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e,s)}}),"json")}},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.layoutId,s=i.itemType,a=i._getLayoutItems();if(i.$form.hasClass("ditty-editor-has-errors"))return!1;i.codeEditor.codemirror.save(),i.settings.editor.updateStart();var d={action:"ditty_editor_layout_update",layout_id:e,item_type:s,item_ids:a,edit_type:"html",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:d,success:function(t){i.initData=i.$form.serialize(),i._disablePreviewButton(),t.label&&(i.$editorLayoutTitle&&i.$editorLayoutTitle.html(t.label),i.$editorLayoutVariationTitle.html(t.label)),i.$editorLayoutTitle&&i.$editorLayoutTitle.find(".ditty-layout-version").remove(),i.$editorLayoutVariationTitle&&i.$editorLayoutVariationTitle.find(".ditty-layout-version").remove(),t.display_items&&i.settings.editor.ditty.updateItems(t.display_items,!1,!1,!0),t.draft_id&&t.draft_meta&&dittyDraftLayoutUpdate(i,t.draft_id,null,t.draft_meta),i.codeHasUpdates=!1,i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showPrevPanel(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty({return_items:0}),i.afterUpdateAction=""}})},_initEditor:function(){var t=this,i=wp.codeEditor.defaultSettings?_.clone(wp.codeEditor.defaultSettings):{};i.codemirror=_.extend({},i.codemirror,{indentUnit:2,tabSize:2}),this.codeEditor=wp.codeEditor.initialize(this.$textarea[0],i),this.codeEditor.codemirror.on("change",(function(){t.codeEditor.codemirror.save(),t.settings.editor.addUpdate("layout_html_update",t.layoutId),t.codeHasUpdates=!0,t._enablePreviewButton(),t.settings.editor.delayedSubmitEnable()}))},_insertTag:function(t){var i=t.data.self,e=$(t.target),s=e.text(),a=e.data("atts"),d=i.codeEditor.codemirror.getCursor();if(t.shiftKey&&a){var r="",o=s.length-1;$.each(a,(function(t,i){r+=" "+t+'="'+i.toString()+'"'})),s=s.substring(0,o)+r+s.substring(o)}i.codeEditor.codemirror.replaceRange(s,d),d.ch=d.ch+s.length,i.codeEditor.codemirror.setCursor(d)},_options:function(t){return this.settings[t]},trigger:function(t,i){var e=[this.settings];i&&(e=i),this.$elmt.trigger("ditty_layout_html_editor_panel_"+t,e),"function"==typeof this.settings[t]&&this.settings[t].apply(this.$elmt,e)},options:function(i,e){if("object"==typeof i)this.settings=$.extend({},t,$.ditty_layout_html_editor_panel.defaults,i);else{if("string"!=typeof i)return this.settings;if(void 0===e)return this.settings[i];this.settings[i]=e}this.trigger("options_update")},destroy:function(){this.$back.off("click",{self:this},this._backClick),this.$preview.off("click",{self:this},this._previewClick),this.$editCss.off("click",{self:this},this._editCss),this.$form.off("submit",{self:this},this._submitForm),this.$form.off("click",".ditty-editor-options__tag",{self:this},this._insertTag),this.$title.off("keyup",{self:this},this._titleUpdate),this.settings.editor.$elmt.off("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.off("ditty_editor_save_drafts",{self:this},this._saveDrafts),this.codeEditor.codemirror.off("change"),this.codeEditor.codemirror.toTextArea(),this.elmt._ditty_layout_html_editor_panel=null}},$.fn.ditty_layout_html_editor_panel=function(t){var e,s=arguments,a=!1;if(void 0===t||"object"==typeof t)return this.each((function(){this._ditty_layout_html_editor_panel||(this._ditty_layout_html_editor_panel=new i(this,t))}));if("string"==typeof t){if(this.each((function(){var i=this._ditty_layout_html_editor_panel;if(!i)throw new Error("No Ditty_Layout_Html_Editor_Panel applied to this element.");"function"==typeof i[t]&&"_"!==t[0]?e=i[t].apply(i,[].slice.call(s,1)):a=!0})),a)throw new Error('No method "'+t+'" in Ditty_Layout_Html_Editor_Panel.');return void 0!==e?e:this}},$.ditty_layout_html_editor_panel={},$.ditty_layout_html_editor_panel.defaults=t}(jQuery),function($){"use strict";var t={editor:null,prevPanel:""},i=function(i,e){this.elmt=i,this.settings=$.extend({},t,$.ditty_layout_css_editor_panel.defaults,e),this.$elmt=$(i),this.$form=this.$elmt.find(".ditty-editor-options"),this.$textarea=this.$elmt.find(".ditty-editor-options__code"),this.$back=this.$elmt.find(".ditty-editor-options__back"),this.$preview=this.$elmt.find(".ditty-editor-options__preview"),this.$editHtml=this.$elmt.find(".ditty-editor-options__edit-html"),this.$title=this.$elmt.find(".ditty-editor-options__title"),this.$body=this.$elmt.find(".ditty-editor-options__body"),this.$tags=this.$elmt.find(".ditty-editor-options__tags"),this.itemType=this.$form.data("item_type"),this.layoutId=this.$form.data("layout_id"),this.$editorItem=dittyVars.editor.currentItem,this.$editorLayout=dittyVars.editor.currentLayout,this.$editorLayoutTitle=!!this.$editorLayout&&this.$editorLayout.find(".ditty-data-list__item__label"),this.$editorLayoutVariation=dittyVars.editor.currentLayoutVariation,this.$editorLayoutVariationTitle=this.$editorLayoutVariation.find(".ditty-layout-variation__template span"),this.editorDittyId=this.$editorItem.data("ditty_id"),this.editorItemId=this.$editorItem.data("item_id"),this.itemSelector="",this.codeEditor=null,this.codeHasUpdates=!1,
6
+ this.initData=null,this.afterUpdateAction="",this._init()};i.prototype={_init:function(){this.initData=this.$form.serialize(),this._setCssSelector(),this._initEditor(),this.$back.on("click",{self:this},this._backClick),this.$preview.on("click",{self:this},this._previewClick),this.$editHtml.on("click",{self:this},this._editHtml),this.$form.on("submit",{self:this},this._submitForm),this.$form.on("click",".ditty-editor-options__tag",{self:this},this._insertTag),this.$title.on("keyup",{self:this},this._titleUpdate),this.$body.on("click",".ditty-editor-options__body__error",{self:this},this._removeErrorNotice),this.settings.editor.$elmt.on("ditty_editor_add_drafts",{self:this},this._addDrafts),this.settings.editor.$elmt.on("ditty_editor_save_drafts",{self:this},this._saveDrafts)},_setCssSelector:function(){dittyVars.isTickerPost?this.itemSelector="#poststuff .ditty-layout--"+this.layoutId:this.itemSelector=".ditty-layout--"+this.layoutId},_showPrevPanel:function(){this.settings.editor.$panels.ditty_slider("options","transition","slideRight"),this.settings.editor.$panels.ditty_slider("showSlideById",this.settings.prevPanel)},_titleUpdate:function(t){var i=t.data.self;i.settings.editor.addUpdate("layoutUpdate",i.layoutId)},_enablePreviewButton:function(){this.$preview.addClass("ditty-has-updates")},_disablePreviewButton:function(){this.$preview.removeClass("ditty-has-updates"),this.$preview.children("i").attr("class",this.$preview.children("i").data("class"))},_addDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&i.$form.trigger("submit")},_saveDrafts:function(t){var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.afterUpdateAction="save",i.$form.trigger("submit"))},_backClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),i.$form.serialize()!==i.initData||i.codeHasUpdates?(i.afterUpdateAction="return",i.$form.trigger("submit")):i._showPrevPanel()},_previewClick:function(t){t.preventDefault();var i=t.data.self;i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit"))},_editHtml:function(t){t.preventDefault();var i=t.data.self,e="layout_html_editor";if(i.settings.editor.updateStart(),i.codeEditor.codemirror.save(),(i.$form.serialize()!==i.initData||i.codeHasUpdates)&&(i.$preview.children("i").attr("class",dittyVars.updateIcon),i.$form.trigger("submit")),i.settings.editor.panelExists(e))i.settings.editor.$elmt.find(".ditty-editor__panel--layout_html_editor input.ditty-editor-options__title").val(i.$title.val()),i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e);else{var s={action:"ditty_editor_layout_fields",layout_id:i.layoutId,layout_title:i.$title.val(),ditty_id:i.editorDittyId,item_id:i.editorItemId,item_type:i.itemType,edit_type:"html",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};$.post(dittyVars.ajaxurl,s,(function(t){if(t){var s='<div class="ditty-editor__panel ditty-editor__panel--'+e+'">'+t.form+"</div>";i.settings.editor.panelOptions("transition","fade"),i.settings.editor.showPanel(e,s)}}),"json")}},_showErrorNotice:function(){var t=$('<div class="ditty-editor-options__body__error"><span>'+dittyVars.strings.layout_css_error+"</span></div>");this.$body.append(t)},_removeErrorNotice:function(t){t.data.self.$body.find(".ditty-editor-options__body__error").remove()},_submitForm:function(t){t.preventDefault();var i=t.data.self,e=i.layoutId,s=i.itemType;if(i.$form.hasClass("ditty-editor-has-errors"))return!1;i.codeEditor.codemirror.save(),i.settings.editor.updateStart();var a={action:"ditty_editor_layout_update",layout_id:e,item_type:s,edit_type:"css",draft_values:i.settings.editor.getDraftValues(),security:dittyVars.security};i.$form.ajaxSubmit({url:dittyVars.ajaxurl,type:"post",dataType:"json",data:a,success:function(t){i.initData=i.$form.serialize(),i._disablePreviewButton(),t.label&&(i.$editorLayoutTitle&&i.$editorLayoutTitle.html(t.label),i.$editorLayoutVariationTitle.html(t.label)),i.$editorLayoutTitle&&i.$editorLayoutTitle.find(".ditty-layout-version").remove(),i.$editorLayoutVariationTitle&&i.$editorLayoutVariationTitle.find(".ditty-layout-version").remove(),t.code?dittyLayoutCss(t.code,i.layoutId):i._showErrorNotice(),t.draft_id&&t.draft_meta&&dittyDraftLayoutUpdate(i,t.draft_id,null,t.draft_meta),i.codeHasUpdates=!1,i.settings.editor.updateStop(),i.settings.editor.delayedSubmitDisable(),"return"===i.afterUpdateAction&&i._showPrevPanel(),"save"===i.afterUpdateAction&&i.settings.editor.saveDitty(),i.afterUpdateAction=""}})},_initEditor:function()